@@ -134,6 +134,9 @@ module LAoP.Matrix.Internal
135 fromBool,
135 fromBool,
137 fromFRel,
140 fromFRel,
138 fromFRel',
141 fromFRel',
@@ -787,6 +790,9 @@ prettyPrint = putStrLn . pretty
788-- Relational operators functions
791-- Relational operators functions
793+type Boolean = Natural 0 1
794+type Relation a b = Matrix Boolean a b
790-- | Helper conversion function
796-- | Helper conversion function
791toBool :: (Num e, Eq e) => e -> Bool
797toBool :: (Num e, Eq e) => e -> Bool
@@ -799,7 +805,7 @@ fromBool True = nat 1
799fromBool False = nat 0
805fromBool False = nat 0
801-- | Relational negation
807-- | Relational negation
802−negateM :: Matrix (Natural 0 1) cols rows -> Matrix (Natural 0 1) cols rows
808+negateM :: Relation cols rows -> Relation cols rows
803negateM Empty = Empty
809negateM Empty = Empty
804negateM (One (Nat 0)) = One (Nat 1)
810negateM (One (Nat 0)) = One (Nat 1)
805negateM (One (Nat 1)) = One (Nat 0)
811negateM (One (Nat 1)) = One (Nat 0)
@@ -807,7 +813,7 @@ negateM (Junc a b) = Junc (negateM a) (negateM b)
807negateM (Split a b) = Split (negateM a) (negateM b)
813negateM (Split a b) = Split (negateM a) (negateM b)
809-- | Relational addition
815-- | Relational addition
810−orM :: Matrix (Natural 0 1) cols rows -> Matrix (Natural 0 1) cols rows -> Matrix (Natural 0 1) cols rows
816+orM :: Relation cols rows -> Relation cols rows -> Relation cols rows
811orM Empty Empty = Empty
817orM Empty Empty = Empty
812orM (One a) (One b) = One (fromBool (toBool a || toBool b))
818orM (One a) (One b) = One (fromBool (toBool a || toBool b))
813orM (Junc a b) (Junc c d) = Junc (orM a c) (orM b d)
819orM (Junc a b) (Junc c d) = Junc (orM a c) (orM b d)
@@ -816,7 +822,7 @@ orM x@(Split _ _) y@(Junc _ _) = orM x (abideJS y)
816orM x@(Junc _ _) y@(Split _ _) = orM (abideJS x) y
822orM x@(Junc _ _) y@(Split _ _) = orM (abideJS x) y
818-- | Relational multiplication
824-- | Relational multiplication
819−andM :: Matrix (Natural 0 1) cols rows -> Matrix (Natural 0 1) cols rows -> Matrix (Natural 0 1) cols rows
825+andM :: Relation cols rows -> Relation cols rows -> Relation cols rows
820andM Empty Empty = Empty
826andM Empty Empty = Empty
821andM (One a) (One b) = One (fromBool (toBool a && toBool b))
827andM (One a) (One b) = One (fromBool (toBool a && toBool b))
822andM (Junc a b) (Junc c d) = Junc (andM a c) (andM b d)
828andM (Junc a b) (Junc c d) = Junc (andM a c) (andM b d)
@@ -825,7 +831,7 @@ andM x@(Split _ _) y@(Junc _ _) = andM x (abideJS y)
825andM x@(Junc _ _) y@(Split _ _) = andM (abideJS x) y
831andM x@(Junc _ _) y@(Split _ _) = andM (abideJS x) y
827-- | Relational subtraction
833-- | Relational subtraction
828−subM :: Matrix (Natural 0 1) cols rows -> Matrix (Natural 0 1) cols rows -> Matrix (Natural 0 1) cols rows
834+subM :: Relation cols rows -> Relation cols rows -> Relation cols rows
829subM Empty Empty = Empty
835subM Empty Empty = Empty
830subM (One a) (One b) = if a - b < nat 0 then One (nat 0) else One (a - b)
836subM (One a) (One b) = if a - b < nat 0 then One (nat 0) else One (a - b)
831subM (Junc a b) (Junc c d) = Junc (subM a c) (subM b d)
837subM (Junc a b) (Junc c d) = Junc (subM a c) (subM b d)
@@ -834,13 +840,31 @@ subM x@(Split _ _) y@(Junc _ _) = subM x (abideJS y)
834subM x@(Junc _ _) y@(Split _ _) = subM (abideJS x) y
840subM x@(Junc _ _) y@(Split _ _) = subM (abideJS x) y
836-- | Matrix relational composition.
842-- | Matrix relational composition.
837−compRel :: Matrix (Natural 0 1) cr rows -> Matrix (Natural 0 1) cols cr -> Matrix (Natural 0 1) cols rows
843+compRel :: Relation cr rows -> Relation cols cr -> Relation cols rows
838compRel Empty Empty = Empty
844compRel Empty Empty = Empty
839compRel (One a) (One b) = One (fromBool (toBool a && toBool b))
845compRel (One a) (One b) = One (fromBool (toBool a && toBool b))
840−compRel (Junc a b) (Split c d) = orM (compRel a c) (compRel b d) -- Divide-and-conquer law
846+compRel (Junc a b) (Split c d) = orM (compRel a c) (compRel b d) -- Divide-and-conquer law
841compRel (Split a b) c = Split (compRel a c) (compRel b c) -- Split fusion law
847compRel (Split a b) c = Split (compRel a c) (compRel b c) -- Split fusion law
842compRel c (Junc a b) = Junc (compRel c a) (compRel c b) -- Junc fusion law
848compRel c (Junc a b) = Junc (compRel c a) (compRel c b) -- Junc fusion law
850+-- | Matrix relational right division
851+divR :: Relation b c -> Relation b a -> Relation a c
852+divR Empty Empty = Empty
853+divR (One a) (One b) = One (fromBool (not (toBool b) || toBool a)) -- b implies a
854+divR (Junc a b) (Junc c d) = andM (divR a c) (divR b d)
855+divR (Split a b) c = Split (divR a c) (divR b c)
856+divR c (Split a b) = Junc (divR c a) (divR c b)
858+-- | Matrix relational left division
859+divL :: Relation c b -> Relation a b -> Relation a c
860+divL x y = tr (divR (tr y) (tr x))
862+-- | Matrix relational symmetric division
863+divS :: Relation c a -> Relation b a -> Relation c b
864+divS s r = divL r s `intersection` divR (tr r) (tr s)
844-- | Lifts functions to relations with arbitrary dimensions.
868-- | Lifts functions to relations with arbitrary dimensions.
846-- NOTE: Be careful to not ask for a relation bigger than the cardinality of
870-- NOTE: Be careful to not ask for a relation bigger than the cardinality of
@@ -857,7 +881,7 @@ fromFRel ::
857 FromLists (Natural 0 1) rows cols
881 FromLists (Natural 0 1) rows cols
859 (a -> b) ->
883 (a -> b) ->
860− Matrix (Natural 0 1) cols rows
884+ Relation cols rows
861fromFRel f =
885fromFRel f =
862 let minA = minBound @a
886 let minA = minBound @a
863 maxA = maxBound @a
887 maxA = maxBound @a
@@ -891,7 +915,7 @@ fromFRel' ::
891 FromLists (Natural 0 1) (Normalize b) (Normalize a)
915 FromLists (Natural 0 1) (Normalize b) (Normalize a)
893 (a -> b) ->
917 (a -> b) ->
894− Matrix (Natural 0 1) (Normalize a) (Normalize b)
918+ Relation (Normalize a) (Normalize b)
895fromFRel' f =
919fromFRel' f =
896 let minA = minBound @a
920 let minA = minBound @a
897 maxA = maxBound @a
921 maxA = maxBound @a
@@ -923,7 +947,7 @@ toRel ::
923 KnownNat (Count (Normalize b)),
947 KnownNat (Count (Normalize b)),
924 FromLists (Natural 0 1) (Normalize b) (Normalize a)
948 FromLists (Natural 0 1) (Normalize b) (Normalize a)
926− => (a -> b -> Bool) -> Matrix (Natural 0 1) (Normalize a) (Normalize b)
950+ => (a -> b -> Bool) -> Relation (Normalize a) (Normalize b)
928 let minA = minBound @a
952 let minA = minBound @a
929 maxA = maxBound @a
953 maxA = maxBound @a