summaryrefslogtreecommitdiff
path: root/src/Core/Term/Substitution.idr
diff options
context:
space:
mode:
Diffstat (limited to 'src/Core/Term/Substitution.idr')
-rw-r--r--src/Core/Term/Substitution.idr221
1 files changed, 205 insertions, 16 deletions
diff --git a/src/Core/Term/Substitution.idr b/src/Core/Term/Substitution.idr
index abeb487..c14c652 100644
--- a/src/Core/Term/Substitution.idr
+++ b/src/Core/Term/Substitution.idr
@@ -4,6 +4,8 @@ import Core.Term
import Core.Term.Thinned
import Core.Thinning
+import Syntax.PreorderReasoning
+
infix 4 =~=
-- Definition ------------------------------------------------------------------
@@ -22,6 +24,81 @@ namespace Eq
%name Subst sub
%name Eq.(=~=) prf
+-- Weakening -------------------------------------------------------------------
+
+public export
+wkn : Subst k m -> m `Thins` n -> Subst k n
+wkn (Wkn thin') thin = Wkn (thin . thin')
+wkn (sub :< t) thin = wkn sub thin :< wkn t thin
+
+export
+wknCong :
+ {0 sub1, sub2 : Subst k m} ->
+ sub1 =~= sub2 ->
+ (thin : m `Thins` n) ->
+ wkn sub1 thin =~= wkn sub2 thin
+wknCong Refl thin = Refl
+wknCong (prf :< prf') thin = wknCong prf thin :< wknCong prf' thin
+
+export
+wknHomo :
+ (sub : Subst j k) ->
+ (thin1 : k `Thins` m) ->
+ (thin2 : m `Thins` n) ->
+ wkn (wkn sub thin1) thin2 = wkn sub (thin2 . thin1)
+wknHomo (Wkn thin) thin1 thin2 = cong Wkn (compAssoc thin2 thin1 thin)
+wknHomo (sub :< t) thin1 thin2 = cong2 (:<) (wknHomo sub thin1 thin2) (wknHomo t thin1 thin2)
+
+-- Composition -----------------------------------------------------------------
+
+export
+(.) : Subst m n -> k `Thins` m -> Subst k n
+comp : Subst m n -> Thinned n -> {0 thin : k `Thins` S m} -> View thin -> Subst k n
+
+Wkn thin1 . thin = Wkn (thin1 . thin)
+(sub :< t) . thin = comp sub t (view thin)
+
+comp sub t (Id (S m)) = sub :< t
+comp sub t (Drop thin) = sub . thin
+comp sub t (Keep thin) = (sub . thin) :< t
+
+export
+compId : (sub : Subst m n) -> sub . id m = sub
+compId (Wkn thin) = cong Wkn (compRightId thin)
+compId (sub :< t) = viewId m (\v => comp sub t v = sub :< t) Refl
+
+export
+compKeep :
+ (sub : Subst m n) ->
+ (t : Thinned n) ->
+ (thin : k `Thins` m) ->
+ (sub :< t) . keep thin = (sub . thin) :< t
+compKeep sub t thin =
+ viewKeep thin (\v => comp sub t v = (sub . thin) :< t)
+ (\Refl, Refl => sym $ cong (:< t) $ compId sub)
+ Refl
+
+export
+wknComp :
+ (sub : Subst k m) ->
+ (thin1 : j `Thins` k) ->
+ (thin2 : m `Thins` n) ->
+ wkn (sub . thin1) thin2 = wkn sub thin2 . thin1
+wknComp' :
+ (sub : Subst k m) ->
+ (t : Thinned m) ->
+ {0 thin1 : j `Thins` S k} ->
+ (v : View thin1) ->
+ (thin2 : m `Thins` n) ->
+ wkn (comp sub t v) thin2 = comp (wkn sub thin2) (wkn t thin2) v
+
+wknComp (Wkn thin) thin1 thin2 = cong Wkn (compAssoc thin2 thin thin1)
+wknComp (sub :< t) thin1 thin2 = wknComp' sub t (view thin1) thin2
+
+wknComp' sub t (Id (S k)) thin2 = Refl
+wknComp' sub t (Drop thin1) thin2 = wknComp sub thin1 thin2
+wknComp' sub t (Keep thin1) thin2 = cong (:< wkn t thin2) (wknComp sub thin1 thin2)
+
-- Indexing --------------------------------------------------------------------
public export
@@ -40,27 +117,79 @@ indexCong Refl i = Refl
indexCong (prf :< prf') FZ = prf'
indexCong (prf :< prf') (FS i) = indexCong prf i
--- Weakening -------------------------------------------------------------------
-
-public export
-wkn : Subst k m -> m `Thins` n -> Subst k n
-wkn (Wkn thin') thin = Wkn (thin . thin')
-wkn (sub :< t) thin = wkn sub thin :< wkn t thin
-
export
-wknCong :
- {0 sub1, sub2 : Subst k m} ->
- sub1 =~= sub2 ->
+indexHomo :
+ (sub : Subst k m) ->
(thin : m `Thins` n) ->
- wkn sub1 thin =~= wkn sub2 thin
-wknCong Refl thin = Refl
-wknCong (prf :< prf') thin = wknCong prf thin :< wknCong prf' thin
+ (i : Fin k) ->
+ index (wkn sub thin) i = wkn (index sub i) thin
+indexHomo (Wkn thin') thin i = Refl
+indexHomo (sub :< t) thin FZ = Refl
+indexHomo (sub :< t) thin (FS i) = indexHomo sub thin i
+
+export
+indexComp :
+ (sub : Subst m n) ->
+ (thin : k `Thins` m) ->
+ (i : Fin k) ->
+ index (sub . thin) i =~= index sub (wkn i thin)
+indexComp' :
+ (sub : Subst m n) ->
+ (t : Thinned n) ->
+ {0 thin : k `Thins` S m} ->
+ (v : View thin) ->
+ (i : Fin k) ->
+ index (comp sub t v) i =~= index (sub :< t) (wkn i thin)
+
+indexComp (Wkn thin1) thin i = sym $ cong Var $ wknHomo i thin thin1
+indexComp (sub :< t) thin i = indexComp' sub t (view thin) i
+
+indexComp' sub t (Id (S m)) i = rewrite wknId i in Refl
+indexComp' sub t (Drop thin) i = rewrite wknDrop i thin in indexComp sub thin i
+indexComp' sub t (Keep thin) FZ = rewrite wknKeepFZ thin in Refl
+indexComp' sub t (Keep thin) (FS i) = rewrite wknKeepFS i thin in indexComp sub thin i
-- Constructors ----------------------------------------------------------------
public export
+Refl' : {0 sub1, sub2 : Subst m n} -> sub1 = sub2 -> sub1 =~= sub2
+Refl' Refl = Refl
+
+public export
lift : Subst m n -> Subst (S m) (S n)
-lift sub = wkn sub (drop $ id n) :< (Var 0 `Over` id (S n))
+lift sub = wkn sub (wkn1 n) :< pure (Var 0)
+
+export
+wknLift :
+ (sub : Subst k m) ->
+ (thin : m `Thins` n) ->
+ wkn (lift sub) (keep thin) =~= lift (wkn sub thin)
+wknLift sub thin =
+ let
+ eq1 : wkn (wkn sub (wkn1 m)) (keep thin) =~= wkn (wkn sub thin) (wkn1 n)
+ eq1 = Refl' $ Calc $
+ |~ wkn (wkn sub (wkn1 m)) (keep thin)
+ ~~ wkn sub (keep thin . wkn1 m) ...(wknHomo sub (wkn1 m) (keep thin))
+ ~~ wkn sub (wkn1 n . thin) ...(cong (wkn sub) $ wkn1Comm thin)
+ ~~ wkn (wkn sub thin) (wkn1 n) ...(sym $ wknHomo sub thin (wkn1 n))
+ eq2 : (Var (wkn 0 (keep thin . id (S m))) = Var (wkn FZ (id $ S n)))
+ eq2 = cong Var $ Calc $
+ |~ wkn 0 (keep thin . id (S m))
+ ~~ wkn 0 (keep thin) ...(cong (wkn 0) $ compRightId (keep thin))
+ ~~ 0 ...(wknKeepFZ thin)
+ ~~ wkn 0 (id $ S n) ...(sym $ wknId 0)
+ in
+ eq1 :< eq2
+
+export
+compLift :
+ (sub : Subst m n) ->
+ (thin : k `Thins` m) ->
+ lift sub . keep thin = lift (sub . thin)
+compLift sub thin = Calc $
+ |~ lift sub . keep thin
+ ~~ (wkn sub (wkn1 n) . thin) :< pure (Var 0) ...(compKeep (wkn sub (wkn1 n)) (pure $ Var 0) thin)
+ ~~ lift (sub . thin) ...(sym $ cong (:< pure (Var 0)) $ wknComp sub thin (wkn1 n))
-- Substitution ----------------------------------------------------------------
@@ -72,6 +201,10 @@ subst (Pi t u) sub = Pi (subst t sub) (subst u $ lift sub)
subst (Abs t) sub = Abs (subst t $ lift sub)
subst (App t u) sub = App (subst t sub) (subst u sub)
+public export
+subst1 : Term (S n) -> Term n -> Term n
+subst1 t u = subst t (Wkn (id n) :< pure u)
+
export
substCong :
(t : Term m) ->
@@ -83,6 +216,62 @@ substCong Set prf = Refl
substCong (Pi t u) prf =
cong2 Pi
(substCong t prf)
- (substCong u $ wknCong prf (drop $ id n) :< Refl)
-substCong (Abs t) prf = cong Abs (substCong t $ wknCong prf (drop $ id n) :< Refl)
+ (substCong u $ wknCong prf (wkn1 n) :< Refl)
+substCong (Abs t) prf = cong Abs (substCong t $ wknCong prf (wkn1 n) :< Refl)
substCong (App t u) prf = cong2 App (substCong t prf) (substCong u prf)
+
+-- Interaction with Weakening
+
+export
+wknSubst :
+ (t : Term k) ->
+ (sub : Subst k m) ->
+ (thin : m `Thins` n) ->
+ wkn (subst t sub) thin = subst t (wkn sub thin)
+wknSubst (Var i) sub thin = sym $ Calc $
+ |~ expand (index (wkn sub thin) i)
+ ~~ expand (wkn (index sub i) thin) ...(cong expand $ indexHomo sub thin i)
+ ~~ wkn (expand (index sub i)) thin ...(expandHomo (index sub i) thin)
+wknSubst Set sub thin = Refl
+wknSubst (Pi t u) sub thin = cong2 Pi (wknSubst t sub thin) $ Calc $
+ |~ wkn (subst u $ lift sub) (keep thin)
+ ~~ subst u (wkn (lift sub) (keep thin)) ...(wknSubst u (lift sub) (keep thin))
+ ~~ subst u (lift $ wkn sub thin) ...(substCong u $ wknLift sub thin)
+wknSubst (Abs t) sub thin = cong Abs $ Calc $
+ |~ wkn (subst t $ lift sub) (keep thin)
+ ~~ subst t (wkn (lift sub) (keep thin)) ...(wknSubst t (lift sub) (keep thin))
+ ~~ subst t (lift $ wkn sub thin) ...(substCong t $ wknLift sub thin)
+wknSubst (App t u) sub thin = cong2 App (wknSubst t sub thin) (wknSubst u sub thin)
+
+export
+substWkn :
+ (t : Term k) ->
+ (thin : k `Thins` m) ->
+ (sub : Subst m n) ->
+ subst (wkn t thin) sub = subst t (sub . thin)
+
+substWkn (Var i) thin sub = sym (indexComp sub thin i)
+substWkn Set thin sub = Refl
+substWkn (Pi t u) thin sub = cong2 Pi (substWkn t thin sub) $ Calc $
+ |~ subst (wkn u (keep thin)) (lift sub)
+ ~~ subst u (lift sub . keep thin) ...(substWkn u (keep thin) (lift sub))
+ ~~ subst u (lift (sub . thin)) ...(cong (subst u) $ compLift sub thin)
+substWkn (Abs t) thin sub = cong Abs $ Calc $
+ |~ subst (wkn t (keep thin)) (lift sub)
+ ~~ subst t (lift sub . keep thin) ...(substWkn t (keep thin) (lift sub))
+ ~~ subst t (lift (sub . thin)) ...(cong (subst t) $ compLift sub thin)
+substWkn (App t u) thin sub = cong2 App (substWkn t thin sub) (substWkn u thin sub)
+
+export
+wknSubst1 :
+ (t : Term (S m)) ->
+ (u : Term m) ->
+ (thin : m `Thins` n) ->
+ wkn (subst1 t u) thin = subst1 (wkn t $ keep thin) (wkn u thin)
+wknSubst1 t u thin = Calc $
+ |~ wkn (subst t (Wkn (id m) :< pure u)) thin
+ ~~ subst t (Wkn (thin . id m) :< (u `Over` thin . id m)) ...(wknSubst t (Wkn (id m) :< pure u) thin)
+ ~~ subst t (Wkn thin :< (u `Over` thin)) ...(cong (\thin => subst t (Wkn thin :< (u `Over` thin))) $ compRightId thin)
+ ~~ subst t (Wkn (id n . thin) :< pure (wkn u thin)) ...(sym $ substCong t (Refl' (cong Wkn $ compLeftId thin) :< wknId (wkn u thin)))
+ ~~ subst t ((Wkn (id n) :< pure (wkn u thin)) . keep thin) ...(sym $ cong (subst t) $ compKeep (Wkn $ id n) (pure $ wkn u thin) thin)
+ ~~ subst (wkn t $ keep thin) (Wkn (id n) :< pure (wkn u thin)) ...(sym $ substWkn t (keep thin) (Wkn (id n) :< pure (wkn u thin)))