@@ -1,3 +1,4 @@
1+{-# LANGUAGE TypeFamilies #-}
12{-# LANGUAGE ConstraintKinds #-}
23{-# LANGUAGE GADTs #-}
34{-# LANGUAGE UndecidableInstances #-}
@@ -178,9 +179,9 @@ import Data.Void
178179import qualified LAoP.Matrix.Internal as I
179180import LAoP.Utils.Internal
180181import Control.DeepSeq
181−import qualified Control.Category as C
182182import Data.Bool
183183import GHC.TypeLits
184+import Prelude hiding (id, (.))
184185
185186-- | Boolean type synonym for working with boolean matrices
186187type Boolean = Natural 0 1
@@ -202,14 +203,12 @@ type Liftable a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num
202203type Trivial a = I.Normalize a ~ I.Normalize (I.Normalize a)
203204type TrivialP a b = I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
204205
205−-- | It isn't possible to implement the 'id' function so it's
206−-- implementation is 'undefined'. However 'comp' can be and this partial
207−-- class implementation exists just to make the code more readable.
208−--
209−-- Please use 'iden' instead.
210−instance C.Category Relation where
211− id = undefined
212− (.) = comp
206+-- | It is possible to implement a constrained version of the category type
207+-- class.
208+instance Category Relation where
209+ type Object Relation a = (FromListsN a a, CountableN a)
210+ id = iden
211+ (.) = comp
213212
214213instance Num (Relation a b) where
215214 -- | Matrix addition becomes Boolean matrix disjointion
@@ -387,7 +386,7 @@ belongs = toRel elemR
387386-- Also known as ⊥ (Bottom) Relation or empty Relation.
388387--
389388-- @
390−-- r ``comp`` ⊥ == ⊥ ``comp`` r == ⊥
389+-- r `.` ⊥ == ⊥ `.` r == ⊥
391390-- ⊥ ``sse`` R && R ``sse`` T == True
392391-- @
393392zeros ::
@@ -433,7 +432,7 @@ point = fromF . const
433432-- | iden matrix
434433--
435434-- @
436−-- 'iden' ``comp`` r == r == r ``comp`` 'iden'
435+-- 'iden' `.` r == r == r `.` 'iden'
437436-- @
438437iden ::
439438 (FromListsN a a, CountableN a) => Relation a a
@@ -442,7 +441,7 @@ iden = relationBuilder' (bool (nat 0) (nat 1) . uncurry (==))
442441-- | Relational composition
443442--
444443-- @
445−-- r ``comp`` (s ``comp`` p) = (r ``comp`` s) ``comp`` p
444+-- r `.` (s `.` p) = (r `.` s) `.` p
446445-- @
447446comp :: Relation b c -> Relation a b -> Relation a c
448447comp (R a) (R b) = R (I.compRel a b)
@@ -506,7 +505,7 @@ pointAp ::
506505 FromListsN a One,
507506 FromListsN b One
508507 ) => a -> b -> Relation a b -> Relation One One
509−pointAp a b r = conv (point b) `comp` r `comp` point a
508+pointAp a b r = conv (point b) . r . point a
510509
511510-- | Relational application
512511--
@@ -518,7 +517,7 @@ pointApBool ::
518517 FromListsN a One,
519518 FromListsN b One
520519 ) => a -> b -> Relation a b -> Bool
521−pointApBool a b r = toBool $ conv (point b) `comp` r `comp` point a
520+pointApBool a b r = toBool $ conv (point b) . r . point a
522521
523522-- | Relational converse
524523--
@@ -560,8 +559,8 @@ intersection a b = a * b
560559-- @
561560-- (r ``union`` s) ``union`` t == r `'union' (s ``union`` t)
562561-- r ``union`` s ``sse`` x == r ``sse`` x && s ``sse`` x
563−-- r ``comp`` (s ``union`` t) == (r ``comp`` s) ``union`` (r ``comp`` t)
564−-- (s ``union`` t) ``comp`` r == (s ``comp`` r) ``union`` (t ``comp`` r)
562+-- r `.` (s ``union`` t) == (r `.` s) ``union`` (r `.` t)
563+-- (s ``union`` t) `.` r == (s `.` r) ``union`` (t `.` r)
565564-- @
566565union :: Relation a b -> Relation a b -> Relation a b
567566union a b = a + b
@@ -569,29 +568,29 @@ union a b = a + b
569568-- | Relation Kernel
570569--
571570-- @
572−-- 'ker' r == 'conv' r ``comp`` r
571+-- 'ker' r == 'conv' r `.` r
573572-- 'ker' r == 'img' ('conv' r)
574573-- @
575574ker :: Relation a b -> Relation a a
576−ker r = conv r `comp` r
575+ker r = conv r . r
577576
578577-- | Relation Image
579578--
580579-- @
581−-- 'img' r == r ``comp`` conv r
580+-- 'img' r == r `.` conv r
582581-- 'img' r == 'ker' ('conv' r)
583582-- @
584583img :: Relation a b -> Relation b b
585−img r = r `comp` conv r
584+img r = r . conv r
586585
587586-- | Function division. Special case of 'divS'.
588587--
589588-- NOTE: _This is only valid_ if @f@ and @g@ are 'function's, i.e. 'simple' and
590589-- 'entire'.
591590--
592−-- @'divisionF' f g == 'conv' g ``comp`` f@
591+-- @'divisionF' f g == 'conv' g `.` f@
593592divisionF :: Relation a c -> Relation b c -> Relation a b
594−divisionF f g = conv g `comp` f
593+divisionF f g = conv g . f
595594
596595-- Taxonomy of binary relations
597596
@@ -617,8 +616,8 @@ surjective = reflexive . img
617616-- relations:
618617--
619618-- @
620−-- f ``comp`` r ``sse`` s == r ``sse`` f ``comp`` s
621−-- r ``comp`` f ``sse`` s == r ``sse`` s ``comp`` f
619+-- f `.` r ``sse`` s == r ``sse`` f `.` s
620+-- r `.` f ``sse`` s == r ``sse`` s `.` f
622621-- @
623622function ::
624623 ( CountableDimensionsN a b,
@@ -672,29 +671,29 @@ bijection r = injection r && surjection r
672671
673672-- Properties of relations
674673
675−-- | A 'Relation' @r@ is 'reflexive' 'iff' @'iden' ``sse`` r@
674+-- | A 'Relation' @r@ is 'reflexive' 'iff' @'id' ``sse`` r@
676675reflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
677−reflexive r = iden <= r
676+reflexive r = id <= r
678677
679−-- | A 'Relation' @r@ is 'coreflexive' 'iff' @r ``sse`` 'iden'@
678+-- | A 'Relation' @r@ is 'coreflexive' 'iff' @r ``sse`` 'id'@
680679coreflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
681−coreflexive r = r <= iden
680+coreflexive r = r <= id
682681
683−-- | A 'Relation' @r@ is 'transitive' 'iff' @(r ``comp`` r) ``sse`` r@
682+-- | A 'Relation' @r@ is 'transitive' 'iff' @(r `.` r) ``sse`` r@
684683transitive :: Relation a a -> Bool
685−transitive r = (r `comp` r) `sse` r
684+transitive r = (r . r) `sse` r
686685
687686-- | A 'Relation' @r@ is 'symmetric' 'iff' @r == 'conv' r@
688687symmetric :: Relation a a -> Bool
689688symmetric r = r == conv r
690689
691−-- | A 'Relation' @r@ is anti-symmetric 'iff' @(r ``intersection`` 'conv' r) ``sse`` 'iden'@
690+-- | A 'Relation' @r@ is anti-symmetric 'iff' @(r ``intersection`` 'conv' r) ``sse`` 'id'@
692691antiSymmetric :: (CountableN a, FromListsN a a) => Relation a a -> Bool
693−antiSymmetric r = (r `intersection` conv r) `sse` iden
692+antiSymmetric r = (r `intersection` conv r) `sse` id
694693
695−-- | A 'Relation' @r@ is 'irreflexive' 'iff' @(r ``intersection`` 'iden') == 'zeros'@
694+-- | A 'Relation' @r@ is 'irreflexive' 'iff' @(r ``intersection`` 'id') == 'zeros'@
696695irreflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
697−irreflexive r = (r `intersection` iden) == zeros
696+irreflexive r = (r `intersection` id) == zeros
698697
699698-- | A 'Relation' @r@ is 'connected' 'iff' @(r ``union`` 'conv' r) == 'ones'@
700699connected :: (CountableN a, FromListsN a a) => Relation a a -> Bool
@@ -721,9 +720,9 @@ partialEquivalence :: (CountableN a, FromListsN a a) => Relation a a -> Bool
721720partialEquivalence r = partialOrder r && equivalence r
722721
723722-- | A 'Relation' @r@ is 'difunctional' or regular wherever
724−-- @r ``comp`` 'conv' r ``comp`` r == r@
723+-- @r `.` 'conv' r `.` r == r@
725724difunctional :: Relation a b -> Bool
726−difunctional r = r `comp` conv r `comp` r == r
725+difunctional r = r . conv r . r == r
727726
728727-- Relational pairing
729728
@@ -732,17 +731,17 @@ difunctional r = r `comp` conv r `comp` r == r
732731-- NOTE: That this is not a true categorical product, see for instance:
733732--
734733-- @
735−-- | 'fstR' ``comp`` 'splitR' a b ``sse`` a
734+-- | 'fstR' `.` 'splitR' a b ``sse`` a
736735-- 'splitR' a b <=> |
737−-- | 'sndR' ``comp`` 'splitR' a b ``sse`` b
736+-- | 'sndR' `.` 'splitR' a b ``sse`` b
738737-- @
739738--
740739-- __Emphasis__ on the 'sse'.
741740--
742741-- @
743−-- 'splitR' r s ``comp`` f == 'splitR' (r ``comp`` f) (s ``comp`` f)
744−-- (R '><' S) ``comp`` 'splitR' p q == 'splitR' (r ``comp`` p) (s ``comp`` q)
745−-- 'conv' ('splitR' r s) ``comp`` 'splitR' x y == ('conv' r ``comp`` x) ``intersection`` ('conv' s ``comp`` y)
742+-- 'splitR' r s `.` f == 'splitR' (r `.` f) (s `.` f)
743+-- (R '><' S) `.` 'splitR' p q == 'splitR' (r `.` p) (s `.` q)
744+-- 'conv' ('splitR' r s) `.` 'splitR' x y == ('conv' r `.` x) ``intersection`` ('conv' s `.` y)
746745-- @
747746--
748747-- @
@@ -761,7 +760,7 @@ splitR (R f) (R g) = R (I.kr f g)
761760-- | Relational pairing first component projection
762761--
763762-- @
764−-- 'fstR' ``comp`` 'splitR' r s ``sse`` r
763+-- 'fstR' `.` 'splitR' r s ``sse`` r
765764-- @
766765fstR ::
767766 forall a b .
@@ -776,7 +775,7 @@ fstR = R (I.fstM @Boolean @(I.Normalize a) @(I.Normalize b))
776775-- | Relational pairing second component projection
777776--
778777-- @
779−-- 'sndR' ``comp`` 'splitR' r s ``sse`` s
778+-- 'sndR' `.` 'splitR' r s ``sse`` s
780779-- @
781780sndR ::
782781 forall a b .
@@ -794,8 +793,8 @@ infixl 4 ><
794793-- | Relational pairing functor
795794--
796795-- @
797−-- r '><' s == 'splitR' (r ``comp`` fstR) (s ``comp`` sndR)
798−-- (r '><' s) ``comp`` (p '><' q) == (r ``comp`` p) '><' (s ``comp`` q)
796+-- r '><' s == 'splitR' (r `.` fstR) (s `.` sndR)
797+-- (r '><' s) `.` (p '><' q) == (r `.` p) '><' (s `.` q)
799798-- @
800799(><) ::
801800 ( CountableDimensionsN a b,
@@ -816,13 +815,13 @@ infixl 4 ><
816815-- | Relational coproduct.
817816--
818817-- @
819−-- | 'eitherR' a b ``comp`` 'i1' == a
818+-- | 'eitherR' a b `.` 'i1' == a
820819-- 'eitherR' a b <=> |
821−-- | 'eitherR' a b ``comp`` 'i2' == b
820+-- | 'eitherR' a b `.` 'i2' == b
822821-- @
823822--
824823-- @
825−-- 'eitherR' r s ``comp`` 'conv' ('eitherR' t u) == (r ``comp`` 'conv' t) ``union`` (s ``comp`` 'conv' u)
824+-- 'eitherR' r s `.` 'conv' ('eitherR' t u) == (r `.` 'conv' t) ``union`` (s `.` 'conv' u)
826825-- @
827826--
828827-- @
@@ -834,8 +833,8 @@ eitherR = join
834833-- | Relational coproduct first component injection
835834--
836835-- @
837−-- 'img' 'i1' ``union`` 'img' 'i2' == 'iden'
838−-- 'i1' ``comp`` 'i2' = 'zeros'
836+-- 'img' 'i1' ``union`` 'img' 'i2' == 'id'
837+-- 'i1' `.` 'i2' = 'zeros'
839838-- @
840839i1 ::
841840 ( CountableDimensionsN a b,
@@ -848,8 +847,8 @@ i1 = R I.i1
848847-- | Relational coproduct second component injection
849848--
850849-- @
851−-- 'img' 'i1' ``union`` 'img' 'i2' == 'iden'
852−-- 'i1' ``comp`` 'i2' = 'zeros'
850+-- 'img' 'i1' ``union`` 'img' 'i2' == 'id'
851+-- 'i1' `.` 'i2' = 'zeros'
853852-- @
854853i2 ::
855854 ( CountableDimensionsN a b,
@@ -864,7 +863,7 @@ infixl 5 -|-
864863-- | Relational coproduct functor.
865864--
866865-- @
867−-- r '-|-' s == 'eitherR' ('i1' ``comp`` r) ('i2' ``comp`` s)
866+-- r '-|-' s == 'eitherR' ('i1' `.` r) ('i2' `.` s)
868867-- @
869868(-|-) ::
870869 ( CountableDimensionsN b d,
@@ -897,7 +896,7 @@ trans ::
897896 TrivialP c b
898897 )
899898 => Relation (a, b) c -> Relation a (c, b)
900−trans r = splitR r sndR `comp` conv fstR
899+trans r = splitR r sndR . conv fstR
901900
902901-- | Relational 'untrans'
903902--
@@ -918,17 +917,17 @@ untrans ::
918917 TrivialP c b
919918 )
920919 => Relation a (c, b) -> Relation (a, b) c
921−untrans s = fstR `comp` conv (splitR (conv s) sndR)
920+untrans s = fstR . conv (splitR (conv s) sndR)
922921
923922-- | Transforms predicate @p@ into a correflexive relation.
924923--
925924-- @
926−-- 'predR' ('const' True) == 'iden'
925+-- 'predR' ('const' True) == 'id'
927926-- 'predR' ('const' False) == 'zeros'
928927-- @
929928--
930929-- @
931−-- 'predR' q ``comp`` 'predR' p == 'predR' q ``union`` 'predR' p
930+-- 'predR' q `.` 'predR' p == 'predR' q ``union`` 'predR' p
932931-- @
933932predR ::
934933 ( Bounded a,
@@ -938,14 +937,14 @@ predR ::
938937 FromListsN Bool a
939938 )
940939 => Relation a Bool -> Relation a a
941−predR p = iden `intersection` divisionF (fromF (const True)) p
940+predR p = id `intersection` divisionF (fromF (const True)) p
942941
943942-- | Equalizes functions @f@ and @g@.
944943-- That is, @'equalizer' f g@ is the largest coreflexive
945944-- that restricts @g@ so that @f@ and @g@ yield the same outputs.
946945--
947946-- @
948−-- 'equalizer' r r == 'iden'
947+-- 'equalizer' r r == 'id'
949948-- 'equalizer' ('point' True) ('point' False) == 'zeros'
950949-- @
951950equalizer ::
@@ -953,12 +952,12 @@ equalizer ::
953952 FromListsN a a
954953 )
955954 => Relation a b -> Relation a b -> Relation a a
956−equalizer f g = iden `intersection` divisionF f g
955+equalizer f g = id `intersection` divisionF f g
957956
958957-- | Relational conditional guard.
959958--
960959-- @
961−-- 'guard' p = 'i2' ``overriddenBy`` 'i1' ``comp`` 'predR' p
960+-- 'guard' p = 'i2' ``overriddenBy`` 'i1' `.` 'predR' p
962961-- @
963962guard ::
964963 ( Bounded b,
@@ -978,27 +977,27 @@ cond ::
978977 FromListsN Bool b
979978 )
980979 => Relation b Bool -> Relation b c -> Relation b c -> Relation b c
981−cond p r s = eitherR r s `comp` guard p
980+cond p r s = eitherR r s . guard p
982981
983982-- | Relational domain.
984983--
985984-- For injective relations, 'domain' and 'ker'nel coincide,
986−-- since @'ker' r ``sse`` 'iden'@ in such situations.
985+-- since @'ker' r ``sse`` 'id'@ in such situations.
987986domain ::
988987 ( CountableN a,
989988 FromListsN a a
990989 ) => Relation a b -> Relation a a
991−domain r = ker r `intersection` iden
990+domain r = ker r `intersection` id
992991
993992-- | Relational range.
994993--
995994-- For functions, 'range' and 'img' (image) coincide,
996−-- since @'img' f ``sse`` 'iden'@ for any @f@.
995+-- since @'img' f ``sse`` id@ for any @f@.
997996range ::
998997 ( CountableN b,
999998 FromListsN b b
1000999 ) => Relation a b -> Relation b b
1001−range r = img r `intersection` iden
1000+range r = img r `intersection` id
10021001
10031002-- Relation pretty print
10041003