diff options
author | Greg Brown <greg.brown01@ed.ac.uk> | 2023-07-07 17:36:37 +0100 |
---|---|---|
committer | Greg Brown <greg.brown01@ed.ac.uk> | 2023-07-07 17:36:37 +0100 |
commit | 6b637a6d2954e77985e24bbd17f3697eb6f8238a (patch) | |
tree | ff60597d324f182084ccf855a25b6f1251034293 | |
parent | 8c529393421843a7ccad041d2f29fa90b46bf6b6 (diff) |
Define properties of substitutions.
-rw-r--r-- | src/Data/Term.idr | 11 | ||||
-rw-r--r-- | src/Data/Term/Property.idr | 143 | ||||
-rw-r--r-- | src/Data/Vect/Quantifiers/Extra.idr | 14 | ||||
-rw-r--r-- | unify.ipkg | 2 |
4 files changed, 170 insertions, 0 deletions
diff --git a/src/Data/Term.idr b/src/Data/Term.idr index 2afc774..3b16f38 100644 --- a/src/Data/Term.idr +++ b/src/Data/Term.idr @@ -38,6 +38,13 @@ public export 0 (.=.) : Rel (Fin k -> Term sig n) f .=. g = (i : Fin k) -> f i = g i +export +subCong : {f, g : Fin k -> Term sig n} -> f .=. g -> (t : Term sig k) -> f <$> t = g <$> t +subCong prf (Var i) = prf i +subCong prf (Op op ts) = + cong (Op op) $ + mapExtensional (f <$>) (g <$>) (\t => subCong prf (assert_smaller ts t)) ts + -- Substitution is Monadic ----------------------------------------------------- export @@ -80,6 +87,10 @@ opInjectiveLen : (prf : Op {k} op ts = Op {k = n} op' us) -> k = n opInjectiveLen Refl = Refl export +opInjectiveTs' : {0 ts, us : Vect k (Term sig n)} -> (prf : Op op ts = Op op us) -> ts = us +opInjectiveTs' Refl = Refl + +export opInjectiveTs : {0 ts : Vect k (Term sig n)} -> {0 us : Vect j (Term sig n)} -> diff --git a/src/Data/Term/Property.idr b/src/Data/Term/Property.idr new file mode 100644 index 0000000..41fb906 --- /dev/null +++ b/src/Data/Term/Property.idr @@ -0,0 +1,143 @@ +module Data.Term.Property + +import Data.Term + +import Data.Vect.Properties.Index +import Data.Vect.Quantifiers +import Data.Vect.Quantifiers.Extra + +import Syntax.PreorderReasoning + +-- Definition ------------------------------------------------------------------ + +public export +record Property (sig : Signature) (k : Nat) where + constructor MkProp + Prop : forall n. (Fin k -> Term sig n) -> Type + cong : forall n. {f, g : Fin k -> Term sig n} -> f .=. g -> Prop f -> Prop g + +%name Property p, q + +-- Instances ------------------------------------------------------------------- + +public export +Unifies : Term sig k -> Term sig k -> Property sig k +Unifies t u = MkProp + { Prop = \f => f <$> t = f <$> u + , cong = \cong, prf => Calc $ + |~ _ <$> t + ~~ _ <$> t ..<(subCong cong t) + ~~ _ <$> u ...(prf) + ~~ _ <$> u ...(subCong cong u) + } + +public export +All : Vect n (Property sig k) -> Property sig k +All ps = MkProp (\f => All (\p => p.Prop f) ps) (\cong => mapRel (\p => p.cong cong)) + +-- Equivalence ----------------------------------------------------------------- + +public export 0 +(<=>) : Property sig k -> Property sig k -> Type +p <=> q = forall n. (f : Fin k -> Term sig n) -> p.Prop f <=> q.Prop f + +-- Properties + +export +unifiesSym : Unifies t u <=> Unifies u t +unifiesSym f = MkEquivalence (\prf => sym prf) (\prf => sym prf) + +export +unifiesOp : + {k : Nat} -> + {0 op : sig.Operator k} -> + {0 ts, us : Vect k (Term sig j)} -> + Unifies (Op op ts) (Op op us) <=> All (tabulate (\i => Unifies (index i ts) (index i us))) +unifiesOp f = MkEquivalence + { leftToRight = \prf => tabulate (\i => Unifies (index i ts) (index i us)) (leftToRight prf) + , rightToLeft = \prf => irrelevantEq $ cong (Op op) $ rightToLeft prf + } + where + leftToRight : + (Unifies (Op op ts) (Op op us)).Prop f -> + (i : _) -> + f <$> index i ts = f <$> index i us + leftToRight prf i = + Calc $ + |~ f <$> index i ts + ~~ index i (map (f <$>) ts) ...(sym $ indexNaturality i (f <$>) ts) + ~~ index i (map (f <$>) us) ...(cong (index i) $ opInjectiveTs' prf) + ~~ f <$> index i us ...(indexNaturality i (f <$>) us) + + rightToLeft : + {k : Nat} -> + {ts, us : Vect k (Term sig j)} -> + (All (tabulate (\i => Unifies (index i ts) (index i us)))).Prop f -> + map (f <$>) ts = map (f <$>) us + rightToLeft {ts = [], us = []} [] = Refl + rightToLeft {ts = t :: ts, us = u :: us} (prf :: prfs) = cong2 (::) prf (rightToLeft prfs) + +-- Nothing --------------------------------------------------------------------- + +public export 0 +Nothing : Property sig k -> Type +Nothing p = forall n. (f : Fin k -> Term sig n) -> Not (p.Prop f) + +-- Properties + +export +nothingEquiv : p <=> q -> Nothing p -> Nothing q +nothingEquiv eq absurd f x = absurd f ((eq f).rightToLeft x) + +-- Extensions ------------------------------------------------------------------ + +public export +Extension : Property sig k -> (Fin k -> Term sig n) -> Property sig n +Extension p f = MkProp + { Prop = \g => p.Prop (g . f) + , cong = \prf => p.cong (\i => subCong prf (f i)) + } + +-- Properties + +export +nothingExtends : Nothing p -> Nothing (Extension p f) +nothingExtends absurd g x = void $ absurd (g . f) x + +export +extendUnit : (p : Property sig k) -> p <=> Extension p Var +extendUnit p f = MkEquivalence id id + +export +extendAssoc : + (p : Property sig j) -> + (f : Fin j -> Term sig k) -> + (g : Fin k -> Term sig m) -> + Extension (Extension p f) g <=> Extension p (g . f) +extendAssoc p f g h = + MkEquivalence + (p.cong (\i => subAssoc h g (f i))) + (p.cong (\i => sym $ subAssoc h g (f i))) + +export +extendUnify : + (t, u : Term sig j) -> + (f : Fin j -> Term sig k) -> + (g : Fin k -> Term sig m) -> + Extension (Unifies t u) (g . f) <=> Extension (Unifies (f <$> t) (f <$> u)) g +extendUnify t u f g h = + MkEquivalence + (\prf => Calc $ + |~ (h . g) <$> (f <$> t) + ~~ ((h . g) . f) <$> t ...(sym $ subAssoc (h . g) f t) + ~~ (h . (g . f)) <$> t ...(subCong (\i => subAssoc h g (f i)) t) + ~~ (h . (g . f)) <$> u ...(prf) + ~~ ((h . g) . f) <$> u ...(sym $ subCong (\i => subAssoc h g (f i)) u) + ~~ (h . g) <$> (f <$> u) ...(subAssoc (h . g) f u)) + (\prf => Calc $ + |~ (h . (g . f)) <$> t + ~~ ((h . g) . f) <$> t ...(sym $ subCong (\i => subAssoc h g (f i)) t) + ~~ (h . g) <$> (f <$> t) ...(subAssoc (h . g) f t) + ~~ (h . g) <$> (f <$> u) ...(prf) + ~~ ((h . g) . f) <$> u ...(sym $ subAssoc (h . g) f u) + ~~ (h . (g . f)) <$> u ...(subCong (\i => subAssoc h g (f i)) u)) diff --git a/src/Data/Vect/Quantifiers/Extra.idr b/src/Data/Vect/Quantifiers/Extra.idr new file mode 100644 index 0000000..dc5a224 --- /dev/null +++ b/src/Data/Vect/Quantifiers/Extra.idr @@ -0,0 +1,14 @@ +module Data.Vect.Quantifiers.Extra + +import Data.Vect +import Data.Vect.Quantifiers + +export +mapRel : ((x : a) -> p x -> q x) -> {xs : Vect n a} -> All p xs -> All q xs +mapRel f [] = [] +mapRel f (px :: pxs) = f _ px :: mapRel f pxs + +export +tabulate : {n : Nat} -> (0 f : Fin n -> a) -> ((i : Fin n) -> p (f i)) -> All p (tabulate f) +tabulate {n = 0} f pf = [] +tabulate {n = S k} f pf = pf FZ :: tabulate (f . FS) (\i => pf $ FS i) @@ -10,5 +10,7 @@ modules = Data.Fin.Occurs , Data.Maybe.Properties , Data.Term + , Data.Term.Property , Data.Term.Zipper , Data.Vect.Properties.Insert + , Data.Vect.Quantifiers.Extra |