summaryrefslogtreecommitdiff
path: root/src/Data/Term/Unify.idr
diff options
context:
space:
mode:
Diffstat (limited to 'src/Data/Term/Unify.idr')
-rw-r--r--src/Data/Term/Unify.idr603
1 files changed, 273 insertions, 330 deletions
diff --git a/src/Data/Term/Unify.idr b/src/Data/Term/Unify.idr
index b87ab21..b4f7ebd 100644
--- a/src/Data/Term/Unify.idr
+++ b/src/Data/Term/Unify.idr
@@ -1,10 +1,6 @@
module Data.Term.Unify
-import Data.DPair
import Data.Fin.Occurs
-import Data.Fin.Strong
-import Data.Maybe.Properties
-import Data.Singleton
import Data.Term
import Data.Term.Property
import Data.Term.Zipper
@@ -16,10 +12,10 @@ import Syntax.PreorderReasoning
-- Check -----------------------------------------------------------------------
export
-check : SFin k -> Term sig k -> Maybe (Term sig (pred k))
-checkAll : SFin k -> Vect n (Term sig k) -> Maybe (Vect n (Term sig (pred k)))
+check : {k : Nat} -> Fin (S k) -> Term sig (S k) -> Maybe (Term sig k)
+checkAll : {k : Nat} -> Fin (S k) -> Vect n (Term sig (S k)) -> Maybe (Vect n (Term sig k))
-check x (Var y) = Var' <$> thick x y
+check x (Var y) = Var <$> thick x y
check x (Op op ts) = Op op <$> checkAll x ts
checkAll x [] = Just []
@@ -27,168 +23,97 @@ checkAll x (t :: ts) = [| check x t :: checkAll x ts |]
-- Properties
-export
-checkOccurs :
- (x : SFin k) ->
- (zip : Zipper sig k) ->
- IsNothing (check x (zip + Var' x))
-checkAllOccurs :
- (x : SFin k) ->
- (i : SFin n) ->
- (ts : Vect (pred n) (Term sig k)) ->
- (zip : Zipper sig k) ->
- IsNothing (checkAll x (insertAt' i (zip + Var' x) ts))
-
-checkOccurs x Top = mapNothing Var' (thickRefl x)
-checkOccurs x (Op op i ts zip) = mapNothing (Op op) (checkAllOccurs x i ts zip)
-
-checkAllOccurs x FZ ts zip =
- appLeftNothingIsNothing
- (appRightNothingIsNothing (Just (::)) (checkOccurs x zip))
- (checkAll x ts)
-checkAllOccurs x (FS i) (t :: ts) zip =
- appRightNothingIsNothing
- (Just (::) <*> check x t)
- (checkAllOccurs x i ts zip)
-
-export
-checkNothing :
- (x : SFin k) ->
- (t : Term sig k) ->
- (0 _ : IsNothing (check x t)) ->
- (zip : Zipper sig k ** t = zip + Var' x)
-checkAllNothing :
- (x : SFin k) ->
- (t : Term sig k) ->
- (ts : Vect n (Term sig k)) ->
- (0 _ : IsNothing (checkAll x (t :: ts))) ->
- (i ** ts' ** zip : Zipper sig k ** t :: ts = insertAt' i (zip + Var' x) ts')
-
-checkNothing x (Var y) prf =
- (Top ** sym (cong Var (thickNothing x y (mapNothingInverse Var' (thick x y) prf))))
-checkNothing x (Op op (t :: ts)) prf =
- let (i ** ts' ** zip ** prf) = checkAllNothing x t ts (mapNothingInverse (Op op) _ prf) in
- (Op op i ts' zip ** cong (Op op) prf)
-
-checkAllNothing x t ts prf with (appNothingInverse (Just (::) <*> check x t) (checkAll x ts) prf)
- _ | Left prf' = case appNothingInverse (Just (::)) (check x t) prf' of
- Right prf =>
- let (zip ** prf) = checkNothing x t prf in
- (FZ ** ts ** zip ** cong (:: ts) prf)
- checkAllNothing x t (t' :: ts) prf | Right prf' =
- let (i ** ts ** zip ** prf) = checkAllNothing x t' ts prf' in
- (FS i ** t :: ts ** zip ** cong (t ::) prf)
-
-export
-checkThin :
- (x : SFin (S k)) ->
- (t : Term sig k) ->
- IsJust (check x (pure (thin x) <$> t))
-checkAllThin :
- (x : SFin (S k)) ->
- (ts : Vect n (Term sig k)) ->
- IsJust (checkAll x (map (pure (thin x) <$>) ts))
-
-checkThin x (Var y) =
- mapIsJust Var' $
- thickNeq x (thin x y) (\prf => thinSkips x y $ sym prf)
-checkThin x (Op op ts) = mapIsJust (Op op) (checkAllThin x ts)
-
-checkAllThin x [] = ItIsJust
-checkAllThin x (t :: ts) =
- appIsJust
- (appIsJust ItIsJust (checkThin x t))
- (checkAllThin x ts)
+public export
+data CheckProof : Fin (S k) -> Term sig (S k) -> Maybe (Term sig k) -> Type where
+ Occurs : (zip : Zipper sig (S k)) -> res = Nothing -> CheckProof x (zip + Var x) res
+ Stronger : (t : Term sig k) -> res = Just t -> CheckProof x (pure (thin x) <$> t) res
+
+data CheckAllProof : Fin (S k) -> Vect n (Term sig (S k)) -> Maybe (Vect n (Term sig k)) -> Type where
+ OccursAt :
+ (i : Fin (S n)) ->
+ (ts : Vect n (Term sig (S k))) ->
+ (zip : Zipper sig (S k)) ->
+ res = Nothing ->
+ CheckAllProof x (insertAt i (zip + Var x) ts) res
+ AllStronger :
+ (ts : Vect n (Term sig k)) ->
+ res = Just ts ->
+ CheckAllProof x (map (pure (thin x) <$>) ts) res
export
-checkJust :
- (x : SFin k) ->
- (t : Term sig k) ->
- (0 _ : check x t = Just u) ->
- t = pure (thin x) <$> u
-checkAllJust :
- (x : SFin k) ->
- (ts : Vect n (Term sig k)) ->
- (0 _ : checkAll x ts = Just us) ->
- ts = map (pure (thin x) <$>) us
-
-checkJust x (Var y) prf =
- let 0 z = mapJustInverse Var' (thick x y) prf in
- let 0 prf = thickJust x y (fst z.snd) in
- sym $ Calc $
- |~ pure (thin x) <$> u
- ~~ pure (thin x) <$> Var' z.fst ...(cong (pure (thin x) <$>) $ snd z.snd)
- ~~ Var' y ...(cong Var' prf)
-checkJust x (Op op ts) prf =
- let 0 z = mapJustInverse (Op op) (checkAll x ts) prf in
- let 0 prf = checkAllJust x ts (fst z.snd) in
- Calc $
- |~ Op op ts
- ~~ pure (thin x) <$> Op op z.fst ...(cong (Op op) prf)
- ~~ pure (thin x) <$> u ...(sym $ cong (pure (thin x) <$>) $ snd z.snd)
-
-checkAllJust x [] Refl = Refl
-checkAllJust x (t :: ts) prf =
- let 0 z = appJustInverse (Just (::) <*> check x t) (checkAll x ts) prf in
- let 0 w = appJustInverse (Just (::)) (check x t) (fst z.snd.snd) in
- Calc $
- |~ t :: ts
- ~~ map (pure (thin x) <$>) (w.snd.fst :: z.snd.fst) ...(cong2 (::) (checkJust x t (fst $ snd w.snd.snd)) (checkAllJust x ts (fst $ snd z.snd.snd)))
- ~~ map (pure (thin x) <$>) (w.fst w.snd.fst z.snd.fst) ...(cong (\f => map (pure (thin x) <$>) (f w.snd.fst z.snd.fst)) $ injective $ fst w.snd.snd)
- ~~ map (pure (thin x) <$>) (z.fst z.snd.fst) ...(sym $ cong (\f => map (pure (thin x) <$>) (f z.snd.fst)) $ snd $ snd w.snd.snd)
- ~~ map (pure (thin x) <$>) us ...(sym $ cong (map (pure (thin x) <$>)) $ snd $ snd z.snd.snd)
+checkProof : {k : Nat} -> (x : Fin (S k)) -> (t : Term sig (S k)) -> CheckProof x t (check x t)
+checkAllProof :
+ {k : Nat} ->
+ (x : Fin (S k)) ->
+ (ts : Vect n (Term sig (S k))) ->
+ CheckAllProof x ts (checkAll x ts)
+
+checkProof x (Var y) with (thickProof x y)
+ checkProof x (Var x) | Equal prf = Occurs Top (cong (Var <$>) prf)
+ checkProof x (Var _) | Thinned y prf = Stronger (Var y) (cong (Var <$>) prf)
+checkProof x (Op op ts) with (checkAllProof x ts)
+ checkProof x (Op op _) | OccursAt i ts zip prf = Occurs (Op op i ts zip) (cong (Op op <$>) prf)
+ checkProof x (Op op _) | AllStronger ts prf = Stronger (Op op ts) (cong (Op op <$>) prf)
+
+checkAllProof x [] = AllStronger [] Refl
+checkAllProof x (t :: ts) with (checkProof x t)
+ checkAllProof x (_ :: ts) | Occurs zip prf =
+ OccursAt FZ ts zip (cong (\t => [| t :: checkAll x ts |]) prf)
+ checkAllProof x (_ :: ts) | Stronger u prf with (checkAllProof x ts)
+ checkAllProof x (_ :: _) | Stronger u prf | OccursAt i ts zip prf' =
+ OccursAt (FS i) (_ :: ts) zip (cong2 (\t, ts => [| t :: ts |]) prf prf')
+ checkAllProof x (_ :: _) | Stronger u prf | AllStronger us prf' =
+ AllStronger (u :: us) (cong2 (\t, ts => [| t :: ts |]) prf prf')
-- Single Variable Substitution ------------------------------------------------
export
-for : Term sig (pred k) -> SFin k -> SFin k -> Term sig (pred k)
-(t `for` x) y = maybe t Var' (thick x y)
+for : {k : Nat} -> Term sig k -> Fin (S k) -> Fin (S k) -> Term sig k
+(t `for` x) y = maybe t Var (thick x y)
export
forRefl :
- (0 u : Term sig (pred k)) ->
- (x : SFin k) ->
+ (0 u : Term sig k) ->
+ (x : Fin (S k)) ->
(u `for` x) x = u
-forRefl u x = cong (maybe u Var') $ extractIsNothing $ thickRefl x
+forRefl u x = cong (maybe u Var) $ thickRefl x
export
forThin :
- (0 t : Term sig (pred k)) ->
- (x : SFin k) ->
- (t `for` x) . thin x .=. Var'
-forThin t x i = cong (maybe t Var') (thickThin x i)
+ (0 t : Term sig k) ->
+ (x : Fin (S k)) ->
+ (t `for` x) . thin x .=. Var
+forThin t x i = cong (maybe t Var) (thickThin x i)
export
forUnifies :
- (x : SFin k) ->
+ (x : Fin (S k)) ->
(t : Term sig k) ->
- (0 _ : check x t = Just u) ->
- (u `for` x) <$> t = (u `for` x) <$> Var' x
-forUnifies x t prf = Calc $
- |~ (u `for` x) <$> t
- ~~ (u `for` x) <$> pure (thin x) <$> u ...(cong ((u `for` x) <$>) $ checkJust x t prf)
- ~~ (u `for` x) . thin x <$> u ...(sym $ subAssoc (u `for` x) (pure (thin x)) u)
- ~~ Var' <$> u ...(subCong (forThin u x) u)
- ~~ u ...(subUnit u)
- ~~ (u `for` x) <$> Var' x ...(sym $ forRefl u x)
+ (t `for` x) <$> pure (thin x) <$> t = (t `for` x) <$> Var x
+forUnifies x t = Calc $
+ |~ (t `for` x) <$> pure (thin x) <$> t
+ ~~ (t `for` x) . thin x <$> t ...(sym $ subAssoc (t `for` x) (pure (thin x)) t)
+ ~~ Var <$> t ...(subExtensional (forThin t x) t)
+ ~~ t ...(subUnit t)
+ ~~ (t `for` x) <$> Var x ...(sym $ forRefl t x)
-- Substitution List -----------------------------------------------------------
public export
data AList : Signature -> Nat -> Nat -> Type where
Lin : AList sig n n
- (:<) : AList sig k n -> (Term sig k, SFin (S k)) -> AList sig (S k) n
+ (:<) : AList sig k n -> (Term sig k, Fin (S k)) -> AList sig (S k) n
%name AList sub
namespace Exists
public export
- (:<) : Exists (AList sig n) -> (Term sig n, SFin (S n)) -> Exists (AList sig (S n))
+ (:<) : Exists (AList sig n) -> (Term sig n, Fin (S n)) -> Exists (AList sig (S n))
Evidence _ sub :< tx = Evidence _ (sub :< tx)
export
-eval : AList sig k n -> SFin k -> Term sig n
-eval [<] = Var'
+eval : {k : Nat} -> AList sig k n -> Fin k -> Term sig n
+eval [<] = Var
eval (sub :< (t, x)) = eval sub . (t `for` x)
export
@@ -199,11 +124,6 @@ sub ++ sub1 :< tx = (sub ++ sub1) :< tx
-- Properties
export
-recover : Singleton k -> AList sig k n -> Singleton n
-recover x [<] = x
-recover x (sub :< _) = recover (pure pred <*> x) sub
-
-export
evalHomo :
(0 sub2 : AList sig k n) ->
(sub1 : AList sig j k) ->
@@ -211,7 +131,7 @@ evalHomo :
evalHomo sub2 [<] i = Refl
evalHomo sub2 (sub1 :< (t, x)) i = Calc $
|~ eval (sub2 ++ sub1) <$> (t `for` x) i
- ~~ (eval sub2 . eval sub1) <$> (t `for` x) i ...(subCong (evalHomo sub2 sub1) ((t `for` x) i))
+ ~~ (eval sub2 . eval sub1) <$> (t `for` x) i ...(subExtensional (evalHomo sub2 sub1) ((t `for` x) i))
~~ eval sub2 <$> eval sub1 <$> (t `for` x) i ...(subAssoc (eval sub2) (eval sub1) ((t `for` x) i))
export
@@ -233,180 +153,208 @@ appendAssoc sub3 sub2 (sub1 :< tx) = cong (:< tx) (appendAssoc sub3 sub2 sub1)
coerce : {0 op, op' : sig.Op} -> op = op' -> Vect op'.fst a -> Vect op.fst a
coerce Refl = id
-flexFlex : SFin (S n) -> SFin (S n) -> Exists (AList sig (S n))
-flexFlex x y = case thick x y of
- Just z => Evidence _ [<(Var' z, x)]
- Nothing => Evidence _ [<]
+flexFlex : {n : Nat} -> Fin n -> Fin n -> (k ** AList sig n k)
+flexFlex {n = S n} x y = case thick x y of
+ Just z => (_ **[<(Var z, x)])
+ Nothing => (_ ** [<])
-flexRigid : SFin (S n) -> Term sig (S n) -> Maybe (Exists (AList sig (S n)))
-flexRigid x t = case check x t of
+flexRigid : {n : Nat} -> Fin n -> Term sig n -> Maybe (Exists (AList sig n))
+flexRigid {n = S n} x t = case check x t of
Just u => Just (Evidence _ [<(u, x)])
Nothing => Nothing
export
amgu :
DecOp sig =>
+ {n : Nat} ->
(t, u : Term sig n) ->
- Exists (AList sig n) ->
+ AList sig n k ->
Maybe (Exists (AList sig n))
amguAll :
DecOp sig =>
- (ts, us : Vect k (Term sig n)) ->
- Exists (AList sig n) ->
+ {n : Nat} ->
+ (ts, us : Vect j (Term sig n)) ->
+ AList sig n k ->
Maybe (Exists (AList sig n))
amgu (Op op ts) (Op op' us) acc with (decOp (Evidence _ op) (Evidence _ op'))
amgu (Op op ts) (Op op us) acc | Yes Refl = amguAll ts us acc
_ | No neq = Nothing
-amgu (Var x) (Var y) (Evidence _ [<]) = Just (flexFlex x y)
-amgu (Var x) (Op op' us) (Evidence _ [<]) = flexRigid x (Op op' us)
-amgu (Op op ts) (Var y) (Evidence _ [<]) = flexRigid y (Op op ts)
-amgu t@(Var _) u@(Var _) (Evidence _ (sub :< (v, z))) =
- (:< (v, z)) <$> amgu ((v `for` z) <$> t) ((v `for` z) <$> u) (Evidence _ sub)
-amgu t@(Var _) u@(Op _ _) (Evidence _ (sub :< (v, z))) =
- (:< (v, z)) <$> amgu ((v `for` z) <$> t) ((v `for` z) <$> u) (Evidence _ sub)
-amgu t@(Op _ _) u@(Var _) (Evidence _ (sub :< (v, z))) =
- (:< (v, z)) <$> amgu ((v `for` z) <$> t) ((v `for` z) <$> u) (Evidence _ sub)
-
-amguAll [] [] acc = Just acc
+amgu (Var x) (Var y) [<] = Just (Evidence _ (flexFlex x y).snd)
+amgu (Var x) (Op op' us) [<] = flexRigid x (Op op' us)
+amgu (Op op ts) (Var y) [<] = flexRigid y (Op op ts)
+amgu t@(Var _) u@(Var _) (sub :< (v, z)) =
+ (:< (v, z)) <$> amgu ((v `for` z) <$> t) ((v `for` z) <$> u) sub
+amgu t@(Var _) u@(Op _ _) (sub :< (v, z)) =
+ (:< (v, z)) <$> amgu ((v `for` z) <$> t) ((v `for` z) <$> u) sub
+amgu t@(Op _ _) u@(Var _) (sub :< (v, z)) =
+ (:< (v, z)) <$> amgu ((v `for` z) <$> t) ((v `for` z) <$> u) sub
+
+amguAll [] [] acc = Just (Evidence _ acc)
amguAll (t :: ts) (u :: us) acc = do
acc <- amgu t u acc
- amguAll ts us acc
+ amguAll ts us acc.snd
export
-mgu : DecOp sig => (t, u : Term sig n) -> Maybe (Exists (AList sig n))
-mgu t u = amgu t u (Evidence _ [<])
+mgu : DecOp sig => {n : Nat} -> (t, u : Term sig n) -> Maybe (Exists (AList sig n))
+mgu t u = amgu t u [<]
-- Properties
export
trivialUnify :
- (0 f : SFin n -> Term sig k) ->
+ (0 f : Fin n -> Term sig k) ->
(t : Term sig n) ->
- (Max (Extension (Unifies t t) f)).Prop Var'
+ (Max (Extension (Unifies t t) f)).Prop Var
trivialUnify f t = (Refl , \g, prf => varMax g)
export
varElim :
- (x : SFin (S n)) ->
- (t : Term sig (S n)) ->
- (0 _ : check x t = Just u) ->
- (Max (Unifies (Var x) t)).Prop (u `for` x)
-varElim x t prf =
- ( sym $ forUnifies x t prf
- , \g, prf' => MkLte (g . thin x) (\i =>
- case decEq x i of
- Yes Refl =>
- Calc $
- |~ g x
- ~~ g <$> t ...(prf')
- ~~ g <$> pure (thin x) <$> u ...(cong (g <$>) $ checkJust i t prf)
- ~~ (g . thin x) <$> u ...(sym $ subAssoc g (pure (thin x)) u)
- ~~ (g . thin x) <$> (u `for` x) x ..<(cong ((g . thin x) <$>) $ forRefl u x)
- No neq =>
- let isJust = thickNeq x i neq in
- let (y ** thickIsJustY) = extractIsJust isJust in
- let thinXYIsI = thickJust x i thickIsJustY in
- Calc $
- |~ g i
- ~~ g (thin x y) ..<(cong g thinXYIsI)
- ~~ (g . thin x) <$> Var' y ...(Refl)
- ~~ (g . thin x) <$> (u `for` x) (thin x y) ..<(cong ((g . thin x) <$>) $ forThin u x y)
- ~~ (g . thin x) <$> (u `for` x) i ...(cong (((g . thin x) <$>) . (u `for` x)) $ thinXYIsI))
+ {n : Nat} ->
+ (x : Fin (S n)) ->
+ (t : Term sig n) ->
+ (Max (Unifies (Var x) (pure (thin x) <$> t))).Prop (t `for` x)
+varElim x t =
+ ( sym $ forUnifies x t
+ , \g, prf' => MkLte (g . thin x) (lteProof g prf')
)
+ where
+ lteProof :
+ forall k.
+ (g : Fin (S n) -> Term sig k) ->
+ (Unifies (Var x) (pure (thin x) <$> t)).Prop g ->
+ g .=. (g . thin x) . (t `for` x)
+ lteProof g prf i with (thickProof x i)
+ lteProof g prf _ | Equal prf' = Calc $
+ |~ g x
+ ~~ g <$> pure (thin x) <$> t ...(prf)
+ ~~ g . thin x <$> t ..<(subAssoc g (pure (thin x)) t)
+ ~~ g . thin x <$> (t `for` x) x ..<(cong ((g . thin x <$>) . maybe t Var) prf')
+ lteProof g prf _ | Thinned i prf' = sym $ cong (g . thin x <$>) (forThin t x i)
flexFlexUnifies :
- (x, y : SFin (S n)) ->
+ {n : Nat} ->
+ (x, y : Fin n) ->
(Max {sig} (Unifies (Var x) (Var y))).Prop (eval (flexFlex x y).snd)
-flexFlexUnifies x y with (thick x y) proof prf
- _ | Just z =
- (Max (Unifies (Var x) (Var y))).cong
- (\i => sym $ subUnit ((Var' z `for` x) i))
- (varElim x (Var y) (cong (map Var') prf))
- _ | Nothing =
- rewrite thickNothing x y (rewrite prf in ItIsNothing) in
- trivialUnify Var' (Var y)
-
-flexRigidUnifies :
- (x : SFin (S n)) ->
- (t : Term sig (S n)) ->
- (0 _ : flexRigid x t = Just sub) ->
- (Max (Unifies (Var x) t)).Prop (eval sub.snd)
-flexRigidUnifies x t ok with (check x t) proof prf
- flexRigidUnifies x t Refl | Just u =
- (Max (Unifies (Var x) t)).cong
- (\i => sym $ subUnit ((u `for` x) i))
- (varElim x t prf)
-
-flexRigidFails :
- (x : SFin (S k)) ->
- (op : sig.Operator j) ->
- (ts : Vect j (Term sig (S k))) ->
- (0 _ : IsNothing (flexRigid x (Op op ts))) ->
- Nothing (Unifies (Var x) (Op op ts))
-flexRigidFails x op ts isNothing f prf' with (check x (Op op ts)) proof prf
- _ | Nothing =
- let
- (zip ** occurs) = checkNothing x (Op op ts) (rewrite prf in ItIsNothing)
- cycle : (f x = (f <$> zip) + f x)
- cycle = Calc $
- |~ f x
- ~~ f <$> Op op ts ...(prf')
- ~~ f <$> zip + Var x ...(cong (f <$>) occurs)
- ~~ (f <$> zip) + f x ...(actionHomo f zip (Var x))
- zipIsTop : (zip = Top)
- zipIsTop = invertActionTop zip $ noCycles (f <$> zip) (f x) (sym cycle)
- opIsVar : (Op op ts = Var x)
- opIsVar = trans occurs (cong (+ Var x) zipIsTop)
- in
- absurd opIsVar
+flexFlexUnifies {n = S n} x y with (thickProof x y)
+ flexFlexUnifies {n = S n} x _ | Equal prf =
+ rewrite prf in
+ trivialUnify Var (Var x)
+ flexFlexUnifies {n = S n} x _ | Thinned y prf =
+ rewrite prf in
+ (Max (Unifies (Var x) (Var _))).cong
+ (\i => sym $ subUnit ((Var y `for` x) i))
+ (varElim x (Var y))
+
+data FlexRigidProof : Fin n -> Term sig n -> Maybe (Exists (AList sig n)) -> Type where
+ NoUnifier : Nothing (Unifies (Var x) t) -> res = Nothing -> FlexRigidProof x t res
+ ElimVar :
+ {n : Nat} ->
+ (sub : AList sig k n) ->
+ (mgu : (Max (Unifies (Var x) t)).Prop (eval sub)) ->
+ res = Just (Evidence _ sub) ->
+ FlexRigidProof x t res
+
+flexRigidProof :
+ {n : Nat} ->
+ (x : Fin n) ->
+ (op : sig.Operator k) ->
+ (ts : Vect k (Term sig n)) ->
+ FlexRigidProof x (Op op ts) (flexRigid x (Op op ts))
+flexRigidProof {n = S n} x op ts with (checkProof x (Op op ts))
+ flexRigidProof x op _ | Occurs zip@(Op op i ts zip') prf =
+ rewrite prf in
+ NoUnifier
+ (\f, prf' =>
+ let
+ cycle : (f x = (f <$> zip) + f x)
+ cycle = Calc $
+ |~ f x
+ ~~ f <$> Op op _ ...(prf')
+ ~~ (f <$> zip) + f x ...(actionHomo f zip (Var x))
+
+ zipIsTop : (zip = Top)
+ zipIsTop = invertActionTop zip $ noCycles (f <$> zip) (f x) (sym cycle)
+
+ opIsVar : Op op (insertAt i (zip' + Var x) ts) = Var x
+ opIsVar = cong (+ Var x) zipIsTop
+ in
+ absurd opIsVar)
+ Refl
+ flexRigidProof x op _ | Stronger (Op op us) prf =
+ rewrite prf in
+ ElimVar
+ [<(Op op us, x)]
+ ((Max (Unifies (Var x) (Op op _))).cong
+ (\i => sym $ subUnit ((Op op us `for` x) i))
+ (varElim x (Op op us)))
+ Refl
stepEquiv :
+ {k : Nat} ->
(t, u : Term sig (S k)) ->
(sub : AList sig k j) ->
(v : Term sig k) ->
- (x : SFin (S k)) ->
+ (x : Fin (S k)) ->
Extension (Unifies t u) (eval (sub :< (v, x))) <=>
Extension (Unifies ((v `for` x) <$> t) ((v `for` x) <$> u)) (eval sub)
stepEquiv t u sub v x = extendUnify t u (v `for` x) (eval sub)
parameters {auto _ : DecOp sig}
public export
- data AmguProof : (t, u : Term sig k) -> Exists (AList sig k) -> Type where
- Success :
- {0 sub : Exists (AList sig k)} ->
- (sub' : Exists (AList sig sub.fst)) ->
- (Max (Extension (Unifies t u) (eval sub.snd))).Prop (eval sub'.snd) ->
- amgu t u sub = Just (Evidence sub'.fst (sub'.snd ++ sub.snd)) ->
- AmguProof t u sub
+ data AmguProof :
+ Term sig k ->
+ Term sig k ->
+ AList sig k n ->
+ Maybe (Exists (AList sig k)) ->
+ Type
+ where
Failure :
- {0 sub : Exists (AList sig k)} ->
- Nothing (Extension (Unifies t u) (eval sub.snd)) ->
- IsNothing (amgu t u sub) ->
- AmguProof t u sub
+ Nothing (Extension (Unifies t u) (eval sub)) ->
+ res = Nothing ->
+ AmguProof t u sub res
+ Success :
+ {j : Nat} ->
+ {0 sub : AList sig k n} ->
+ (sub' : AList sig n j) ->
+ (Max (Extension (Unifies t u) (eval sub))).Prop (eval sub') ->
+ res = Just (Evidence _ (sub' ++ sub)) ->
+ AmguProof t u sub res
public export
- data AmguAllProof : (ts, us : Vect n (Term sig k)) -> Exists (AList sig k) -> Type where
- SuccessAll :
- {0 sub : Exists (AList sig k)} ->
- (sub' : Exists (AList sig sub.fst)) ->
- (Max (Extension (UnifiesAll ts us) (eval sub.snd))).Prop (eval sub'.snd) ->
- amguAll ts us sub = Just (Evidence sub'.fst (sub'.snd ++ sub.snd)) ->
- AmguAllProof ts us sub
+ data AmguAllProof :
+ Vect j (Term sig k) ->
+ Vect j (Term sig k) ->
+ AList sig k n ->
+ Maybe (Exists (AList sig k)) ->
+ Type
+ where
FailureAll :
- {0 sub : Exists (AList sig k)} ->
- Nothing (Extension (UnifiesAll ts us) (eval sub.snd)) ->
- IsNothing (amguAll ts us sub) ->
- AmguAllProof ts us sub
+ Nothing (Extension (UnifiesAll ts us) (eval sub)) ->
+ res = Nothing ->
+ AmguAllProof ts us sub res
+ SuccessAll :
+ {j : Nat} ->
+ {0 sub : AList sig k n} ->
+ (sub' : AList sig n j) ->
+ (Max (Extension (UnifiesAll ts us) (eval sub))).Prop (eval sub') ->
+ res = Just (Evidence _ (sub' ++ sub)) ->
+ AmguAllProof ts us sub res
export
-amguProof : DecOp sig => (t, u : Term sig n) -> (sub : Exists (AList sig n)) -> AmguProof t u sub
+amguProof :
+ DecOp sig =>
+ {k, n : Nat} ->
+ (t, u : Term sig k) ->
+ (sub : AList sig k n) ->
+ AmguProof t u sub (amgu t u sub)
export
amguAllProof :
DecOp sig =>
- (ts, us : Vect k (Term sig n)) ->
- (sub : Exists (AList sig n)) ->
- AmguAllProof ts us sub
+ {k, n : Nat} ->
+ (ts, us : Vect j (Term sig k)) ->
+ (sub : AList sig k n) ->
+ AmguAllProof ts us sub (amguAll ts us sub)
amguProof (Op op ts) (Op op' us) sub with (decOp (Evidence _ op) (Evidence _ op')) proof prf
amguProof (Op op ts) (Op op us) sub | Yes Refl
@@ -414,53 +362,48 @@ amguProof (Op op ts) (Op op' us) sub with (decOp (Evidence _ op) (Evidence _ op'
_ | SuccessAll sub' val prf' =
let
cong :
- Max (Extension (Unifies (Op op ts) (Op op us)) (eval sub.snd)) <=>
- Max (Extension (UnifiesAll ts us) (eval sub.snd))
- cong = maxCong $ extendCong (eval sub.snd) $ unifiesOp op ts us
+ Max (Extension (Unifies (Op op ts) (Op op us)) (eval sub)) <=>
+ Max (Extension (UnifiesAll ts us) (eval sub))
+ cong = maxCong $ extendCong (eval sub) $ unifiesOp op ts us
in
Success sub'
- (cong.rightToLeft (eval sub'.snd) val)
- (rewrite prf in prf')
+ (cong.rightToLeft (eval sub') val)
+ prf'
_ | FailureAll absurd prf' =
Failure
- (nothingEquiv (symmetric $ extendCong (eval sub.snd) $ unifiesOp op ts us) absurd)
- (rewrite prf in prf')
+ (nothingEquiv (symmetric $ extendCong (eval sub) $ unifiesOp op ts us) absurd)
+ prf'
_ | No neq =
Failure
(\f, prf => neq $ opInjectiveOp prf)
- (rewrite prf in ItIsNothing)
-amguProof (Var x) (Var y) (Evidence _ [<]) with (thick x y) proof prf
- _ | Just z = Success (flexFlex x y) (flexFlexUnifies x y) (rewrite prf in Refl)
- _ | Nothing = Success (flexFlex x y) (flexFlexUnifies x y) (rewrite prf in Refl)
-amguProof (Var x) (Op op' us) (Evidence _ [<]) with (flexRigid x (Op op' us)) proof prf
- _ | Just sub@(Evidence _ _) = Success sub (flexRigidUnifies x (Op op' us) prf) prf
- _ | Nothing =
- Failure
- (flexRigidFails x op' us (rewrite prf in ItIsNothing))
- (rewrite prf in ItIsNothing)
-amguProof (Op op ts) (Var y) (Evidence _ [<]) with (flexRigid y (Op op ts)) proof prf
- _ | Just sub@(Evidence _ sub') =
+ Refl
+amguProof (Var x) (Var y) [<] =
+ Success
+ (flexFlex x y).snd
+ (flexFlexUnifies x y)
+ Refl
+amguProof (Var x) (Op op' us) [<] with (flexRigidProof x op' us)
+ _ | NoUnifier absurd prf = Failure absurd prf
+ _ | ElimVar sub val prf = Success sub val prf
+amguProof (Op op ts) (Var y) [<] with (flexRigidProof y op ts)
+ _ | NoUnifier absurd prf =
let
cong :
- Max (Extension (Unifies (Var y) (Op op ts)) Var') <=>
- Max (Extension (Unifies (Op op ts) (Var y)) Var')
- cong = maxCong $ extendCong Var' $ unifiesSym (Var y) (Op op ts)
+ Nothing (Extension (Unifies (Var y) (Op op ts)) Var) ->
+ Nothing (Extension (Unifies (Op op ts) (Var y)) Var)
+ cong = nothingEquiv $ extendCong Var $ unifiesSym (Var y) (Op op ts)
in
- Success sub
- (cong.leftToRight (eval sub.snd) (flexRigidUnifies y (Op op ts) prf))
- prf
- _ | Nothing =
+ Failure (cong absurd) prf
+ _ | ElimVar sub val prf =
let
cong :
- Nothing (Extension (Unifies (Var y) (Op op ts)) Var') ->
- Nothing (Extension (Unifies (Op op ts) (Var y)) Var')
- cong = nothingEquiv $ extendCong Var' $ unifiesSym (Var y) (Op op ts)
+ Max (Extension (Unifies (Var y) (Op op ts)) Var) <=>
+ Max (Extension (Unifies (Op op ts) (Var y)) Var)
+ cong = maxCong $ extendCong Var $ unifiesSym (Var y) (Op op ts)
in
- Failure
- (cong $ flexRigidFails y op ts (rewrite prf in ItIsNothing))
- (rewrite prf in ItIsNothing)
-amguProof (Var x) (Var y) (Evidence l (sub :< (v, z)))
- with (amguProof ((v `for` z) x) ((v `for` z) y) (Evidence _ sub))
+ Success sub (cong.leftToRight _ val) prf
+amguProof (Var x) (Var y) (sub :< (v, z))
+ with (amguProof ((v `for` z) x) ((v `for` z) y) sub)
_ | Success sub' val prf =
let
cong' :
@@ -469,14 +412,14 @@ amguProof (Var x) (Var y) (Evidence l (sub :< (v, z)))
cong' = maxCong $ stepEquiv (Var x) (Var y) sub v z
in
Success sub'
- (cong'.rightToLeft (eval sub'.snd) val)
+ (cong'.rightToLeft (eval sub') val)
(cong (map (:< (v, z))) prf)
_ | Failure absurd prf =
Failure
(nothingEquiv (symmetric $ stepEquiv (Var x) (Var y) sub v z) absurd)
- (mapNothing (:< (v, z)) prf)
-amguProof (Var x) (Op op' us) (Evidence _ (sub :< (v, z)))
- with (amguProof ((v `for` z) x) ((v `for` z) <$> Op op' us) (Evidence _ sub))
+ (rewrite prf in Refl)
+amguProof (Var x) (Op op' us) (sub :< (v, z))
+ with (amguProof ((v `for` z) x) ((v `for` z) <$> Op op' us) sub)
_ | Success sub' val prf =
let
cong' :
@@ -485,14 +428,14 @@ amguProof (Var x) (Op op' us) (Evidence _ (sub :< (v, z)))
cong' = maxCong $ stepEquiv (Var x) (Op op' us) sub v z
in
Success sub'
- (cong'.rightToLeft (eval sub'.snd) val)
+ (cong'.rightToLeft (eval sub') val)
(cong (map (:< (v, z))) prf)
_ | Failure absurd prf =
Failure
(nothingEquiv (symmetric $ stepEquiv (Var x) (Op op' us) sub v z) absurd)
- (mapNothing (:< (v, z)) prf)
-amguProof (Op op ts) (Var y) (Evidence _ (sub :< (v, z)))
- with (amguProof ((v `for` z) <$> Op op ts) ((v `for` z) y) (Evidence _ sub))
+ (rewrite prf in Refl)
+amguProof (Op op ts) (Var y) (sub :< (v, z))
+ with (amguProof ((v `for` z) <$> Op op ts) ((v `for` z) y) sub)
_ | Success sub' val prf =
let
cong' :
@@ -501,38 +444,38 @@ amguProof (Op op ts) (Var y) (Evidence _ (sub :< (v, z)))
cong' = maxCong $ stepEquiv (Op op ts) (Var y) sub v z
in
Success sub'
- (cong'.rightToLeft (eval sub'.snd) val)
+ (cong'.rightToLeft (eval sub') val)
(cong (map (:< (v, z))) prf)
_ | Failure absurd prf =
Failure
(nothingEquiv (symmetric $ stepEquiv (Op op ts) (Var y) sub v z) absurd)
- (mapNothing (:< (v, z)) prf)
+ (rewrite prf in Refl)
-amguAllProof [] [] (Evidence _ sub) =
- SuccessAll (Evidence _ [<])
+amguAllProof [] [] sub =
+ SuccessAll [<]
([], \g, x => varMax g)
(sym $ cong (\sub => Just (Evidence _ sub)) $ appendUnitLeft sub)
amguAllProof (t :: ts) (u :: us) sub with (amguProof t u sub)
- _ | Success sub' val prf with (amguAllProof ts us (Evidence _ (sub'.snd ++ sub.snd)))
+ _ | Success sub' val prf with (amguAllProof ts us (sub' ++ sub))
_ | SuccessAll sub'' val' prf' =
let
cong' =
maxCong $
- extendCong2 (evalHomo sub'.snd sub.snd) (reflexive {x = UnifiesAll ts us})
+ extendCong2 (evalHomo sub' sub) (reflexive {x = UnifiesAll ts us})
opt =
optimistLemma (unifiesDClosed t u) val $
- cong'.leftToRight (eval sub''.snd) val'
+ cong'.leftToRight (eval sub'') val'
in
- SuccessAll (Evidence _ (sub''.snd ++ sub'.snd))
- ((Max (Extension (UnifiesAll (t :: ts) (u :: us)) (eval sub.snd))).cong
- (\i => sym $ evalHomo sub''.snd sub'.snd i)
+ SuccessAll (sub'' ++ sub')
+ ((Max (Extension (UnifiesAll (t :: ts) (u :: us)) (eval sub))).cong
+ (\i => sym $ evalHomo sub'' sub' i)
opt)
(rewrite prf in rewrite prf' in
- cong (\sub => Just (Evidence sub''.fst sub)) $
- appendAssoc sub''.snd sub'.snd sub.snd)
+ cong (\sub => Just (Evidence _ sub)) $
+ appendAssoc sub'' sub' sub)
_ | FailureAll absurd prf' =
let
- cong' = extendCong2 (evalHomo sub'.snd sub.snd) (reflexive {x = UnifiesAll ts us})
+ cong' = extendCong2 (evalHomo sub' sub) (reflexive {x = UnifiesAll ts us})
in
FailureAll
(failTail val $ nothingEquiv cong' absurd)
@@ -540,24 +483,24 @@ amguAllProof (t :: ts) (u :: us) sub with (amguProof t u sub)
_ | Failure absurd prf =
FailureAll
(failHead absurd)
- (bindNothing prf (amguAll ts us))
+ (rewrite prf in Refl)
parameters {auto _ : DecOp sig}
namespace MguProof
public export
- data MguProof : (t, u : Term sig k) -> Type where
+ data MguProof : (t, u : Term sig k) -> Maybe (Exists (AList sig k)) -> Type where
Success :
- (sub : Exists (AList sig k)) ->
- (Max (Unifies t u)).Prop (eval sub.snd) ->
- mgu t u = Just sub ->
- MguProof t u
+ (sub : AList sig k n) ->
+ (Max (Unifies t u)).Prop (eval sub) ->
+ res = Just (Evidence _ sub) ->
+ MguProof t u res
Failure :
Nothing (Unifies t u) ->
- IsNothing (mgu t u) ->
- MguProof t u
+ res = Nothing ->
+ MguProof t u res
export
-mguProof : DecOp sig => (t, u : Term sig k) -> MguProof t u
-mguProof t u with (amguProof t u (Evidence _ [<]))
- _ | Success (Evidence _ sub) val prf = Success (Evidence _ sub) val prf
+mguProof : DecOp sig => {k : Nat} -> (t, u : Term sig k) -> MguProof t u (mgu t u)
+mguProof t u with (amguProof t u [<])
+ _ | Success sub val prf = Success sub val prf
_ | Failure absurd prf = Failure absurd prf