summaryrefslogtreecommitdiff
path: root/src/Data/Term/Property.idr
diff options
context:
space:
mode:
Diffstat (limited to 'src/Data/Term/Property.idr')
-rw-r--r--src/Data/Term/Property.idr116
1 files changed, 78 insertions, 38 deletions
diff --git a/src/Data/Term/Property.idr b/src/Data/Term/Property.idr
index 1fa53cd..bed4e49 100644
--- a/src/Data/Term/Property.idr
+++ b/src/Data/Term/Property.idr
@@ -2,8 +2,8 @@ module Data.Term.Property
import Data.Term
+import public Data.Vect.Quantifiers
import Data.Vect.Properties.Index
-import Data.Vect.Quantifiers
import Data.Vect.Quantifiers.Extra
import Syntax.PreorderReasoning
@@ -37,6 +37,10 @@ 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))
+public export
+UnifiesAll : Vect n (Term sig k) -> Vect n (Term sig k) -> Property sig k
+UnifiesAll ts us = All (zipWith Unifies ts us)
+
-- Equivalence -----------------------------------------------------------------
public export
@@ -48,40 +52,46 @@ record (<=>) (p, q : Property sig k) where
-- Properties
export
+Reflexive (Property sig k) (<=>) where
+ reflexive = MkEquivalence (\_ => id) (\_ => id)
+
+export
+Symmetric (Property sig k) (<=>) where
+ symmetric prf = MkEquivalence prf.rightToLeft prf.leftToRight
+
+export
unifiesSym : (0 t, u : Term sig k) -> Unifies t u <=> Unifies u t
unifiesSym t u = 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 = MkEquivalence
- { leftToRight = \f, prf => tabulate (\i => Unifies (index i ts) (index i us)) (leftToRight f prf)
- , rightToLeft = \f, prf => irrelevantEq $ cong (Op op) $ rightToLeft f prf
+ {0 k : Nat} ->
+ (0 op : sig.Operator k) ->
+ (ts, us : Vect k (Term sig j)) ->
+ Unifies (Op op ts) (Op op us) <=> UnifiesAll ts us
+unifiesOp op ts us = MkEquivalence
+ { leftToRight = \f, prf => leftToRight ts us f (opInjectiveTs' prf)
+ , rightToLeft = \f, prf => cong (Op op) $ rightToLeft ts us f prf
}
where
leftToRight :
- (f : SFin j -> Term sig n) ->
- (Unifies (Op op ts) (Op op us)).Prop f ->
- (i : _) ->
- f <$> index i ts = f <$> index i us
- leftToRight f 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)
+ forall k.
+ (ts, us : Vect k (Term sig j)) ->
+ (0 f : (SFin j -> Term sig n)) ->
+ map (f <$>) ts = map (f <$>) us ->
+ (UnifiesAll ts us).Prop f
+ leftToRight [] [] f prf = []
+ leftToRight (t :: ts) (u :: us) f prf =
+ fst (biinj (::) prf) :: leftToRight ts us f (snd $ biinj (::) prf)
rightToLeft :
- {k : Nat} ->
- (f : SFin j -> Term sig n) ->
- {ts, us : Vect k (Term sig j)} ->
- (All (tabulate (\i => Unifies (index i ts) (index i us)))).Prop f ->
+ forall k.
+ (ts, us : Vect k (Term sig j)) ->
+ (0 f : (SFin j -> Term sig n)) ->
+ (UnifiesAll ts us).Prop f ->
map (f <$>) ts = map (f <$>) us
- rightToLeft f {ts = [], us = []} [] = Refl
- rightToLeft f {ts = t :: ts, us = u :: us} (prf :: prfs) = cong2 (::) prf (rightToLeft f prfs)
+ rightToLeft [] [] f [] = Refl
+ rightToLeft (t :: ts) (u :: us) f (prf :: prfs) = cong2 (::) prf (rightToLeft ts us f prfs)
-- Nothing ---------------------------------------------------------------------
@@ -111,7 +121,21 @@ nothingExtends : Nothing p -> Nothing (Extension p f)
nothingExtends absurd g x = void $ absurd (g . f) x
export
-extendCong : (f : _) -> p <=> q -> Extension p f <=> Extension q f
+extendCong2 :
+ {f, g : SFin n -> Term sig k} ->
+ {p, q : Property sig n} ->
+ f .=. g ->
+ p <=> q ->
+ Extension p f <=> Extension q g
+extendCong2 prf1 prf2 = MkEquivalence
+ (\h, x => prf2.leftToRight (h . g) $ p.cong (\i => cong (h <$>) $ prf1 i) x)
+ (\h, x => prf2.rightToLeft (h . f) $ q.cong (\i => sym $ cong (h <$>) $ prf1 i) x)
+
+export
+extendCong :
+ (f : SFin n -> Term sig k) ->
+ p <=> q ->
+ Extension p f <=> Extension q f
extendCong f prf = MkEquivalence
(\g => prf.leftToRight (g . f))
(\g => prf.rightToLeft (g . f))
@@ -154,6 +178,21 @@ extendUnify t u f g =
~~ ((h . g) . f) <$> u ...(sym $ subAssoc (h . g) f u)
~~ (h . (g . f)) <$> u ...(subCong (\i => subAssoc h g (f i)) u))
+export
+extendUnifyAll :
+ (ts, us : Vect n (Term sig j)) ->
+ (f : SFin j -> Term sig k) ->
+ (g : SFin k -> Term sig m) ->
+ Extension (UnifiesAll ts us) (g . f) <=>
+ Extension (UnifiesAll (map (f <$>) ts) (map (f <$>) us)) g
+extendUnifyAll [] [] f g = MkEquivalence (\h, [] => []) (\h, [] => [])
+extendUnifyAll (t :: ts) (u :: us) f g =
+ let head = extendUnify t u f g in
+ let tail = extendUnifyAll ts us f g in
+ MkEquivalence
+ (\h, (x :: xs) => head.leftToRight h x :: tail.leftToRight h xs)
+ (\h, (x :: xs) => head.rightToLeft h x :: tail.rightToLeft h xs)
+
-- Ordering --------------------------------------------------------------------
public export
@@ -234,27 +273,28 @@ maxCong prf = MkEquivalence
-- Downward Closed -------------------------------------------------------------
-public export 0
-DClosed : Property sig k -> Type
-DClosed p =
- forall m, n.
- (f : SFin k -> Term sig m) ->
- (g : SFin k -> Term sig n) ->
- f <= g ->
- p.Prop g ->
- p.Prop f
+public export
+record DClosed (p : Property sig k) where
+ constructor MkDClosed
+ closed :
+ forall m, n.
+ (f : SFin k -> Term sig m) ->
+ (g : SFin k -> Term sig n) ->
+ f <= g ->
+ p.Prop g ->
+ p.Prop f
-- Properties
export
unifiesDClosed : (t, u : Term sig k) -> DClosed (Unifies t u)
-unifiesDClosed t u f g prf1 prf2 = Calc $
+unifiesDClosed t u = MkDClosed (\f, g, prf1, prf2 => Calc $
|~ f <$> t
~~ (prf1.sub . g) <$> t ...(subCong prf1.prf t)
~~ prf1.sub <$> g <$> t ...(subAssoc prf1.sub g t)
~~ prf1.sub <$> g <$> u ...(cong (prf1.sub <$>) prf2)
~~ (prf1.sub . g) <$> u ..<(subAssoc prf1.sub g u)
- ~~ f <$> u ..<(subCong prf1.prf u)
+ ~~ f <$> u ..<(subCong prf1.prf u))
export
optimistLemma :
@@ -266,8 +306,8 @@ optimistLemma :
(Max (Extension p a)).Prop f ->
(Max (Extension (All ps) (f . a))).Prop g ->
(Max (Extension (All (p :: ps)) a)).Prop (g . f)
-optimistLemma closed (x, max1) (y, max2) =
- ( ( closed ((g . f) . a) (f . a) (compLte (MkLte g (\i => Refl)) a) x
+optimistLemma prf (x, max1) (y, max2) =
+ ( ( prf.closed ((g . f) . a) (f . a) (compLte (MkLte g (\i => Refl)) a) x
:: (All ps).cong (\i => sym $ subAssoc g f (a i)) y
)
, \h, (x' :: y') =>