@@ -43,10 +43,10 @@ module LAoP.Relation.Internal
4343
4444 -- * Constraint type synonyms
4545 Countable,
46− CountableDimensions,
46+ CountableDims,
4747 CountableN,
48− CountableDimensionsN,
49− FromListsN,
48+ CountableDimsN,
49+ FLN,
5050 Liftable,
5151 Trivial,
5252 TrivialP,
@@ -194,19 +194,19 @@ newtype Relation a b = R (I.Matrix Boolean (I.Normalize a) (I.Normalize b))
194194deriving instance (Read (I.Matrix Boolean (I.Normalize a) (I.Normalize b))) => Read (Relation a b)
195195
196196-- | Constraint type synonyms to keep the type signatures less convoluted
197−type Countable a = KnownNat (I.Count a)
198−type CountableDimensions a b = (Countable a, Countable b)
199−type CountableN a = KnownNat (I.Count (I.Normalize a))
200−type CountableDimensionsN a b = (CountableN a, CountableN b)
201−type FromListsN a b = I.FromLists Boolean (I.Normalize a) (I.Normalize b)
202−type Liftable a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num Boolean, Ord Boolean)
203−type Trivial a = I.Normalize a ~ I.Normalize (I.Normalize a)
204−type TrivialP a b = I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
197+type Countable a = KnownNat (I.Count a)
198+type CountableDims a b = (Countable a, Countable b)
199+type CountableN a = KnownNat (I.Count (I.Normalize a))
200+type CountableDimsN a b = (CountableN a, CountableN b)
201+type FLN a b = I.FromLists (I.Normalize a) (I.Normalize b)
202+type Liftable a b = (Bounded a, Bounded b, Enum a, Enum b, Eq b, Num Boolean, Ord Boolean)
203+type Trivial a = I.Normalize a ~ I.Normalize (I.Normalize a)
204+type TrivialP a b = I.Normalize (a, b) ~ I.Normalize (I.Normalize a, I.Normalize b)
205205
206206-- | It is possible to implement a constrained version of the category type
207207-- class.
208208instance Category Relation where
209− type Object Relation a = (FromListsN a a, CountableN a)
209+ type Object Relation a = (FLN a a, CountableN a)
210210 id = iden
211211 (.) = comp
212212
@@ -269,26 +269,26 @@ infixl 2 ===
269269
270270-- | Build a matrix out of a list of list of elements. Throws a runtime
271271-- error if the dimensions do not match.
272−fromLists :: (FromListsN a b) => [[Boolean]] -> Relation a b
272+fromLists :: (FLN a b) => [[Boolean]] -> Relation a b
273273fromLists = R . I.fromLists
274274
275275-- | Relation builder function. Constructs a relation provided with
276276-- a construction function that operates with indices.
277277relationBuilder' ::
278− (FromListsN a b, CountableDimensionsN a b) =>
278+ (FLN a b, CountableDimsN a b) =>
279279 ((Int, Int) -> Boolean) -> Relation a b
280280relationBuilder' = R . I.matrixBuilder'
281281
282282-- | Relation builder function. Constructs a relation provided with
283283-- a construction function that operates with arbitrary types.
284284relationBuilder ::
285− ( FromListsN a b,
285+ ( FLN a b,
286286 Enum a,
287287 Enum b,
288288 Bounded a,
289289 Bounded b,
290290 Eq a,
291− CountableDimensionsN a b
291+ CountableDimsN a b
292292 ) => ((a, b) -> Boolean) -> Relation a b
293293relationBuilder = R . I.matrixBuilder
294294
@@ -298,8 +298,8 @@ relationBuilder = R . I.matrixBuilder
298298-- types @a@ or @b@ allows.
299299fromF' ::
300300 ( Liftable a b,
301− CountableDimensionsN c d,
302− FromListsN d c
301+ CountableDimsN c d,
302+ FLN d c
303303 )
304304 => (a -> b) -> Relation c d
305305fromF' f = R (I.fromFRel' f)
@@ -308,8 +308,8 @@ fromF' f = R (I.fromFRel' f)
308308-- cardinality's.
309309fromF ::
310310 ( Liftable a b,
311− CountableDimensionsN a b,
312− FromListsN b a
311+ CountableDimsN a b,
312+ FLN b a
313313 )
314314 => (a -> b) -> Relation a b
315315fromF f = R (I.fromFRel f)
@@ -317,8 +317,8 @@ fromF f = R (I.fromFRel f)
317317-- | Lifts relation functions to 'Relation'
318318toRel ::
319319 ( Liftable a b,
320− CountableDimensionsN a b,
321− FromListsN b a
320+ CountableDimsN a b,
321+ FLN b a
322322 )
323323 => (a -> b -> Bool) -> Relation a b
324324toRel = R . I.toRel
@@ -327,9 +327,9 @@ toRel = R . I.toRel
327327fromRel ::
328328 ( Liftable a b,
329329 Eq a,
330− CountableDimensionsN a b,
331− FromListsN a One,
332− FromListsN b One
330+ CountableDimsN a b,
331+ FLN a One,
332+ FLN b One
333333 )
334334 => Relation a b -> (a -> b -> Bool)
335335fromRel r a b = pointApBool a b r
@@ -356,9 +356,9 @@ toBool r = case toList r of
356356pt ::
357357 ( Liftable a b,
358358 Eq a,
359− CountableDimensionsN a b,
360− FromListsN a One,
361− FromListsN b One
359+ CountableDimsN a b,
360+ FLN a One,
361+ FLN b One
362362 )
363363 => Relation a b -> (a -> List b)
364364pt r a =
@@ -370,8 +370,8 @@ belongs ::
370370 ( Bounded a,
371371 Enum a,
372372 Eq a,
373− CountableDimensionsN (List a) a,
374− FromListsN a (List a)
373+ CountableDimsN (List a) a,
374+ FLN a (List a)
375375 )
376376 => Relation (List a) a
377377belongs = toRel elemR
@@ -390,7 +390,7 @@ belongs = toRel elemR
390390-- ⊥ ``sse`` R && R ``sse`` T == True
391391-- @
392392zeros ::
393− (FromListsN a b, CountableDimensionsN a b) =>
393+ (FLN a b, CountableDimsN a b) =>
394394 Relation a b
395395zeros = relationBuilder' (const (nat 0))
396396
@@ -405,7 +405,7 @@ zeros = relationBuilder' (const (nat 0))
405405-- ⊥ ``sse`` R && R ``sse`` T == True
406406-- @
407407ones ::
408− (FromListsN a b, CountableDimensionsN a b) =>
408+ (FLN a b, CountableDimsN a b) =>
409409 Relation a b
410410ones = relationBuilder' (const (nat 1))
411411
@@ -413,7 +413,7 @@ ones = relationBuilder' (const (nat 1))
413413
414414-- | The T (Top) row vector relation.
415415bang ::
416− (FromListsN a One, CountableN a) =>
416+ (FLN a One, CountableN a) =>
417417 Relation a One
418418bang = ones
419419
@@ -423,7 +423,7 @@ point ::
423423 Enum a,
424424 Eq a,
425425 CountableN a,
426− FromListsN a One
426+ FLN a One
427427 ) => a -> Relation One a
428428point = fromF . const
429429
@@ -435,7 +435,7 @@ point = fromF . const
435435-- 'iden' `.` r == r == r `.` 'iden'
436436-- @
437437iden ::
438− (FromListsN a a, CountableN a) => Relation a a
438+ (FLN a a, CountableN a) => Relation a a
439439iden = relationBuilder' (bool (nat 0) (nat 1) . uncurry (==))
440440
441441-- | Relational composition
@@ -489,7 +489,7 @@ shrunkBy r s = r `intersection` divR s (conv r)
489489-- r ``overriddenBy`` r == r
490490-- @
491491overriddenBy ::
492− ( FromListsN b b,
492+ ( FLN b b,
493493 CountableN b
494494 ) => Relation a b -> Relation a b -> Relation a b
495495overriddenBy r s = s `union` r `intersection` divR zeros (conv s)
@@ -501,9 +501,9 @@ overriddenBy r s = s `union` r `intersection` divR zeros (conv s)
501501pointAp ::
502502 ( Liftable a b,
503503 Eq a,
504− CountableDimensionsN a b,
505− FromListsN a One,
506− FromListsN b One
504+ CountableDimsN a b,
505+ FLN a One,
506+ FLN b One
507507 ) => a -> b -> Relation a b -> Relation One One
508508pointAp a b r = conv (point b) . r . point a
509509
@@ -513,9 +513,9 @@ pointAp a b r = conv (point b) . r . point a
513513pointApBool ::
514514 ( Liftable a b,
515515 Eq a,
516− CountableDimensionsN a b,
517− FromListsN a One,
518− FromListsN b One
516+ CountableDimsN a b,
517+ FLN a One,
518+ FLN b One
519519 ) => a -> b -> Relation a b -> Bool
520520pointApBool a b r = toBool $ conv (point b) . r . point a
521521
@@ -595,19 +595,19 @@ divisionF f g = conv g . f
595595-- Taxonomy of binary relations
596596
597597-- | A 'Relation' @r@ is 'simple' 'iff' @'coreflexive' ('img' r)@
598−simple :: (CountableN b, FromListsN b b) => Relation a b -> Bool
598+simple :: (CountableN b, FLN b b) => Relation a b -> Bool
599599simple = coreflexive . img
600600
601601-- | A 'Relation' @r@ is 'injective' 'iff' @'coreflexive' ('ker' r)@
602−injective :: (CountableN a, FromListsN a a) => Relation a b -> Bool
602+injective :: (CountableN a, FLN a a) => Relation a b -> Bool
603603injective = coreflexive . ker
604604
605605-- | A 'Relation' @r@ is 'entire' 'iff' @'reflexive' ('ker' r)@
606−entire :: (CountableN a, FromListsN a a) => Relation a b -> Bool
606+entire :: (CountableN a, FLN a a) => Relation a b -> Bool
607607entire = reflexive . ker
608608
609609-- | A 'Relation' @r@ is 'surjective' 'iff' @'reflexive' ('img' r)@
610−surjective :: (CountableN b, FromListsN b b) => Relation a b -> Bool
610+surjective :: (CountableN b, FLN b b) => Relation a b -> Bool
611611surjective = reflexive . img
612612
613613-- | A 'Relation' @r@ is a 'function' 'iff' @'simple' r && 'entire' r@
@@ -620,9 +620,9 @@ surjective = reflexive . img
620620-- r `.` f ``sse`` s == r ``sse`` s `.` f
621621-- @
622622function ::
623− ( CountableDimensionsN a b,
624− FromListsN a a,
625− FromListsN b b
623+ ( CountableDimsN a b,
624+ FLN a a,
625+ FLN b b
626626 )
627627 => Relation a b -> Bool
628628function r = simple r && entire r
@@ -630,7 +630,7 @@ function r = simple r && entire r
630630-- | A 'Relation' @r@ is a 'representation' 'iff' @'injective' r && 'entire' r@
631631representation ::
632632 ( CountableN a,
633− FromListsN a a
633+ FLN a a
634634 )
635635 => Relation a b -> Bool
636636representation r = injective r && entire r
@@ -638,45 +638,45 @@ representation r = injective r && entire r
638638-- | A 'Relation' @r@ is an 'abstraction' 'iff' @'surjective' r && 'simple' r@
639639abstraction ::
640640 ( CountableN b,
641− FromListsN b b
641+ FLN b b
642642 )
643643 => Relation a b -> Bool
644644abstraction r = surjective r && simple r
645645
646646-- | A 'Relation' @r@ is a 'surjection' 'iff' @'function' r && 'abstraction' r@
647647surjection ::
648− ( CountableDimensionsN a b,
649− FromListsN a a,
650− FromListsN b b
648+ ( CountableDimsN a b,
649+ FLN a a,
650+ FLN b b
651651 )
652652 => Relation a b -> Bool
653653surjection r = function r && abstraction r
654654
655655-- | A 'Relation' @r@ is a 'injection' 'iff' @'function' r && 'representation' r@
656656injection ::
657− ( CountableDimensionsN a b,
658− FromListsN a a,
659− FromListsN b b
657+ ( CountableDimsN a b,
658+ FLN a a,
659+ FLN b b
660660 )
661661 => Relation a b -> Bool
662662injection r = function r && representation r
663663
664664-- | A 'Relation' @r@ is an 'bijection' 'iff' @'injection' r && 'surjection' r@
665665bijection ::
666− ( CountableDimensionsN a b,
667− FromListsN b b,
668− FromListsN a a
666+ ( CountableDimsN a b,
667+ FLN b b,
668+ FLN a a
669669 ) => Relation a b -> Bool
670670bijection r = injection r && surjection r
671671
672672-- Properties of relations
673673
674674-- | A 'Relation' @r@ is 'reflexive' 'iff' @'id' ``sse`` r@
675−reflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
675+reflexive :: (CountableN a, FLN a a) => Relation a a -> Bool
676676reflexive r = id <= r
677677
678678-- | A 'Relation' @r@ is 'coreflexive' 'iff' @r ``sse`` 'id'@
679−coreflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
679+coreflexive :: (CountableN a, FLN a a) => Relation a a -> Bool
680680coreflexive r = r <= id
681681
682682-- | A 'Relation' @r@ is 'transitive' 'iff' @(r `.` r) ``sse`` r@
@@ -688,35 +688,35 @@ symmetric :: Relation a a -> Bool
688688symmetric r = r == conv r
689689
690690-- | A 'Relation' @r@ is anti-symmetric 'iff' @(r ``intersection`` 'conv' r) ``sse`` 'id'@
691−antiSymmetric :: (CountableN a, FromListsN a a) => Relation a a -> Bool
691+antiSymmetric :: (CountableN a, FLN a a) => Relation a a -> Bool
692692antiSymmetric r = (r `intersection` conv r) `sse` id
693693
694694-- | A 'Relation' @r@ is 'irreflexive' 'iff' @(r ``intersection`` 'id') == 'zeros'@
695−irreflexive :: (CountableN a, FromListsN a a) => Relation a a -> Bool
695+irreflexive :: (CountableN a, FLN a a) => Relation a a -> Bool
696696irreflexive r = (r `intersection` id) == zeros
697697
698698-- | A 'Relation' @r@ is 'connected' 'iff' @(r ``union`` 'conv' r) == 'ones'@
699−connected :: (CountableN a, FromListsN a a) => Relation a a -> Bool
699+connected :: (CountableN a, FLN a a) => Relation a a -> Bool
700700connected r = (r `union` conv r) == ones
701701
702702-- | A 'Relation' @r@ is a 'preorder' 'iff' @'reflexive' r && 'transitive' r@
703−preorder :: (CountableN a, FromListsN a a) => Relation a a -> Bool
703+preorder :: (CountableN a, FLN a a) => Relation a a -> Bool
704704preorder r = reflexive r && transitive r
705705
706706-- | A 'Relation' @r@ is a partial-order 'iff' @'antiSymmetric' r && 'preorder' r@
707−partialOrder :: (CountableN a, FromListsN a a) => Relation a a -> Bool
707+partialOrder :: (CountableN a, FLN a a) => Relation a a -> Bool
708708partialOrder r = antiSymmetric r && preorder r
709709
710710-- | A 'Relation' @r@ is a linear-order 'iff' @'connected' r && 'partialOrder' r@
711−linearOrder :: (CountableN a, FromListsN a a) => Relation a a -> Bool
711+linearOrder :: (CountableN a, FLN a a) => Relation a a -> Bool
712712linearOrder r = connected r && partialOrder r
713713
714714-- | A 'Relation' @r@ is an 'equivalence' 'iff' @'symmetric' r && 'preorder' r@
715−equivalence :: (CountableN a, FromListsN a a) => Relation a a -> Bool
715+equivalence :: (CountableN a, FLN a a) => Relation a a -> Bool
716716equivalence r = symmetric r && preorder r
717717
718718-- | A 'Relation' @r@ is a partial-equivalence 'iff' @'partialOrder' r && 'equivalence' r@
719−partialEquivalence :: (CountableN a, FromListsN a a) => Relation a a -> Bool
719+partialEquivalence :: (CountableN a, FLN a a) => Relation a a -> Bool
720720partialEquivalence r = partialOrder r && equivalence r
721721
722722-- | A 'Relation' @r@ is 'difunctional' or regular wherever
@@ -748,10 +748,10 @@ difunctional r = r . conv r . r == r
748748-- 'eitherR' ('splitR' r s) ('splitR' t v) == 'splitR' ('eitherR' r t) ('eitherR' s v)
749749-- @
750750splitR ::
751− ( CountableDimensionsN a b,
751+ ( CountableDimsN a b,
752752 CountableN (a, b),
753− FromListsN (a, b) a,
754− FromListsN (a, b) b,
753+ FLN (a, b) a,
754+ FLN (a, b) b,
755755 TrivialP a b
756756 )
757757 => Relation c a -> Relation c b -> Relation c (a, b)
@@ -764,9 +764,9 @@ splitR (R f) (R g) = R (I.kr f g)
764764-- @
765765fstR ::
766766 forall a b .
767− ( CountableDimensionsN a b,
767+ ( CountableDimsN a b,
768768 CountableN (a, b),
769− FromListsN (a, b) a,
769+ FLN (a, b) a,
770770 TrivialP a b
771771 )
772772 => Relation (a, b) a
@@ -779,9 +779,9 @@ fstR = R (I.fstM @Boolean @(I.Normalize a) @(I.Normalize b))
779779-- @
780780sndR ::
781781 forall a b .
782− ( CountableDimensionsN a b,
782+ ( CountableDimsN a b,
783783 CountableN (a, b),
784− FromListsN (a, b) b,
784+ FLN (a, b) b,
785785 TrivialP a b
786786 )
787787 => Relation (a, b) b
@@ -797,13 +797,13 @@ infixl 4 ><
797797-- (r '><' s) `.` (p '><' q) == (r `.` p) '><' (s `.` q)
798798-- @
799799(><) ::
800− ( CountableDimensionsN a b,
801− CountableDimensionsN c d,
802− CountableDimensionsN (a, c) (b, d),
803− FromListsN (a, c) a,
804− FromListsN (a, c) c,
805− FromListsN (b, d) b,
806− FromListsN (b, d) d,
800+ ( CountableDimsN a b,
801+ CountableDimsN c d,
802+ CountableDimsN (a, c) (b, d),
803+ FLN (a, c) a,
804+ FLN (a, c) c,
805+ FLN (b, d) b,
806+ FLN (b, d) d,
807807 TrivialP a c,
808808 TrivialP b d
809809 )
@@ -837,9 +837,9 @@ eitherR = join
837837-- 'i1' `.` 'i2' = 'zeros'
838838-- @
839839i1 ::
840− ( CountableDimensionsN a b,
841− FromListsN b a,
842− FromListsN a a
840+ ( CountableDimsN a b,
841+ FLN b a,
842+ FLN a a
843843 )
844844 => Relation a (Either a b)
845845i1 = R I.i1
@@ -851,9 +851,9 @@ i1 = R I.i1
851851-- 'i1' `.` 'i2' = 'zeros'
852852-- @
853853i2 ::
854− ( CountableDimensionsN a b,
855− FromListsN a b,
856− FromListsN b b
854+ ( CountableDimsN a b,
855+ FLN a b,
856+ FLN b b
857857 )
858858 => Relation b (Either a b)
859859i2 = R I.i2
@@ -866,11 +866,11 @@ infixl 5 -|-
866866-- r '-|-' s == 'eitherR' ('i1' `.` r) ('i2' `.` s)
867867-- @
868868(-|-) ::
869− ( CountableDimensionsN b d,
870− FromListsN b b,
871− FromListsN d b,
872− FromListsN b d,
873− FromListsN d d
869+ ( CountableDimsN b d,
870+ FLN b b,
871+ FLN d b,
872+ FLN b d,
873+ FLN d d
874874 )
875875 => Relation a b -> Relation c d -> Relation (Either a c) (Either b d)
876876(-|-) (R a) (R b) = R ((I.-|-) a b)
@@ -883,13 +883,13 @@ infixl 5 -|-
883883-- 'trans'/'untrans';
884884-- more-over, where each particular attribute is placed (input/output) is irrelevant.
885885trans ::
886− ( CountableDimensionsN a b,
886+ ( CountableDimsN a b,
887887 CountableN c,
888− CountableDimensionsN (a, b) (c, b),
889− FromListsN (c, b) c,
890− FromListsN (c, b) b,
891− FromListsN (a, b) a,
892− FromListsN (a, b) b,
888+ CountableDimsN (a, b) (c, b),
889+ FLN (c, b) c,
890+ FLN (c, b) b,
891+ FLN (a, b) a,
892+ FLN (a, b) b,
893893 Trivial (a, b),
894894 Trivial (c, b),
895895 TrivialP a b,
@@ -904,13 +904,13 @@ trans r = splitR r sndR . conv fstR
904904-- 'trans'/'untrans';
905905-- more-over, where each particular attribute is placed (input/output) is irrelevant.
906906untrans ::
907− ( CountableDimensionsN a b,
907+ ( CountableDimsN a b,
908908 CountableN c,
909− CountableDimensionsN (a, b) (c, b),
910− FromListsN (c, b) c,
911− FromListsN (c, b) b,
912− FromListsN (a, b) b,
913− FromListsN (a, b) a,
909+ CountableDimsN (a, b) (c, b),
910+ FLN (c, b) c,
911+ FLN (c, b) b,
912+ FLN (a, b) b,
913+ FLN (a, b) a,
914914 Trivial (a, b),
915915 Trivial (c, b),
916916 TrivialP a b,
@@ -933,8 +933,8 @@ predR ::
933933 ( Bounded a,
934934 Enum a,
935935 CountableN a,
936− FromListsN a a,
937− FromListsN Bool a
936+ FLN a a,
937+ FLN Bool a
938938 )
939939 => Relation a Bool -> Relation a a
940940predR p = id `intersection` divisionF (fromF (const True)) p
@@ -949,7 +949,7 @@ predR p = id `intersection` divisionF (fromF (const True)) p
949949-- @
950950equalizer ::
951951 ( CountableN a,
952− FromListsN a a
952+ FLN a a
953953 )
954954 => Relation a b -> Relation a b -> Relation a a
955955equalizer f g = id `intersection` divisionF f g
@@ -963,8 +963,8 @@ guard ::
963963 ( Bounded b,
964964 Enum b,
965965 CountableN b,
966− FromListsN b b,
967− FromListsN Bool b
966+ FLN b b,
967+ FLN Bool b
968968 ) => Relation b Bool -> Relation b (Either b b)
969969guard p = conv (eitherR (predR p) (predR (negate p)))
970970
@@ -973,8 +973,8 @@ cond ::
973973 ( Bounded b,
974974 Enum b,
975975 CountableN b,
976− FromListsN b b,
977− FromListsN Bool b
976+ FLN b b,
977+ FLN Bool b
978978 )
979979 => Relation b Bool -> Relation b c -> Relation b c -> Relation b c
980980cond p r s = eitherR r s . guard p
@@ -985,7 +985,7 @@ cond p r s = eitherR r s . guard p
985985-- since @'ker' r ``sse`` 'id'@ in such situations.
986986domain ::
987987 ( CountableN a,
988− FromListsN a a
988+ FLN a a
989989 ) => Relation a b -> Relation a a
990990domain r = ker r `intersection` id
991991
@@ -995,16 +995,16 @@ domain r = ker r `intersection` id
995995-- since @'img' f ``sse`` id@ for any @f@.
996996range ::
997997 ( CountableN b,
998− FromListsN b b
998+ FLN b b
999999 ) => Relation a b -> Relation b b
10001000range r = img r `intersection` id
10011001
10021002-- Relation pretty print
10031003
10041004-- | Relation pretty printing
1005−pretty :: (CountableDimensionsN a b) => Relation a b -> String
1005+pretty :: (CountableDimsN a b) => Relation a b -> String
10061006pretty (R a) = I.pretty a
10071007
10081008-- | Relation pretty printing
1009−prettyPrint :: (CountableDimensionsN a b) => Relation a b -> IO ()
1009+prettyPrint :: (CountableDimsN a b) => Relation a b -> IO ()
10101010prettyPrint (R a) = I.prettyPrint a