diff options
author | Chloe Brown <chloe.brown.00@outlook.com> | 2023-06-08 14:23:29 +0100 |
---|---|---|
committer | Chloe Brown <chloe.brown.00@outlook.com> | 2023-06-08 14:23:29 +0100 |
commit | c64650ee0f41a1ebe45cf92c9b999f39825e9f5e (patch) | |
tree | 3458f26548dd5b8d857632a5aca3550fc0a30d69 | |
parent | 6590816a835110b8181472a5116dd4ecf67c957c (diff) |
Fully expand thinnings.
This makes adding CoDebruijn syntax simpler. If carrying the lengths of
contexts around is too inefficient, I can always switch back to
truncated thinnings.
-rw-r--r-- | src/Thinning.idr | 301 | ||||
-rw-r--r-- | src/Total/Encoded/Util.idr | 24 | ||||
-rw-r--r-- | src/Total/LogRel.idr | 48 | ||||
-rw-r--r-- | src/Total/NormalForm.idr | 4 | ||||
-rw-r--r-- | src/Total/Reduction.idr | 29 | ||||
-rw-r--r-- | src/Total/Syntax.idr | 31 | ||||
-rw-r--r-- | src/Total/Term.idr | 138 |
7 files changed, 336 insertions, 239 deletions
diff --git a/src/Thinning.idr b/src/Thinning.idr index a9b724d..f9e76b5 100644 --- a/src/Thinning.idr +++ b/src/Thinning.idr @@ -2,125 +2,239 @@ module Thinning import Data.SnocList.Elem +%prefix_record_projections off + -- Definition ------------------------------------------------------------------ public export -data Thins : SnocList a -> SnocList a -> Type -public export -data NotId : Thins sx sy -> Type - -data Thins where - Id : sx `Thins` sx +data Thins : SnocList a -> SnocList a -> Type where + Empty : [<] `Thins` [<] Drop : sx `Thins` sy -> sx `Thins` sy :< z Keep : (thin : sx `Thins` sy) -> - {auto 0 prf : NotId thin} -> sx :< z `Thins` sy :< z -data NotId where - DropNotId : NotId (Drop thin) - KeepNotId : (0 prf : NotId thin) -> NotId (Keep thin) - %name Thins thin --- Smart Constructors ---------------------------------------------------------- +-- Utility --------------------------------------------------------------------- public export -keep : sx `Thins` sy -> sx :< z `Thins` sy :< z -keep Id = Id -keep (Drop thin) = Keep (Drop thin) -keep (Keep thin) = Keep (Keep thin) +data Len : SnocList a -> Type where + Z : Len [<] + S : Len sx -> Len (sx :< x) + +%name Len k, m, n + +%hint +export +length : (sx : SnocList a) -> Len sx +length [<] = Z +length (sx :< x) = S (length sx) + +%hint +export +lenSrc : sx `Thins` sy -> Len sx +lenSrc Empty = Z +lenSrc (Drop thin) = lenSrc thin +lenSrc (Keep thin) = S (lenSrc thin) + +%hint +export +lenTgt : sx `Thins` sy -> Len sy +lenTgt Empty = Z +lenTgt (Drop thin) = S (lenTgt thin) +lenTgt (Keep thin) = S (lenTgt thin) + +%hint +export +lenPred : Len (sx :< x) -> Len sx +lenPred (S k) = k + +export +Cast (Len sx) Nat where + cast Z = 0 + cast (S k) = S (cast k) + +-- Smart Constructors ---------------------------------------------------------- + +export +empty : (len : Len sx) => [<] `Thins` sx +empty {len = Z} = Empty +empty {len = S k} = Drop empty public export -empty : (sx : SnocList a) -> [<] `Thins` sx -empty [<] = Id -empty (sx :< x) = Drop (empty sx) +id : (len : Len sx) => sx `Thins` sx +id {len = Z} = Empty +id {len = S k} = Keep id + +export +point : Len sx => Elem ty sx -> [<ty] `Thins` sx +point Here = Keep empty +point (There i) = Drop (point i) -- Operations ------------------------------------------------------------------ public export index : sx `Thins` sy -> Elem z sx -> Elem z sy -index Id i = i index (Drop thin) i = There (index thin i) index (Keep thin) Here = Here index (Keep thin) (There i) = There (index thin i) public export (.) : sy `Thins` sz -> sx `Thins` sy -> sx `Thins` sz -compNotId : - {0 thin2 : sy `Thins` sz} -> - {0 thin1 : sx `Thins` sy} -> - NotId thin2 -> NotId thin1 -> - NotId (thin2 . thin1) - -Id . thin1 = thin1 -(Drop thin2) . thin1 = Drop (thin2 . thin1) -(Keep thin2) . Id = Keep thin2 -(Keep thin2) . (Drop thin1) = Drop (thin2 . thin1) -(Keep {prf = prf2} thin2) . (Keep {prf = prf1} thin1) = - Keep {prf = compNotId prf2 prf1} (thin2 . thin1) - -compNotId DropNotId p = DropNotId -compNotId (KeepNotId prf) DropNotId = DropNotId -compNotId (KeepNotId prf) (KeepNotId prf') = KeepNotId (compNotId prf prf') +Empty . thin1 = thin1 +Drop thin2 . thin1 = Drop (thin2 . thin1) +Keep thin2 . Drop thin1 = Drop (thin2 . thin1) +Keep thin2 . Keep thin1 = Keep (thin2 . thin1) --- Properties ------------------------------------------------------------------ +export +(++) : sx `Thins` sy -> sz `Thins` sw -> sx ++ sz `Thins` sy ++ sw +thin2 ++ Empty = thin2 +thin2 ++ (Drop thin1) = Drop (thin2 ++ thin1) +thin2 ++ (Keep thin1) = Keep (thin2 ++ thin1) + +-- Commuting Triangles and Coverings ------------------------------------------- + +data Triangle : sy `Thins` sz -> sx `Thins` sy -> sx `Thins` sz -> Type where + EmptyAny : Triangle Empty thin1 thin1 + DropAny : Triangle thin2 thin1 thin -> Triangle (Drop thin2) thin1 (Drop thin) + KeepDrop : Triangle thin2 thin1 thin -> Triangle (Keep thin2) (Drop thin1) (Drop thin) + KeepKeep : Triangle thin2 thin1 thin -> Triangle (Keep thin2) (Keep thin1) (Keep thin) + +data Overlap = Covers | Partitions + +namespace Covering + public export + data Covering : Overlap -> sx `Thins` sz -> sy `Thins` sz -> Type where + EmptyEmpty : Covering ov Empty Empty + DropKeep : Covering ov thin1 thin2 -> Covering ov (Drop thin1) (Keep thin2) + KeepDrop : Covering ov thin1 thin2 -> Covering ov (Keep thin1) (Drop thin2) + KeepKeep : Covering Covers thin1 thin2 -> Covering Covers (Keep thin1) (Keep thin2) + +record Coproduct {sx, sy, sz : SnocList a} (thin1 : sx `Thins` sz) (thin2 : sy `Thins` sz) where + constructor MkCoprod + {0 sw : SnocList a} + {thin1' : sx `Thins` sw} + {thin2' : sy `Thins` sw} + {thin : sw `Thins` sz} + 0 left : Triangle thin thin1' thin1 + 0 right : Triangle thin thin2' thin2 + 0 cover : Covering Covers thin1' thin2' + +coprod : (thin1 : sx `Thins` sz) -> (thin2 : sy `Thins` sz) -> Coproduct thin1 thin2 +coprod Empty Empty = MkCoprod EmptyAny EmptyAny EmptyEmpty +coprod (Drop thin1) (Drop thin2) = + { left $= DropAny, right $= DropAny } (coprod thin1 thin2) +coprod (Drop thin1) (Keep thin2) = + { left $= KeepDrop, right $= KeepKeep, cover $= DropKeep } (coprod thin1 thin2) +coprod (Keep thin1) (Drop thin2) = + { left $= KeepKeep, right $= KeepDrop, cover $= KeepDrop } (coprod thin1 thin2) +coprod (Keep thin1) (Keep thin2) = + { left $= KeepKeep, right $= KeepKeep, cover $= KeepKeep } (coprod thin1 thin2) + +-- Splitting off Contexts ------------------------------------------------------ + +data Split : (global, local : SnocList a) -> (thin : sx `Thins` global ++ local) -> Type where + MkSplit : + (thin2 : sx `Thins` global) -> + (thin1 : used `Thins` local) -> + Split global local (thin2 ++ thin1) + +split : Len local -> (thin : sx `Thins` global ++ local) -> Split global local thin +split Z thin = MkSplit thin Empty +split (S k) (Drop thin) with (split k thin) + split (S k) (Drop .(thin2 ++ thin1)) | MkSplit thin2 thin1 = MkSplit thin2 (Drop thin1) +split (S k) (Keep thin) with (split k thin) + split (S k) (Keep .(thin2 ++ thin1)) | MkSplit thin2 thin1 = MkSplit thin2 (Keep thin1) + +-- Thinned Things -------------------------------------------------------------- --- NotId +public export +record Thinned (T : SnocList a -> Type) (sx : SnocList a) where + constructor Over + {0 support : SnocList a} + value : T support + thin : support `Thins` sx -NotIdUnique : (p, q : NotId thin) -> p = q -NotIdUnique DropNotId DropNotId = Refl -NotIdUnique (KeepNotId prf) (KeepNotId prf) = Refl +public export +record OverlapPair (overlap : Overlap) (T, U : SnocList a -> Type) (sx : SnocList a) where + constructor MakePair + left : Thinned T sx + right : Thinned U sx + 0 cover : Covering overlap left.thin right.thin --- index +public export +Pair : (T, U : SnocList a -> Type) -> SnocList a -> Type +Pair = OverlapPair Covers export -indexKeepHere : (thin : sx `Thins` sy) -> index (keep thin) Here = Here -indexKeepHere Id = Refl -indexKeepHere (Drop thin) = Refl -indexKeepHere (Keep thin) = Refl +MkPair : Thinned t sx -> Thinned u sx -> Thinned (OverlapPair Covers t u) sx +MkPair (t `Over` thin1) (u `Over` thin2) = + let cp = coprod thin1 thin2 in + MakePair (t `Over` cp.thin1') (u `Over` cp.thin2') cp.cover `Over` cp.thin + +public export +record Binds (local : SnocList a) (T : SnocList a -> Type) (sx : SnocList a) where + constructor MakeBound + {0 used : SnocList a} + value : T (sx ++ used) + thin : used `Thins` local export -indexKeepThere : - (thin : sx `Thins` sy) -> - (i : Elem x sx) -> - index (keep thin) (There i) = There (index thin i) -indexKeepThere Id i = Refl -indexKeepThere (Drop thin) i = Refl -indexKeepThere (Keep thin) i = Refl +MkBound : Len local -> Thinned t (sx ++ local) -> Thinned (Binds local t) sx +MkBound k (value `Over` thin) with (split k thin) + MkBound k (value `Over` .(thin2 ++ thin1)) | MkSplit thin2 thin1 = + MakeBound value thin1 `Over` thin2 + +export +map : (forall ctx. t ctx -> u ctx) -> Thinned t ctx -> Thinned u ctx +map f (value `Over` thin) = f value `Over` thin + +%hint +export +thinnedLen : Thinned t sx -> Len sx +thinnedLen (value `Over` thin) = lenTgt thin + +-- Properties ------------------------------------------------------------------ + +export +lenUnique : (k, m : Len sx) -> k = m +lenUnique Z Z = Refl +lenUnique (S k) (S m) = cong S (lenUnique k m) + +export +identityLeft : (len : Len sy) => (thin : sx `Thins` sy) -> id @{len} . thin = thin +identityLeft {len = Z} thin = Refl +identityLeft {len = S k} (Drop thin) = cong Drop (identityLeft thin) +identityLeft {len = S k} (Keep thin) = cong Keep (identityLeft thin) + +export +identityRight : (len : Len sx) => (thin : sx `Thins` sy) -> thin . id @{len} = thin +identityRight {len = Z} Empty = Refl +identityRight (Drop thin) = cong Drop (identityRight thin) +identityRight {len = S k} (Keep thin) = cong Keep (identityRight thin) --- (.) +export +identitySquared : (len : Len sx) -> id @{len} . id @{len} = id @{len} +identitySquared Z = Refl +identitySquared (S k) = cong Keep (identitySquared k) export assoc : - (thin3 : ctx'' `Thins` ctx''') -> - (thin2 : ctx' `Thins` ctx'') -> - (thin1 : ctx `Thins` ctx') -> + (thin3 : sz `Thins` sw) -> + (thin2 : sy `Thins` sz) -> + (thin1 : sx `Thins` sy) -> thin3 . (thin2 . thin1) = (thin3 . thin2) . thin1 -assoc Id thin2 thin1 = Refl +assoc Empty thin2 thin1 = Refl assoc (Drop thin3) thin2 thin1 = cong Drop (assoc thin3 thin2 thin1) -assoc (Keep thin3) Id thin1 = Refl assoc (Keep thin3) (Drop thin2) thin1 = cong Drop (assoc thin3 thin2 thin1) -assoc (Keep thin3) (Keep thin2) Id = Refl assoc (Keep thin3) (Keep thin2) (Drop thin1) = cong Drop (assoc thin3 thin2 thin1) -assoc (Keep {prf = prf3} thin3) (Keep {prf = prf2} thin2) (Keep {prf = prf1} thin1) = - let - eq : (thin3 . (thin2 . thin1) = (thin3 . thin2) . thin1) - eq = assoc thin3 thin2 thin1 - 0 prf : - (compNotId prf3 (compNotId prf2 prf1) = - (rewrite eq in compNotId (compNotId prf3 prf2) prf1)) - prf = NotIdUnique _ _ - in - rewrite eq in - rewrite prf in - Refl - -export -identityRight : (thin : sx `Thins` sy) -> thin . Id = thin -identityRight Id = Refl -identityRight (Drop thin) = cong Drop (identityRight thin) -identityRight (Keep thin) = Refl +assoc (Keep thin3) (Keep thin2) (Keep thin1) = cong Keep (assoc thin3 thin2 thin1) + +export +indexId : (len : Len sx) => (i : Elem x sx) -> index (id @{len}) i = i +indexId {len = S k} Here = Refl +indexId {len = S k} (There i) = cong There (indexId i) export indexHomo : @@ -128,31 +242,8 @@ indexHomo : (thin1 : sx `Thins` sy) -> (i : Elem x sx) -> index thin2 (index thin1 i) = index (thin2 . thin1) i -indexHomo Id thin1 i = Refl -indexHomo (Drop thin2) thin1 i = cong There $ indexHomo thin2 thin1 i -indexHomo (Keep thin2) Id i = Refl -indexHomo (Keep thin2) (Drop thin1) i = cong There $ indexHomo thin2 thin1 i +indexHomo Empty Empty i impossible +indexHomo (Drop thin2) thin1 i = cong There (indexHomo thin2 thin1 i) +indexHomo (Keep thin2) (Drop thin1) i = cong There (indexHomo thin2 thin1 i) indexHomo (Keep thin2) (Keep thin1) Here = Refl -indexHomo (Keep thin2) (Keep thin1) (There i) = cong There $ indexHomo thin2 thin1 i - -export -keepHomo : - (thin2 : sy `Thins` sz) -> - (thin1 : sx `Thins` sy) -> - keep thin2 . keep thin1 = keep (thin2 . thin1) -keepHomo Id thin1 = Refl -keepHomo (Drop thin2) Id = rewrite identityRight thin2 in Refl -keepHomo (Drop thin2) (Drop thin1) = Refl -keepHomo (Drop thin2) (Keep thin1) = Refl -keepHomo (Keep thin2) Id = Refl -keepHomo (Keep thin2) (Drop thin) = Refl -keepHomo (Keep thin2) (Keep thin) = Refl - -export -keepDrop : - (thin2 : sy `Thins` sz) -> - (thin1 : sx `Thins` sy) -> - keep thin2 . Drop thin1 = Drop (thin2 . thin1) -keepDrop Id thin1 = Refl -keepDrop (Drop thin2) thin1 = Refl -keepDrop (Keep thin2) thin1 = Refl +indexHomo (Keep thin2) (Keep thin1) (There i) = cong There (indexHomo thin2 thin1 i) diff --git a/src/Total/Encoded/Util.idr b/src/Total/Encoded/Util.idr index 705d74b..1a848c0 100644 --- a/src/Total/Encoded/Util.idr +++ b/src/Total/Encoded/Util.idr @@ -22,8 +22,8 @@ namespace Bool False = Suc Zero export - If : Term ctx B -> Term ctx ty -> Term ctx ty -> Term ctx ty - If t u v = Rec t u (Abs $ wkn v (Drop Id)) + If : Len ctx => Term ctx B -> Term ctx ty -> Term ctx ty -> Term ctx ty + If t u v = Rec t u (Abs $ wkn v (Drop id)) namespace Arb export @@ -112,7 +112,7 @@ namespace Pair export mapProd : {ctx, tys, tys' : SnocList Ty} -> - {auto 0 prf : length tys = length tys'} -> + {auto 0 prf : SnocList.length tys = SnocList.length tys'} -> All (Term ctx) (zipWith (~>) tys tys') -> Term ctx (Product tys ~> Product tys') mapProd {tys = [<], tys' = [<]} [<] = Abs (Var Here) @@ -120,8 +120,8 @@ namespace Pair Abs' (S Z) (\p => App' (lift pair) - [<App (wkn (mapProd fs {prf = injective prf}) (Drop Id) . lift fst) p - , App (wkn f (Drop Id) . lift snd) p + [<App (wkn (mapProd fs {prf = injective prf}) (Drop id) . lift fst) p + , App (wkn f (Drop id) . lift snd) p ]) replicate : Nat -> a -> SnocList a @@ -292,9 +292,9 @@ namespace Nat Cond ((n, v) :: xs) = Abs' (S Z) (\t => - If (App' (lift LE) [<t, wkn n (Drop Id)]) - (App (wkn v (Drop Id)) t) - (App (wkn (Cond xs) (Drop Id)) (App' (lift Sub) [<t, wkn n (Drop Id)]))) + If (App' (lift LE) [<t, wkn n (Drop id)]) + (App (wkn v (Drop id)) t) + (App (wkn (Cond xs) (Drop id)) (App' (lift Sub) [<t, wkn n (Drop id)]))) namespace Data public export @@ -394,7 +394,7 @@ namespace Data (lift $ put {tys = map (flip fillShape N) c} $ rewrite forgetMap (flip fillShape N) c in elemMap (flip fillShape N) i) - (App' (lift mapSnd) [<Abs (lift $ enumerate n), wkn t (Drop Id)]))) + (App' (lift mapSnd) [<Abs (lift $ enumerate n), wkn t (Drop id)]))) :: calcData (App (lift snd) t) (Suc Zero) ) ]) @@ -409,8 +409,8 @@ namespace Data elim cases = Abs' (S Z) (\t => let tags = Suc (App (lift $ project $ There $ There Here) t) in - let offset = App (lift $ project $ There Here) (wkn t (Drop $ Drop Id)) in - let vals = App (lift $ project $ Here) (wkn t (Drop $ Drop Id)) in + let offset = App (lift $ project $ There Here) (wkn t (Drop $ Drop id)) in + let vals = App (lift $ project $ Here) (wkn t (Drop $ Drop id)) in App' (Rec tags (lift arb) @@ -420,7 +420,7 @@ namespace Data (rewrite forgetMap (flip fillShape N) c in gmap (\f => - wkn f (Drop $ Drop $ Drop Id) . + wkn f (Drop $ Drop $ Drop id) . App (lift mapShape) (rec . App (lift Add) (App offset n))) cases) . vals) diff --git a/src/Total/LogRel.idr b/src/Total/LogRel.idr index 1ed7276..ebde8d5 100644 --- a/src/Total/LogRel.idr +++ b/src/Total/LogRel.idr @@ -178,44 +178,49 @@ allValid : allValid help (Var i) sub allRels = index help.var allRels i allValid help (Abs t) sub allRels = let valid = allValid help t in - ( let + (let rec = valid - (wknAll sub (Drop Id) :< Var Here) - (wknAllRel help allRels (Drop Id) :< help.var Here) + (wknAll sub (Drop $ id @{termsLen sub}) :< Var Here) + (wknAllRel help allRels (Drop $ id @{termsLen sub}) :< help.var Here) in help.abs rec , \thin, u, rel => let eq : - (subst (wkn (subst t (wknAll sub (Drop Id) :< Var Here)) (keep thin)) (Base Id :< u) = + (subst + (wkn (subst t (wknAll sub (Drop $ id @{termsLen sub}) :< Var Here)) (Keep thin)) + (Base (id @{length _}) :< u) = subst t (wknAll sub thin :< u)) - eq = Calc $ - |~ subst (wkn (subst t (wknAll sub (Drop Id) :< Var Here)) (keep thin)) (Base Id :< u) - ~~ subst (subst t (wknAll sub (Drop Id) :< Var Here)) (restrict (Base Id :< u) (keep thin)) - ...(substWkn (subst t (wknAll sub (Drop Id) :< Var Here)) (keep thin) (Base Id :< u)) - ~~ subst (subst t (wknAll sub (Drop Id) :< Var Here)) (Base thin :< u) - ...(cong (subst (subst t (wknAll sub (Drop Id) :< Var Here))) $ restrictKeep (Base Id) u thin) - ~~ subst t ((Base thin :< u) . wknAll sub (Drop Id) :< u) - ...(substHomo t (wknAll sub (Drop Id) :< Var Here) (Base thin :< u)) - ~~ subst t (Base (thin . Id) . sub :< u) - ...(cong (subst t . (:< u)) $ compWknAll sub (Base thin :< u) (Drop Id)) - ~~ subst t (Base thin . sub :< u) - ...(cong (subst t . (:< u) . (. sub) . Base) $ identityRight thin) - ~~ subst t (wknAll sub thin :< u) - ...(cong (subst t . (:< u)) $ baseComp thin sub) + eq = + rewrite lenUnique (termsLen sub) (length ctx') in + Calc $ + |~ subst (wkn (subst t (wknAll sub (Drop id) :< Var Here)) (Keep thin)) (Base id :< u) + ~~ subst (subst t (wknAll sub (Drop id) :< Var Here)) (restrict (Base id :< u) (Keep thin)) + ...(substWkn (subst t (wknAll sub (Drop id) :< Var Here)) (Keep thin) (Base id :< u)) + ~~ subst (subst t (wknAll sub (Drop id) :< Var Here)) (Base thin :< u) + ...(cong (subst (subst t (wknAll sub (Drop id) :< Var Here)) . (:< u) . Base) $ identityLeft thin) + ~~ subst t ((Base thin :< u) . wknAll sub (Drop id) :< u) + ...(substHomo t (wknAll sub (Drop id) :< Var Here) (Base thin :< u)) + ~~ subst t (Base (thin . id) . sub :< u) + ...(cong (subst t . (:< u)) $ compWknAll sub (Base thin :< u) (Drop id)) + ~~ subst t (Base thin . sub :< u) + ...(cong (subst t . (:< u) . (. sub) . Base) $ identityRight thin) + ~~ subst t (wknAll sub thin :< u) + ...(cong (subst t . (:< u)) $ baseComp thin sub) in preserve (backStepHelper help.step) (valid (wknAll sub thin :< u) (wknAllRel help allRels thin :< rel)) (replace {p = (App (wkn (subst (Abs t) sub) thin) u >)} eq - AppBeta) + (AppBeta (length _))) ) allValid help (App t u) sub allRels = let (pt, app) = allValid help t sub allRels in let rel = allValid help u sub allRels in - rewrite sym $ wknId (subst t sub) in app Id (subst u sub) rel + rewrite sym $ wknId @{termsLen sub} (subst t sub) in + app (id @{termsLen sub}) (subst u sub) rel allValid help Zero sub allRels = help.zero allValid help (Suc t) sub allRels = let pt = allValid help t sub allRels in @@ -234,4 +239,5 @@ allRel : ValidHelper P -> (t : Term ctx ty) -> P t -allRel help t = rewrite sym $ substId t in escape (allValid help t (Base Id) Base) +allRel help t = + rewrite sym $ substId @{length ctx} t in escape (allValid help t (Base $ id @{length ctx}) Base) diff --git a/src/Total/NormalForm.idr b/src/Total/NormalForm.idr index b5580b5..266d00d 100644 --- a/src/Total/NormalForm.idr +++ b/src/Total/NormalForm.idr @@ -93,8 +93,8 @@ recNf' : recNf' Zero n relU relV = backStepsRel relU [<RecZero] recNf' (Suc t') n relU relV = let rec = recNf' t' (invSuc n) relU relV in - let step : Rec (Suc t') u v > App (wkn v Id) (Rec t' u v) = rewrite wknId v in RecSuc in - backStepsRel (snd relV Id _ rec) [<step] + let step : Rec (Suc t') u v > App (wkn v id) (Rec t' u v) = rewrite wknId v in RecSuc in + backStepsRel (snd relV id _ rec) [<step] recNf' t'@(Var _) n relU relV = let nfU = escape relU in let nfV = escape {ty = ty ~> ty} relV in diff --git a/src/Total/Reduction.idr b/src/Total/Reduction.idr index cb13706..b11665b 100644 --- a/src/Total/Reduction.idr +++ b/src/Total/Reduction.idr @@ -8,7 +8,9 @@ data (>) : Term ctx ty -> Term ctx ty -> Type where AbsCong : t > u -> Abs t > Abs u AppCong1 : t > u -> App t v > App u v AppCong2 : u > v -> App t u > App t v - AppBeta : App (Abs t) u > subst t (Base Id :< u) + AppBeta : + (0 len : Len ctx) -> + App (Abs t) u > subst t (Base (id @{len}) :< u) SucCong : t > u -> Suc t > Suc u RecCong1 : t1 > t2 -> Rec t1 u v > Rec t2 u v RecCong2 : u1 > u2 -> Rec t u1 v > Rec t u2 v @@ -68,27 +70,28 @@ RecCong3' (steps :< step) = RecCong3' steps :< RecCong3 step -- Properties ------------------------------------------------------------------ lemma : + (0 len : Len ctx) -> (t : Term (ctx :< ty) ty') -> (thin : ctx `Thins` ctx') -> (u : Term ctx ty) -> - subst (wkn t (keep thin)) (Base Id :< wkn u thin) = wkn (subst t (Base Id :< u)) thin -lemma t thin u = Calc $ - |~ subst (wkn t (keep thin)) (Base Id :< wkn u thin) - ~~ subst t (restrict (Base Id :< wkn u thin) (keep thin)) - ...(substWkn t (keep thin) (Base Id :< wkn u thin)) - ~~ subst t (Base thin :< wkn u thin) - ...(cong (subst t) $ restrictKeep (Base Id) (wkn u thin) thin) - ~~ subst t (Base (thin . Id) :< wkn u thin) - ...(sym $ cong (subst t . (:< wkn u thin) . Base) $ identityRight thin) - ~~ wkn (subst t (Base Id :< u)) thin - ...(sym $ wknSubst t (Base Id :< u) thin) + subst (wkn t (Keep thin)) (Base Thinning.id :< wkn u thin) = wkn (subst t (Base (id @{len}) :< u)) thin +lemma len t thin u = Calc $ + |~ subst (wkn t (Keep thin)) (Base id :< wkn u thin) + ~~ subst t (restrict (Base id :< wkn u thin) (Keep thin)) + ...(substWkn t (Keep thin) (Base id :< wkn u thin)) + ~~ subst t (Base (id . thin) :< wkn u thin) + ...(Refl) + ~~ subst t (Base (thin . id) :< wkn u thin) + ...(cong (subst t . (:< wkn u thin) . Base) $ trans (identityLeft thin) (sym $ identityRight thin)) + ~~ wkn (subst t (Base id :< u)) thin + ...(sym $ wknSubst t (Base id :< u) thin) export wknStep : t > u -> wkn t thin > wkn u thin wknStep (AbsCong step) = AbsCong (wknStep step) wknStep (AppCong1 step) = AppCong1 (wknStep step) wknStep (AppCong2 step) = AppCong2 (wknStep step) -wknStep (AppBeta {t, u}) {thin} = rewrite sym $ lemma t thin u in AppBeta +wknStep (AppBeta len {t, u}) {thin} = rewrite sym $ lemma len t thin u in AppBeta _ wknStep (SucCong step) = SucCong (wknStep step) wknStep (RecCong1 step) = RecCong1 (wknStep step) wknStep (RecCong2 step) = RecCong2 (wknStep step) diff --git a/src/Total/Syntax.idr b/src/Total/Syntax.idr index 084ae3e..6c34250 100644 --- a/src/Total/Syntax.idr +++ b/src/Total/Syntax.idr @@ -14,29 +14,17 @@ public export tys ~>* ty = foldr (~>) ty tys public export -data Len : SnocList Ty -> Type where - Z : Len [<] - S : Len tys -> Len (tys :< ty) - -%name Len k, m, n - -public export -Cast (Len ctx) Nat where - cast Z = 0 - cast (S k) = S (cast k) - -public export -0 Fun : Len tys -> (Ty -> Type) -> Type -> Type +0 Fun : {sx : SnocList a} -> Len sx -> (a -> Type) -> Type -> Type Fun Z arg ret = ret -Fun (S {ty} k) arg ret = Fun k arg (arg ty -> ret) +Fun (S {x = ty} k) arg ret = Fun k arg (arg ty -> ret) -after : (k : Len tys) -> (a -> b) -> Fun k p a -> Fun k p b +after : (k : Len sx) -> (a -> b) -> Fun k p a -> Fun k p b after Z f x = f x after (S k) f x = after k (f .) x before : - (k : Len tys) -> - (forall ty. p ty -> q ty) -> + (k : Len sx) -> + (forall x. p x -> q x) -> Fun k q ret -> Fun k p ret before Z f x = x @@ -70,19 +58,20 @@ App' t [<] = t App' t (us :< u) = App (App' t us) u export -(.) : {ty, ty' : Ty} -> Term ctx (ty' ~> ty'') -> Term ctx (ty ~> ty') -> Term ctx (ty ~> ty'') -t . u = Abs' (S Z) (\x => App (wkn t (Drop Id)) (App (wkn u (Drop Id)) x)) +(.) : Len ctx => {ty, ty' : Ty} -> Term ctx (ty' ~> ty'') -> Term ctx (ty ~> ty') -> Term ctx (ty ~> ty'') +t . u = Abs' (S Z) (\x => App (wkn t (Drop id)) (App (wkn u (Drop id)) x)) export (.*) : + Len ctx => {ty : Ty} -> {tys : SnocList Ty} -> Term ctx (ty ~> ty') -> Term ctx (tys ~>* ty) -> Term ctx (tys ~>* ty') (.*) {tys = [<]} t u = App t u -(.*) {tys = tys :< ty''} t u = Abs' (S Z) (\f => wkn t (Drop Id) . f) .* u +(.*) {tys = tys :< ty''} t u = Abs' (S Z) (\f => wkn t (Drop id) . f) .* u export lift : {ctx : SnocList Ty} -> Term [<] ty -> Term ctx ty -lift t = wkn t (empty ctx) +lift t = wkn t empty diff --git a/src/Total/Term.idr b/src/Total/Term.idr index d4da92a..d21ec73 100644 --- a/src/Total/Term.idr +++ b/src/Total/Term.idr @@ -29,7 +29,7 @@ data Term : SnocList Ty -> Ty -> Type where public export wkn : Term ctx ty -> ctx `Thins` ctx' -> Term ctx' ty wkn (Var i) thin = Var (index thin i) -wkn (Abs t) thin = Abs (wkn t $ keep thin) +wkn (Abs t) thin = Abs (wkn t $ Keep thin) wkn (App t u) thin = App (wkn t thin) (wkn u thin) wkn Zero thin = Zero wkn (Suc t) thin = Suc (wkn t thin) @@ -42,6 +42,12 @@ data Terms : SnocList Ty -> SnocList Ty -> Type where %name Terms sub +%hint +export +termsLen : Terms ctx' ctx -> Len ctx' +termsLen (Base thin) = lenTgt thin +termsLen (sub :< t) = termsLen sub + public export index : Terms ctx' ctx -> Elem ty ctx -> Term ctx' ty index (Base thin) i = Var (index thin i) @@ -56,7 +62,7 @@ wknAll (sub :< t) thin = wknAll sub thin :< wkn t thin public export subst : Term ctx ty -> Terms ctx' ctx -> Term ctx' ty subst (Var i) sub = index sub i -subst (Abs t) sub = Abs (subst t $ wknAll sub (Drop Id) :< Var Here) +subst (Abs t) sub = Abs (subst t $ wknAll sub (Drop id) :< Var Here) subst (App t u) sub = App (subst t sub) (subst u sub) subst Zero sub = Zero subst (Suc t) sub = Suc (subst t sub) @@ -65,7 +71,6 @@ subst (Rec t u v) sub = Rec (subst t sub) (subst u sub) (subst v sub) public export restrict : Terms ctx'' ctx' -> ctx `Thins` ctx' -> Terms ctx'' ctx restrict (Base thin') thin = Base (thin' . thin) -restrict (sub :< t) Id = sub :< t restrict (sub :< t) (Drop thin) = restrict sub thin restrict (sub :< t) (Keep thin) = restrict sub thin :< t @@ -92,7 +97,7 @@ wknHomo : wknHomo (Var i) thin1 thin2 = cong Var (indexHomo thin2 thin1 i) wknHomo (Abs t) thin1 thin2 = - cong Abs $ trans (wknHomo t (keep thin1) (keep thin2)) (cong (wkn t) $ keepHomo thin2 thin1) + cong Abs (wknHomo t (Keep thin1) (Keep thin2)) wknHomo (App t u) thin1 thin2 = cong2 App (wknHomo t thin1 thin2) (wknHomo u thin1 thin2) wknHomo Zero thin1 thin2 = @@ -103,8 +108,8 @@ wknHomo (Rec t u v) thin1 thin2 = cong3 Rec (wknHomo t thin1 thin2) (wknHomo u thin1 thin2) (wknHomo v thin1 thin2) export -wknId : (t : Term ctx ty) -> wkn t Id = t -wknId (Var i) = Refl +wknId : Len ctx => (t : Term ctx ty) -> wkn t Thinning.id = t +wknId (Var i) = cong Var (indexId i) wknId (Abs t) = cong Abs (wknId t) wknId (App t u) = cong2 App (wknId t) (wknId u) wknId Zero = Refl @@ -136,24 +141,13 @@ indexRestrict : (i : Elem ty ctx) -> index (restrict sub thin) i = index sub (index thin i) indexRestrict thin (Base thin') i = sym $ cong Var $ indexHomo thin' thin i -indexRestrict Id (sub :< t) i = Refl indexRestrict (Drop thin) (sub :< t) i = indexRestrict thin sub i indexRestrict (Keep thin) (sub :< t) Here = Refl indexRestrict (Keep thin) (sub :< t) (There i) = indexRestrict thin sub i -restrictId : (sub : Terms ctx' ctx) -> restrict sub Id = sub +restrictId : (len : Len ctx) => (sub : Terms ctx' ctx) -> restrict sub (id @{len}) = sub restrictId (Base thin) = cong Base (identityRight thin) -restrictId (sub :< t) = Refl - -export -restrictKeep : - (sub : Terms ctx'' ctx) -> - (t : Term ctx'' ty) -> - (thin : ctx' `Thins` ctx) -> - restrict (sub :< t) (keep thin) = restrict sub thin :< t -restrictKeep sub t Id = sym $ cong (:< t) $ restrictId sub -restrictKeep sub t (Drop thin) = Refl -restrictKeep sub t (Keep thin) = Refl +restrictId {len = S k} (sub :< t) = cong (:< t) (restrictId sub) restrictHomo : (sub : Terms ctx ctx''') -> @@ -161,9 +155,7 @@ restrictHomo : (thin2 : ctx' `Thins` ctx'') -> restrict sub (thin1 . thin2) = restrict (restrict sub thin1) thin2 restrictHomo (Base thin) thin1 thin2 = cong Base (assoc thin thin1 thin2) -restrictHomo (sub :< t) Id thin2 = Refl restrictHomo (sub :< t) (Drop thin1) thin2 = restrictHomo sub thin1 thin2 -restrictHomo (sub :< t) (Keep thin1) Id = Refl restrictHomo (sub :< t) (Keep thin1) (Drop thin2) = restrictHomo sub thin1 thin2 restrictHomo (sub :< t) (Keep thin1) (Keep thin2) = cong (:< t) $ restrictHomo sub thin1 thin2 @@ -173,7 +165,6 @@ wknAllRestrict : (thin2 : ctx'' `Thins` ctx''') -> restrict (wknAll sub thin2) thin1 = wknAll (restrict sub thin1) thin2 wknAllRestrict thin1 (Base thin) thin2 = sym $ cong Base $ assoc thin2 thin thin1 -wknAllRestrict Id (sub :< t) thin2 = Refl wknAllRestrict (Drop thin) (sub :< t) thin2 = wknAllRestrict thin sub thin2 wknAllRestrict (Keep thin) (sub :< t) thin2 = cong (:< wkn t thin2) (wknAllRestrict thin sub thin2) @@ -188,16 +179,17 @@ wknSubst : wknSubst (Var i) sub thin = sym (indexWknAll sub thin i) wknSubst (Abs t) sub thin = + rewrite lenUnique (termsLen $ wknAll sub thin) (lenTgt thin) in cong Abs $ Calc $ - |~ wkn (subst t (wknAll sub (Drop Id) :< Var Here)) (keep thin) - ~~ subst t (wknAll (wknAll sub (Drop Id)) (keep thin) :< Var (index (keep thin) Here)) - ...(wknSubst t (wknAll sub (Drop Id) :< Var Here) (keep thin)) - ~~ subst t (wknAll sub (keep thin . Drop Id) :< Var Here) - ...(cong2 (\sub, i => subst t (sub :< Var i)) (wknAllHomo sub (Drop Id) (keep thin)) (indexKeepHere thin)) - ~~ subst t (wknAll sub (Drop Id . thin) :< Var Here) - ...(cong (subst t . (:< Var Here) . wknAll sub) $ trans (keepDrop thin Id) (cong Drop $ identityRight thin)) - ~~ subst t (wknAll (wknAll sub thin) (Drop Id) :< Var Here) - ...(sym $ cong (subst t . (:< Var Here)) $ wknAllHomo sub thin (Drop Id)) + |~ wkn (subst t (wknAll sub (Drop id) :< Var Here)) (Keep thin) + ~~ subst t (wknAll (wknAll sub (Drop id)) (Keep thin) :< Var (index (Keep thin) Here)) + ...(wknSubst t (wknAll sub (Drop id) :< Var Here) (Keep thin)) + ~~ subst t (wknAll sub (Keep thin . Drop id) :< Var Here) + ...(cong (subst t . (:< Var Here)) (wknAllHomo sub (Drop id) (Keep thin))) + ~~ subst t (wknAll sub (Drop id . thin) :< Var Here) + ...(cong (subst t . (:< Var Here) . wknAll sub . Drop) $ trans (identityRight thin) (sym $ identityLeft thin)) + ~~ subst t (wknAll (wknAll sub thin) (Drop id) :< Var Here) + ...(sym $ cong (subst t . (:< Var Here)) $ wknAllHomo sub thin (Drop id)) wknSubst (App t u) sub thin = cong2 App (wknSubst t sub thin) (wknSubst u sub thin) wknSubst Zero sub thin = @@ -216,14 +208,13 @@ substWkn : substWkn (Var i) thin sub = sym (indexRestrict thin sub i) substWkn (Abs t) thin sub = + rewrite lenUnique (termsLen $ restrict sub thin) (termsLen sub) in cong Abs $ Calc $ - |~ subst (wkn t $ keep thin) (wknAll sub (Drop Id) :< Var Here) - ~~ subst t (restrict (wknAll sub (Drop Id) :< Var Here) (keep thin)) - ...(substWkn t (keep thin) (wknAll sub (Drop Id) :< Var Here)) - ~~ subst t (restrict (wknAll sub (Drop Id)) thin :< Var Here) - ...(cong (subst t) $ restrictKeep (wknAll sub (Drop Id)) (Var Here) thin) - ~~ subst t (wknAll (restrict sub thin) (Drop Id) :< Var Here) - ...(cong (subst t . (:< Var Here)) $ wknAllRestrict thin sub (Drop Id)) + |~ subst (wkn t $ Keep thin) (wknAll sub (Drop id) :< Var Here) + ~~ subst t (restrict (wknAll sub (Drop id)) thin :< Var Here) + ...(substWkn t (Keep thin) (wknAll sub (Drop id) :< Var Here)) + ~~ subst t (wknAll (restrict sub thin) (Drop id) :< Var Here) + ...(cong (subst t . (:< Var Here)) $ wknAllRestrict thin sub (Drop id)) substWkn (App t u) thin sub = cong2 App (substWkn t thin sub) (substWkn u thin sub) substWkn Zero thin sub = @@ -236,26 +227,37 @@ substWkn (Rec t u v) thin sub = namespace Equiv public export data Equiv : Terms ctx' ctx -> Terms ctx' ctx -> Type where - Base : Equiv (Base (keep thin)) (Base (Drop thin) :< Var Here) + Base : Equiv (Base (Keep thin)) (Base (Drop thin) :< Var Here) WknAll : + (len : Len ctx) => Equiv sub sub' -> - Equiv (wknAll sub (Drop Id) :< Var Here) (wknAll sub' (Drop Id) :< Var Here) + Equiv + (wknAll sub (Drop $ id @{len}) :< Var Here) + (wknAll sub' (Drop $ id @{len}) :< Var Here) %name Equiv prf indexCong : Equiv sub sub' -> (i : Elem ty ctx) -> index sub i = index sub' i -indexCong Base Here = irrelevantEq $ cong Var (indexKeepHere _) -indexCong Base (There i) = irrelevantEq $ cong Var (indexKeepThere _ i) +indexCong Base Here = Refl +indexCong Base (There i) = Refl indexCong (WknAll prf) Here = Refl indexCong (WknAll {sub, sub'} prf) (There i) = Calc $ - |~ index (wknAll sub (Drop Id)) i - ~~ wkn (index sub i) (Drop Id) ...(indexWknAll sub (Drop Id) i) - ~~ wkn (index sub' i) (Drop Id) ...(cong (flip wkn (Drop Id)) $ indexCong prf i) - ~~ index (wknAll sub' (Drop Id)) i ...(sym $ indexWknAll sub' (Drop Id) i) + |~ index (wknAll sub (Drop id)) i + ~~ wkn (index sub i) (Drop id) ...(indexWknAll sub (Drop id) i) + ~~ wkn (index sub' i) (Drop id) ...(cong (flip wkn (Drop id)) $ indexCong prf i) + ~~ index (wknAll sub' (Drop id)) i ...(sym $ indexWknAll sub' (Drop id) i) -substCong : (t : Term ctx ty) -> Equiv sub sub' -> subst t sub = subst t sub' +substCong : + (len : Len ctx') => + (t : Term ctx ty) -> + {0 sub, sub' : Terms ctx' ctx} -> + Equiv sub sub' -> + subst t sub = subst t sub' substCong (Var i) prf = indexCong prf i -substCong (Abs t) prf = cong Abs (substCong t (WknAll prf)) +substCong (Abs t) prf = + rewrite lenUnique (termsLen sub) (termsLen sub') in + rewrite lenUnique (termsLen sub') len in + cong Abs (substCong t (WknAll prf)) substCong (App t u) prf = cong2 App (substCong t prf) (substCong u prf) substCong Zero prf = Refl substCong (Suc t) prf = cong Suc (substCong t prf) @@ -263,10 +265,12 @@ substCong (Rec t u v) prf = cong3 Rec (substCong t prf) (substCong u prf) (subst substBase : (t : Term ctx ty) -> (thin : ctx `Thins` ctx') -> subst t (Base thin) = wkn t thin substBase (Var i) thin = Refl -substBase (Abs t) thin = cong Abs $ Calc $ - |~ subst t (Base (Drop thin) :< Var Here) - ~~ subst t (Base $ keep thin) ...(sym $ substCong t Base) - ~~ wkn t (keep thin) ...(substBase t (keep thin)) +substBase (Abs t) thin = + rewrite identityLeft thin in + cong Abs $ Calc $ + |~ subst t (Base (Drop thin) :< Var Here) + ~~ subst t (Base $ Keep thin) ...(sym $ substCong t Base) + ~~ wkn t (Keep thin) ...(substBase t (Keep thin)) substBase (App t u) thin = cong2 App (substBase t thin) (substBase u thin) substBase Zero thin = Refl substBase (Suc t) thin = cong Suc (substBase t thin) @@ -322,9 +326,12 @@ baseComp thin (sub :< t) = cong2 (:<) (baseComp thin sub) (substBase t thin) -- Substitution export -substId : (t : Term ctx ty) -> subst t (Base Id) = t -substId (Var i) = Refl -substId (Abs t) = cong Abs $ trans (sym $ substCong t Base) (substId t) +substId : (len : Len ctx) => (t : Term ctx ty) -> subst t (Base $ id @{len}) = t +substId (Var i) = cong Var (indexId i) +substId (Abs t) = + rewrite lenUnique (termsLen $ Base $ id @{len}) len in + rewrite identitySquared len in + cong Abs $ trans (sym $ substCong t Base) (substId t) substId (App t u) = cong2 App (substId t) (substId u) substId Zero = Refl substId (Suc t) = cong Suc (substId t) @@ -339,18 +346,19 @@ substHomo : substHomo (Var i) sub1 sub2 = sym $ indexComp sub1 sub2 i substHomo (Abs t) sub1 sub2 = + rewrite lenUnique (termsLen $ sub2 . sub1) (termsLen sub2) in cong Abs $ Calc $ - |~ subst (subst t (wknAll sub1 (Drop Id) :< Var Here)) (wknAll sub2 (Drop Id) :< Var Here) - ~~ subst t ((wknAll sub2 (Drop Id) :< Var Here) . (wknAll sub1 (Drop Id) :< Var Here)) - ...(substHomo t (wknAll sub1 (Drop Id) :< Var Here) (wknAll sub2 (Drop Id) :< Var Here)) - ~~ subst t ((wknAll sub2 (Drop Id) :< Var Here) . wknAll sub1 (Drop Id) :< Var Here) + |~ subst (subst t (wknAll sub1 (Drop id) :< Var Here)) (wknAll sub2 (Drop id) :< Var Here) + ~~ subst t ((wknAll sub2 (Drop id) :< Var Here) . (wknAll sub1 (Drop id) :< Var Here)) + ...(substHomo t (wknAll sub1 (Drop id) :< Var Here) (wknAll sub2 (Drop id) :< Var Here)) + ~~ subst t ((wknAll sub2 (Drop id) :< Var Here) . wknAll sub1 (Drop id) :< Var Here) ...(Refl) - ~~ subst t (restrict (wknAll sub2 (Drop Id)) Id . sub1 :< Var Here) - ...(cong (subst t . (:< Var Here)) $ compDrop sub1 (Drop Id) (wknAll sub2 (Drop Id) :< Var Here)) - ~~ subst t (wknAll sub2 (Drop Id) . sub1 :< Var Here) - ...(cong (subst t . (:< Var Here) . (. sub1)) $ restrictId (wknAll sub2 (Drop Id))) - ~~ subst t (wknAll (sub2 . sub1) (Drop Id) :< Var Here) - ...(cong (subst t . (:< Var Here)) $ wknAllComp sub1 sub2 (Drop Id)) + ~~ subst t (restrict (wknAll sub2 (Drop id)) id . sub1 :< Var Here) + ...(cong (subst t . (:< Var Here)) $ compDrop sub1 (Drop id) (wknAll sub2 (Drop id) :< Var Here)) + ~~ subst t (wknAll sub2 (Drop id) . sub1 :< Var Here) + ...(cong (subst t . (:< Var Here) . (. sub1)) $ restrictId (wknAll sub2 (Drop id))) + ~~ subst t (wknAll (sub2 . sub1) (Drop id) :< Var Here) + ...(cong (subst t . (:< Var Here)) $ wknAllComp sub1 sub2 (Drop id)) substHomo (App t u) sub1 sub2 = cong2 App (substHomo t sub1 sub2) (substHomo u sub1 sub2) substHomo Zero sub1 sub2 = |