diff options
author | Chloe Brown <chloe.brown.00@outlook.com> | 2023-06-16 15:06:59 +0100 |
---|---|---|
committer | Chloe Brown <chloe.brown.00@outlook.com> | 2023-06-16 15:06:59 +0100 |
commit | 5adc1ae9357e42937a601aab57d16b2190e10536 (patch) | |
tree | 219b0bac7058abd55729990536fb93cecda7cc7b | |
parent | f910e142ce7c10f8244ecfa40e41756fb8c8a53f (diff) |
Reset using only co-de Bruijn syntax.
-rw-r--r-- | church-eval.ipkg | 8 | ||||
-rw-r--r-- | src/Term.idr | 341 | ||||
-rw-r--r-- | src/Thinned.idr | 140 | ||||
-rw-r--r-- | src/Thinning.idr | 566 | ||||
-rw-r--r-- | src/Total/Encoded/Util.idr | 444 | ||||
-rw-r--r-- | src/Total/LogRel.idr | 355 | ||||
-rw-r--r-- | src/Total/NormalForm.idr | 187 | ||||
-rw-r--r-- | src/Total/Pretty.idr | 163 | ||||
-rw-r--r-- | src/Total/Reduction.idr | 114 | ||||
-rw-r--r-- | src/Total/Syntax.idr | 128 | ||||
-rw-r--r-- | src/Total/Term.idr | 357 | ||||
-rw-r--r-- | src/Total/Term/CoDebruijn.idr | 317 | ||||
-rw-r--r-- | src/Type.idr | 10 |
13 files changed, 822 insertions, 2308 deletions
diff --git a/church-eval.ipkg b/church-eval.ipkg index 2456685..54b7dcc 100644 --- a/church-eval.ipkg +++ b/church-eval.ipkg @@ -8,11 +8,3 @@ depends = contrib modules = Thinning - , Total.Encoded.Util - , Total.LogRel - , Total.NormalForm - , Total.Pretty - , Total.Reduction - , Total.Syntax - , Total.Term - , Total.Term.CoDebruijn diff --git a/src/Term.idr b/src/Term.idr new file mode 100644 index 0000000..e9f6b1f --- /dev/null +++ b/src/Term.idr @@ -0,0 +1,341 @@ +module Term + +import Control.Order +import Control.Relation +import Syntax.PreorderReasoning +import Syntax.PreorderReasoning.Generic + +import public Data.SnocList.Quantifiers +import public Thinned +import public Type + +%prefix_record_projections off + +-- Definition ------------------------------------------------------------------ + +||| System T terms that use all the variables in scope. +public export +data FullTerm : Ty -> SnocList Ty -> Type where + Var : FullTerm ty [<ty] + Const : FullTerm ty' ctx -> FullTerm (ty ~> ty') ctx + Abs : FullTerm ty' (ctx :< ty) -> FullTerm (ty ~> ty') ctx + App : + {ty : Ty} -> + Pair (FullTerm (ty ~> ty')) (FullTerm ty) ctx -> + FullTerm ty' ctx + Zero : FullTerm N [<] + Suc : FullTerm N ctx -> FullTerm N ctx + Rec : + Pair (FullTerm N) (Pair (FullTerm ty) (FullTerm (ty ~> ty))) ctx -> + FullTerm ty ctx + +%name FullTerm t, u, v + +||| System T terms. +public export +Term : Ty -> SnocList Ty -> Type +Term ty ctx = Thinned (FullTerm ty) ctx + +-- Smart Constructors ---------------------------------------------------------- + +namespace Smart + export + Var : Elem ty ctx -> Term ty ctx + Var i = Var `Over` Point i + + export + Const : Term ty' ctx -> Term (ty ~> ty') ctx + Const t = map Const t + + export + Abs : Term ty' (ctx :< ty) -> Term (ty ~> ty') ctx + Abs (t `Over` Id) = Abs t `Over` Id + Abs (t `Over` Empty) = Const t `Over` Empty + Abs (t `Over` Drop thin) = Const t `Over` thin + Abs (t `Over` Keep thin) = Abs t `Over` thin + + export + App : {ty : Ty} -> Term (ty ~> ty') ctx -> Term ty ctx -> Term ty' ctx + App t u = map App $ MkPair t u + + export + Zero : Term N ctx + Zero = Zero `Over` Empty + + export + Suc : Term N ctx -> Term N ctx + Suc t = map Suc t + + export + Rec : Term N ctx -> Term ty ctx -> Term (ty ~> ty) ctx -> Term ty ctx + Rec t u v = map Rec $ MkPair t (MkPair u v) + + --- Properties + + export + varCong : {0 i, j : Elem ty ctx} -> i = j -> Var i <~> Var j + + export + shiftVar : (i : Elem ty ctx) -> shift (Var i) <~> Var (There i) + + export + constCong : {0 t, u : Term ty' ctx} -> t <~> u -> Const t <~> Const u + + export + absCong : {0 t, u : Term ty' (ctx :< ty)} -> t <~> u -> Abs t <~> Abs u + + export + appCong : + {0 t1, u1 : Term (ty ~> ty') ctx} -> + {0 t2, u2 : Term ty ctx} -> + t1 <~> u1 -> + t2 <~> u2 -> + App t1 t2 <~> App u1 u2 + + export + sucCong : {0 t, u : Term N ctx} -> t <~> u -> Suc t <~> Suc u + + export + recCong : + {0 t1, u1 : Term N ctx} -> + {0 t2, u2 : Term ty ctx} -> + {0 t3, u3 : Term (ty ~> ty) ctx} -> + t1 <~> u1 -> + t2 <~> u2 -> + t3 <~> u3 -> + Rec t1 t2 t3 <~> Rec u1 u2 u3 + recCong prf1 prf2 prf3 = + mapCong Rec + ?recCong_rhs_1 + +-- Substitution Definition ----------------------------------------------------- + +||| Substitution of variables for terms. +public export +data Subst : (ctx, ctx' : SnocList Ty) -> Type where + Base : ctx `Thins` ctx' -> Subst ctx ctx' + (:<) : Subst ctx ctx' -> Term ty ctx' -> Subst (ctx :< ty) ctx' + +%name Subst sub + +export +index : Subst ctx ctx' -> Elem ty ctx -> Term ty ctx' +index (Base thin) i = Var (index thin i) +index (sub :< v) Here = v +index (sub :< v) (There i) = index sub i + +||| Equivalence relation on substitutions. +public export +record (<~>) (sub1, sub2 : Subst ctx ctx') where + constructor MkEquivalence + equiv : forall ty. (i : Elem ty ctx) -> index sub1 i <~> index sub2 i + +%name Term.(<~>) prf + +--- Properties + +export +irrelevantEquiv : + {0 sub1, sub2 : Subst ctx ctx'} -> + (0 prf : sub1 <~> sub2) -> + sub1 <~> sub2 +irrelevantEquiv prf = MkEquivalence (\i => irrelevantEquiv $ prf.equiv i) + +export +Reflexive (Subst ctx ctx') (<~>) where + reflexive = MkEquivalence (\i => reflexive) + +export +Symmetric (Subst ctx ctx') (<~>) where + symmetric prf = MkEquivalence (\i => symmetric $ prf.equiv i) + +export +Transitive (Subst ctx ctx') (<~>) where + transitive prf1 prf2 = MkEquivalence (\i => transitive (prf1.equiv i) (prf2.equiv i)) + +export +Equivalence (Subst ctx ctx') (<~>) where + +export +Preorder (Subst ctx ctx') (<~>) where + +namespace Subst + export + Base : + {0 thin1, thin2 : ctx `Thins` ctx'} -> + thin1 <~> thin2 -> + Base thin1 <~> Base thin2 + Base prf = MkEquivalence (\i => varCong (prf.equiv i)) + + export + (:<) : + {0 sub1, sub2 : Subst ctx ctx'} -> + {0 t, u : Term ty ctx'} -> + sub1 <~> sub2 -> + t <~> u -> + sub1 :< t <~> sub2 :< u + prf1 :< prf2 = + MkEquivalence (\i => case i of Here => prf2; There i => prf1.equiv i) + +-- Operations ------------------------------------------------------------------ + +||| Shifts a substitution under a binder. +export +shift : Subst ctx ctx' -> Subst ctx (ctx' :< ty) +shift (Base thin) = Base (Drop thin) +shift (sub :< t) = shift sub :< shift t + +||| Lifts a substitution under a binder. +export +lift : Subst ctx ctx' -> Subst (ctx :< ty) (ctx' :< ty) +lift sub = shift sub :< Var Here + +||| Limits the domain of a substitution +export +(.) : Subst ctx' ctx'' -> ctx `Thins` ctx' -> Subst ctx ctx'' +Base thin' . thin = Base (thin' . thin) +(sub :< t) . Id = sub :< t +(sub :< t) . Empty = Base Empty +(sub :< t) . Drop thin = sub . thin +(sub :< t) . Keep thin = sub . thin :< t + +--- Properties + +export +shiftIndex : + (sub : Subst ctx ctx') -> + (i : Elem ty ctx) -> + shift (index sub i) <~> index (shift sub) i +shiftIndex (Base thin) i = CalcWith $ + |~ shift (Var $ index thin i) + <~ Var (There $ index thin i) ...(shiftVar (index thin i)) + <~ Var (index (Drop thin) i) ..<(varCong $ indexDrop thin i) +shiftIndex (sub :< v) Here = reflexive +shiftIndex (sub :< v) (There i) = shiftIndex sub i + +export +shiftCong : {0 sub1, sub2 : Subst ctx' ctx''} -> sub1 <~> sub2 -> shift sub1 <~> shift sub2 +shiftCong prf = irrelevantEquiv $ MkEquivalence (\i => + CalcWith $ + |~ index (shift sub1) i + <~ shift (index sub1 i) ..<(shiftIndex sub1 i) + <~ shift (index sub2 i) ...(shiftCong (prf.equiv i)) + <~ index (shift sub2) i ...(shiftIndex sub2 i)) + +export +liftCong : {0 sub1, sub2 : Subst ctx' ctx''} -> sub1 <~> sub2 -> lift sub1 <~> lift sub2 +liftCong prf = shiftCong prf :< (irrelevantEquiv $ reflexive) + +export +indexHomo : + (sub : Subst ctx' ctx'') -> + (thin : ctx `Thins` ctx') -> + (i : Elem ty ctx) -> + index sub (index thin i) = index (sub . thin) i +indexHomo (Base thin') thin i = cong Var (indexHomo thin' thin i) +indexHomo (sub :< v) Id i = cong (index (sub :< v)) $ indexId i +indexHomo (sub :< v) (Drop thin) i = Calc $ + |~ index (sub :< v) (index (Drop thin) i) + ~~ index (sub :< v) (There (index thin i)) ...(cong (index (sub :< v)) $ indexDrop thin i) + ~~ index sub (index thin i) ...(Refl) + ~~ index (sub . thin) i ...(indexHomo sub thin i) +indexHomo (sub :< v) (Keep thin) Here = Calc $ + |~ index (sub :< v) (index (Keep thin) Here) + ~~ index (sub :< v) Here ...(cong (index (sub :< v)) $ indexKeepHere thin) + ~~ v ...(Refl) +indexHomo (sub :< v) (Keep thin) (There i) = Calc $ + |~ index (sub :< v) (index (Keep thin) (There i)) + ~~ index (sub :< v) (There (index thin i)) ...(cong (index (sub :< v)) $ indexKeepThere thin i) + ~~ index sub (index thin i) ...(Refl) + ~~ index (sub . thin) i ...(indexHomo sub thin i) + +export +compCong : + {0 sub1, sub2 : Subst ctx' ctx''} -> + {0 thin1, thin2 : ctx `Thins` ctx'} -> + sub1 <~> sub2 -> + thin1 <~> thin2 -> + (sub1 . thin1) <~> (sub2 . thin2) +compCong prf1 prf2 = irrelevantEquiv $ MkEquivalence (\i => CalcWith $ + |~ index (sub1 . thin1) i + ~~ index sub1 (index thin1 i) ..<(indexHomo sub1 thin1 i) + <~ index sub2 (index thin1 i) ...(prf1.equiv (index thin1 i)) + ~~ index sub2 (index thin2 i) ...(cong (index sub2) $ prf2.equiv i) + ~~ index (sub2 . thin2) i ...(indexHomo sub2 thin2 i)) + +-- Substitution Operation ------------------------------------------------------ + +fullSubst : FullTerm ty ctx -> Subst ctx ctx' -> Term ty ctx' +fullSubst Var sub = index sub Here +fullSubst (Const t) sub = Const (fullSubst t sub) +fullSubst (Abs t) sub = Abs (fullSubst t $ lift sub) +fullSubst (App (MakePair (t `Over` thin1) (u `Over` thin2) _)) sub = + App (fullSubst t $ sub . thin1) (fullSubst u $ sub . thin2) +fullSubst Zero sub = Zero +fullSubst (Suc t) sub = Suc (fullSubst t sub) +fullSubst + (Rec (MakePair + (t `Over` thin1) + (MakePair (u `Over` thin2) (v `Over` thin3) _ `Over` thin') + _)) + sub = + let sub' = sub . thin' in + Rec + (fullSubst t $ sub . thin1) + (fullSubst u $ sub' . thin2) + (fullSubst v $ sub' . thin3) + +||| Applies a substitution to a term. +export +subst : Term ty ctx -> Subst ctx ctx' -> Term ty ctx' +subst (t `Over` thin) sub = fullSubst t (sub . thin) + +--- Properties + +fullSubstCong : + (t : FullTerm ty ctx) -> + {0 sub1, sub2 : Subst ctx ctx'} -> + sub1 <~> sub2 -> + fullSubst t sub1 <~> fullSubst t sub2 +fullSubstCong Var prf = prf.equiv Here +fullSubstCong (Const t) prf = constCong (fullSubstCong t prf) +fullSubstCong (Abs t) prf = absCong (fullSubstCong t $ liftCong prf) +fullSubstCong (App (MakePair (t `Over` thin1) (u `Over` thin2) _)) prf = + appCong + (fullSubstCong t $ compCong prf reflexive) + (fullSubstCong u $ compCong prf reflexive) +fullSubstCong Zero prf = irrelevantEquiv $ reflexive +fullSubstCong (Suc t) prf = sucCong (fullSubstCong t prf) +fullSubstCong + (Rec (MakePair + (t `Over` thin1) + (MakePair (u `Over` thin2) (v `Over` thin3) _ `Over` thin') + _)) + prf = + let prf' = compCong prf reflexive in + recCong + (fullSubstCong t $ compCong prf reflexive) + (fullSubstCong u $ compCong prf' reflexive) + (fullSubstCong v $ compCong prf' reflexive) + +export +substCong : + {0 t, u : Term ty ctx} -> + {0 sub1, sub2 : Subst ctx ctx'} -> + t <~> u -> + sub1 <~> sub2 -> + subst t sub1 <~> subst u sub2 +substCong (UpToThin prf1) prf2 = irrelevantEquiv $ fullSubstCong _ (compCong prf2 prf1) + +export +substBase : + (t : Term ty ctx) -> + (thin : ctx `Thins` ctx') -> + subst t (Base thin) <~> wkn t thin + +export +substHomo : + (t : Term ty ctx) -> + (sub1 : Subst ctx ctx') -> + (sub2 : Subst ctx' ctx'') -> + subst (subst t sub1) sub2 <~> subst t ?d diff --git a/src/Thinned.idr b/src/Thinned.idr new file mode 100644 index 0000000..7f5d2ac --- /dev/null +++ b/src/Thinned.idr @@ -0,0 +1,140 @@ +module Thinned + +import Control.Order +import Control.Relation + +import public Thinning + +%prefix_record_projections off + +-- Definition ------------------------------------------------------------------ + +||| Data embedded in a wider context via a thinning. +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 + +%name Thinned v, u + +||| An equivalence relation on thinned objects. +public export +data (<~>) : Thinned t sx -> Thinned t sx -> Type where + UpToThin : + {0 v : t sx} -> + {0 thin1, thin2 : sx `Thins` sy} -> + thin1 <~> thin2 -> + (<~>) {t} (v `Over` thin1) (v `Over` thin2) + +%name Thinned.(<~>) prf + +export (.supportPrf) : + {0 v, u : Thinned t sx} -> + v <~> u -> + v.support = u.support +(UpToThin prf) .supportPrf = Refl + +export (.valuePrf) : + {0 v, u : Thinned t sx} -> + (e : v <~> u) -> + v.value = (rewrite e.supportPrf in u.value) +(UpToThin prf) .valuePrf = Refl + +export (.thinPrf) : + {0 v, u : Thinned t sx} -> + (e : v <~> u) -> + v.thin <~> (rewrite e.supportPrf in u.thin) +(UpToThin prf) .thinPrf = prf + +--- Properties + +export +irrelevantEquiv : + {0 v, u : Thinned t sx} -> + (0 prf : v <~> u) -> + v <~> u +irrelevantEquiv {v = v `Over` thin1, u = u `Over` thin2} prf = + rewrite prf.supportPrf in + rewrite prf.valuePrf in + UpToThin (rewrite sym prf.supportPrf in irrelevantEquiv prf.thinPrf) + +export +Reflexive (Thinned t sx) (<~>) where + reflexive {x = t `Over` thin} = UpToThin reflexive + +export +Symmetric (Thinned t sx) (<~>) where + symmetric (UpToThin prf) = UpToThin (symmetric prf) + +export +Transitive (Thinned t sx) (<~>) where + transitive (UpToThin prf1) (UpToThin prf2) = UpToThin (transitive prf1 prf2) + +export +Equivalence (Thinned t sx) (<~>) where + +export +Preorder (Thinned t sx) (<~>) where + +-- Operations ------------------------------------------------------------------ + +||| Map the underlying value. +public export +map : (forall sx. t sx -> u sx) -> Thinned t sx -> Thinned u sx +map f (value `Over` thin) = f value `Over` thin + +||| Weaken the surrounding context. +public export +wkn : Thinned t sx -> sx `Thins` sy -> Thinned t sy +wkn (value `Over` thin') thin = value `Over` thin . thin' + +||| Shift the surrounding context. +public export +shift : Thinned t sx -> Thinned t (sx :< x) +shift (value `Over` thin) = value `Over` Drop thin + +--- Properties + +export +mapCong : + {0 t, u : SnocList a -> Type} -> + (0 f : forall sx. t sx -> u sx) -> + {0 v1, v2 : Thinned t sx} -> + v1 <~> v2 -> + map f v1 <~> map f v2 +mapCong f (UpToThin prf) = UpToThin prf + +export +shiftCong : {0 v, u : Thinned t sx} -> v <~> u -> shift v <~> shift u +shiftCong (UpToThin prf) = UpToThin (dropCong prf) + +-- Pairs ----------------------------------------------------------------------- + +||| Product of two values ensuring the whole context is used. +public export +record Pair (t, u : SnocList a -> Type) (sx : SnocList a) where + constructor MakePair + fst : Thinned t sx + snd : Thinned u sx + 0 cover : Covering fst.thin snd.thin + +||| Smart constructor for thinned pairs. +export +MkPair : Thinned t sx -> Thinned u sx -> Thinned (Pair t u) sx +MkPair (v `Over` thin1) (u `Over` thin2) = + let cp = coprod thin1 thin2 in + MakePair (v `Over` cp.thin1') (u `Over` cp.thin2') cp.cover `Over` cp.factor + +--- Properties + +export +mkPairCong : + {0 v1, w1 : Thinned t sx} -> + {0 v2, w2 : Thinned u sx} -> + v1 <~> w1 -> + v2 <~> w2 -> + MkPair v1 v2 <~> MkPair w1 w2 +mkPairCong (UpToThin prf1) (UpToThin prf2) = + ?mkPairCong_rhs_1 diff --git a/src/Thinning.idr b/src/Thinning.idr index d2d65df..1ba5eb0 100644 --- a/src/Thinning.idr +++ b/src/Thinning.idr @@ -1,246 +1,187 @@ +||| A setoid of context thinnings. module Thinning -import Data.Singleton -import Data.SnocList.Elem +import Control.Order +import Control.Relation +import Data.Either +import Data.Nat +import Syntax.PreorderReasoning + +import public Data.SnocList.Elem %prefix_record_projections off +infix 4 <~> + -- Definition ------------------------------------------------------------------ +||| An injective, order-preserving map from one context to another. public export data Thins : SnocList a -> SnocList a -> Type where - Empty : [<] `Thins` [<] - Drop : sx `Thins` sy -> sx `Thins` sy :< z - Keep : - (thin : sx `Thins` sy) -> - sx :< z `Thins` sy :< z + ||| Identity map. + Id : sx `Thins` sx + ||| Empty map. + Empty : [<] `Thins` sx + ||| Skips over an element in the target context. + Drop : sx `Thins` sy -> sx `Thins` sy :< y + ||| Extends both contexts with a new element. + Keep : sx `Thins` sy -> sx :< z `Thins` sy :< z %name Thins thin --- Utility --------------------------------------------------------------------- - -public export -data Len : SnocList a -> Type where - Z : Len [<] - S : Len sx -> Len (sx :< x) - -%name Len k, m, n - -%hint -public export -length : (sx : SnocList a) -> Len sx -length [<] = Z -length (sx :< x) = S (length sx) - -%hint +||| Apply a thinning to an element of the source context. export -lenAppend : Len sx -> Len sy -> Len (sx ++ sy) -lenAppend k Z = k -lenAppend k (S m) = S (lenAppend k m) - -%hint -public 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 -id : (len : Len sx) => sx `Thins` sx -id {len = Z} = Empty -id {len = S k} = Keep id - -public 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 : sx `Thins` sy -> Elem x sx -> Elem x 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) +||| An equivalence relation on thinnings. Two thinnings are equal if they have +||| the same action on elements. public export -(.) : sy `Thins` sz -> sx `Thins` sy -> sx `Thins` sz -Empty . thin1 = thin1 -Drop thin2 . thin1 = Drop (thin2 . thin1) -Keep thin2 . Drop thin1 = Drop (thin2 . thin1) -Keep thin2 . Keep thin1 = Keep (thin2 . thin1) +record (<~>) (thin1, thin2 : sx `Thins` sy) where + constructor MkEquivalence + equiv : forall x. (i : Elem x sx) -> index thin1 i = index thin2 i -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) +%name (<~>) prf --- Commuting Triangles and Coverings ------------------------------------------- +--- Properties -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) +-- Relational -public export -data Overlap = Covers | Partitions +export +irrelevantEquiv : + {0 thin1, thin2 : sx `Thins` sy} -> + (0 prf : thin1 <~> thin2) -> + thin1 <~> thin2 +irrelevantEquiv prf = MkEquivalence (\i => irrelevantEq $ prf.equiv i) -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) +export +Reflexive (sx `Thins` sy) (<~>) where + reflexive = MkEquivalence (\i => Refl) -public export -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' +export +Symmetric (sx `Thins` sy) (<~>) where + symmetric prf = MkEquivalence (\i => sym $ prf.equiv i) export -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) +Transitive (sx `Thins` sy) (<~>) where + transitive prf1 prf2 = MkEquivalence (\i => trans (prf1.equiv i) (prf2.equiv i)) --- Splitting off Contexts ------------------------------------------------------ +export +Equivalence (sx `Thins` sy) (<~>) where -public export -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) +export +Preorder (sx `Thins` sy) (<~>) where -public export -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) +export +dropCong : thin1 <~> thin2 -> Drop thin1 <~> Drop thin2 +dropCong prf = MkEquivalence (\i => cong There $ prf.equiv i) --- Thinned Things -------------------------------------------------------------- +export +keepCong : thin1 <~> thin2 -> Keep thin1 <~> Keep thin2 +keepCong prf = MkEquivalence + (\i => + case i of + Here => Refl + There i => cong There $ prf.equiv i) -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 +-- Indexing -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 +export +indexId : (i : Elem x sx) -> index Id i = i +indexId i = Refl -public export -Pair : (T, U : SnocList a -> Type) -> SnocList a -> Type -Pair = OverlapPair Covers +export +indexDrop : + (thin : sx `Thins` sy) -> + (i : Elem x sx) -> + index (Drop thin) i = There (index thin i) +indexDrop thin i = Refl -public export -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 +export +indexKeepHere : (thin : sx `Thins` sy) -> index (Keep thin) Here = Here +indexKeepHere thin = Refl -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 thin i = Refl -public export -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 +-- Other -public export -map : (forall ctx. t ctx -> u ctx) -> Thinned t ctx -> Thinned u ctx -map f (value `Over` thin) = f value `Over` thin +thinToEmpty : sx `Thins` [<] -> sx = [<] +thinToEmpty Id = Refl +thinToEmpty Empty = Refl -public export -drop : Thinned t sx -> Thinned t (sx :< x) -drop (value `Over` thin) = value `Over` Drop thin +0 thinLen : sx `Thins` sy -> length sx `LTE` length sy +thinLen Id = reflexive +thinLen Empty = LTEZero +thinLen (Drop thin) = lteSuccRight (thinLen thin) +thinLen (Keep thin) = LTESucc (thinLen thin) -public export -wkn : Thinned t sx -> sx `Thins` sy -> Thinned t sy -wkn (value `Over` thin) thin' = value `Over` thin' . thin +idUnique' : (thin : sx `Thins` sx) -> (i : Elem x sx) -> index thin i = i +idUnique' Id i = Refl +idUnique' (Drop thin) i = void $ LTEImpliesNotGT (thinLen thin) reflexive +idUnique' (Keep thin) Here = Refl +idUnique' (Keep thin) (There i) = cong There $ idUnique' thin i --- Properties ------------------------------------------------------------------ +export +idUnique : (thin1, thin2 : sx `Thins` sx) -> thin1 <~> thin2 +idUnique thin1 thin2 = + MkEquivalence + (\i => trans (idUnique' thin1 i) (sym $ idUnique' thin2 i)) export -lenUnique : (k, m : Len sx) -> k = m -lenUnique Z Z = Refl -lenUnique (S k) (S m) = cong S (lenUnique k m) +emptyUnique : (thin1, thin2 : [<] `Thins` sx) -> thin1 <~> thin2 +emptyUnique thin1 thin2 = MkEquivalence (\i => absurd i) +-- Smart Constructors ---------------------------------------------------------- + +||| Point map. The representable thinning of an element. export -emptyUnique : (thin1, thin2 : [<] `Thins` sx) -> thin1 = thin2 -emptyUnique Empty Empty = Refl -emptyUnique (Drop thin1) (Drop thin2) = cong Drop (emptyUnique thin1 thin2) +Point : Elem x sx -> [<x] `Thins` sx +Point Here = Keep Empty +Point (There i) = Drop (Point i) 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) +indexPoint : (i : Elem x sx) -> index (Point i) Here = i +indexPoint Here = Refl +indexPoint (There i) = cong There $ indexPoint i 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) +pointCong : {0 i, j : Elem x sx} -> i = j -> Point i <~> Point j +pointCong prf = MkEquivalence (\Here => cong (\i => index (Point i) Here) prf) export -identitySquared : (len : Len sx) -> id @{len} . id @{len} = id @{len} -identitySquared Z = Refl -identitySquared (S k) = cong Keep (identitySquared k) +dropPoint : (i : Elem x sx) -> Drop (Point i) <~> Point (There i) +dropPoint i = MkEquivalence (\Here => Refl) export -assoc : - (thin3 : sz `Thins` sw) -> - (thin2 : sy `Thins` sz) -> - (thin1 : sx `Thins` sy) -> - thin3 . (thin2 . thin1) = (thin3 . thin2) . thin1 -assoc Empty thin2 thin1 = Refl -assoc (Drop thin3) thin2 thin1 = cong Drop (assoc thin3 thin2 thin1) -assoc (Keep thin3) (Drop thin2) thin1 = cong Drop (assoc thin3 thin2 thin1) -assoc (Keep thin3) (Keep thin2) (Drop thin1) = cong Drop (assoc thin3 thin2 thin1) -assoc (Keep thin3) (Keep thin2) (Keep thin1) = cong Keep (assoc thin3 thin2 thin1) +keepEmptyIsPoint : Keep Empty <~> Point Here +keepEmptyIsPoint = MkEquivalence (\Here => Refl) +-- Operations ------------------------------------------------------------------ + +||| Composition of two thinnings. 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) +(.) : sy `Thins` sz -> sx `Thins` sy -> sx `Thins` sz +Id . thin1 = thin1 +Empty . Id = Empty +Empty . Empty = Empty +Drop thin2 . Id = Drop thin2 +Drop thin2 . Empty = Empty +Drop thin2 . Drop thin1 = Drop (thin2 . Drop thin1) +Drop thin2 . Keep thin1 = Drop (thin2 . Keep thin1) +Keep thin2 . Id = Keep thin2 +Keep thin2 . Empty = Empty +Keep thin2 . Drop thin1 = Drop (thin2 . thin1) +Keep thin2 . Keep thin1 = Keep (thin2 . thin1) + +--- Properties export indexHomo : @@ -248,69 +189,224 @@ indexHomo : (thin1 : sx `Thins` sy) -> (i : Elem x sx) -> index thin2 (index thin1 i) = index (thin2 . thin1) i +indexHomo Id thin1 i = Refl +indexHomo Empty Id i impossible 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 (Drop thin2) Id i = Refl +indexHomo (Drop thin2) (Drop thin1) i = cong There $ indexHomo thin2 (Drop thin1) i +indexHomo (Drop thin2) (Keep thin1) i = cong There $ indexHomo thin2 (Keep thin1) i +indexHomo (Keep thin2) Id i = Refl +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) +indexHomo (Keep thin2) (Keep thin1) (There i) = cong There $ indexHomo thin2 thin1 i --- Objects +-- Categorical export -indexPoint : (len : Len sx) => (i : Elem x sx) -> index (point @{len} i) Here = i -indexPoint Here = Refl -indexPoint (There i) = cong There (indexPoint i) +identityLeft : (thin : sx `Thins` sy) -> Id . thin <~> thin +identityLeft thin = reflexive export -MkTriangle : - (thin2 : sy `Thins` sz) -> - (thin1 : sx `Thins` sy) -> - Triangle thin2 thin1 (thin2 . thin1) -MkTriangle Empty thin1 = EmptyAny -MkTriangle (Drop thin2) thin1 = DropAny (MkTriangle thin2 thin1) -MkTriangle (Keep thin2) (Drop thin1) = KeepDrop (MkTriangle thin2 thin1) -MkTriangle (Keep thin2) (Keep thin1) = KeepKeep (MkTriangle thin2 thin1) +identityRight : (thin : sx `Thins` sy) -> thin . Id <~> thin +identityRight Id = reflexive +identityRight Empty = reflexive +identityRight (Drop thin) = reflexive +identityRight (Keep thin) = reflexive export -triangleCorrect : Triangle thin2 thin1 thin -> thin2 . thin1 = thin -triangleCorrect EmptyAny = Refl -triangleCorrect (DropAny t) = cong Drop (triangleCorrect t) -triangleCorrect (KeepDrop t) = cong Drop (triangleCorrect t) -triangleCorrect (KeepKeep t) = cong Keep (triangleCorrect t) +assoc : + (thin3 : sz `Thins` sw) -> + (thin2 : sy `Thins` sz) -> + (thin1 : sx `Thins` sy) -> + thin3 . (thin2 . thin1) <~> (thin3 . thin2) . thin1 +assoc thin3 thin2 thin1 = MkEquivalence (\i => Calc $ + |~ index (thin3 . (thin2 . thin1)) i + ~~ index thin3 (index (thin2 . thin1) i) ..<(indexHomo thin3 (thin2 . thin1) i) + ~~ index thin3 (index thin2 (index thin1 i)) ..<(cong (index thin3) $ indexHomo thin2 thin1 i) + ~~ index (thin3 . thin2) (index thin1 i) ...(indexHomo thin3 thin2 (index thin1 i)) + ~~ index ((thin3 . thin2) . thin1) i ...(indexHomo (thin3 . thin2) thin1) i) -export -coprodEta : - {thin1 : sx `Thins` sz} -> - {thin2 : sy `Thins` sz} -> - (thin : sz `Thins` sw) -> - (cover : Covering Covers thin1 thin2) -> - coprod (thin . thin1) (thin . thin2) = - MkCoprod (MkTriangle thin thin1) (MkTriangle thin thin2) cover -coprodEta Empty EmptyEmpty = Refl -coprodEta (Drop thin) cover = rewrite coprodEta thin cover in Refl -coprodEta (Keep thin) (DropKeep cover) = rewrite coprodEta thin cover in Refl -coprodEta (Keep thin) (KeepDrop cover) = rewrite coprodEta thin cover in Refl -coprodEta (Keep thin) (KeepKeep cover) = rewrite coprodEta thin cover in Refl +-- Other export -dropIsWkn : (len : Len sx) => (v : Thinned t sx) -> drop {x} v = wkn v (Drop $ id @{len}) -dropIsWkn (value `Over` thin) = sym $ cong ((value `Over`) . Drop) $ identityLeft thin +dropLeft : + (thin2 : sy `Thins` sz) -> + (thin1 : sx `Thins` sy) -> + Drop thin2 . thin1 <~> Drop (thin2 . thin1) +dropLeft thin2 Id = symmetric $ dropCong $ identityRight thin2 +dropLeft thin2 Empty = emptyUnique Empty (Drop (thin2 . Empty)) +dropLeft thin2 (Drop thin1) = reflexive +dropLeft thin2 (Keep thin1) = reflexive export -wknId : (len : Len sx) => (v : Thinned t sx) -> wkn v (id @{len}) = v -wknId (value `Over` thin) = cong (value `Over`) $ identityLeft thin +keepDrop : + (thin2 : sy `Thins` sz) -> + (thin1 : sx `Thins` sy) -> + Keep thin2 . Drop thin1 <~> Drop (thin2 . thin1) +keepDrop thin2 thin1 = reflexive export -wknHomo : - (v : Thinned t sx) -> +keepHomo : (thin2 : sy `Thins` sz) -> (thin1 : sx `Thins` sy) -> - wkn (wkn v thin1) thin2 = wkn v (thin2 . thin1) -wknHomo (value `Over` thin) thin2 thin1 = cong (value `Over`) $ assoc thin2 thin1 thin + Keep thin2 . Keep thin1 <~> Keep (thin2 . thin1) +keepHomo thin2 thin1 = reflexive + +export +pointRight : + (thin : sx `Thins` sy) -> + (i : Elem x sx) -> + thin . Point i <~> Point (index thin i) +pointRight Id i = reflexive +pointRight (Drop thin) i = transitive (dropLeft thin (Point i)) (dropCong (pointRight thin i)) +pointRight (Keep thin) Here = keepCong (emptyUnique (thin . Empty) Empty) +pointRight (Keep thin) (There i) = dropCong (pointRight thin i) + +-- Coverings and Coproducts ---------------------------------------------------- -%hint +||| Proof that the thinnings are jointly surjective. +public export +record Covering (thin1 : sx `Thins` sz) (thin2 : sy `Thins` sz) where + constructor MkCovering + covers : + forall x. + (i : Elem x sz) -> + Either (j ** index thin1 j = i) (k ** index thin2 k = i) + +||| Unique thinning that factors into a covering. +public export +record Coproduct (thin1 : sx `Thins` sz) (thin2 : sy `Thins` sz) where + constructor MkCoproduct + {0 sw : SnocList _} + {thin1' : sx `Thins` sw} + {thin2' : sy `Thins` sw} + {factor : sw `Thins` sz} + 0 left : factor . thin1' <~> thin1 + 0 right : factor . thin2' <~> thin2 + 0 cover : Covering thin1' thin2' + +%name Covering cover +%name Coproduct cp + +--- Properties + +-- Coverings + +coverSym : Covering thin1 thin2 -> Covering thin2 thin1 +coverSym cover = MkCovering (\i => mirror $ cover.covers i) + +coverId : (0 thin : sx `Thins` sy) -> Covering Id thin +coverId thin = MkCovering (\i => Left (i ** Refl)) + +coverDropKeep : Covering thin1 thin2 -> Covering (Drop thin1) (Keep thin2) +coverDropKeep cover = MkCovering + (\i => case i of + Here => Right (Here ** Refl) + There i => case cover.covers i of + Left (j ** prf) => Left (j ** cong There prf) + Right (k ** prf) => Right (There k ** cong There prf)) + +coverKeepDrop : Covering thin1 thin2 -> Covering (Keep thin1) (Drop thin2) +coverKeepDrop cp = coverSym $ coverDropKeep $ coverSym cp + +coverKeepKeep : Covering thin1 thin2 -> Covering (Keep thin1) (Keep thin2) +coverKeepKeep cover = MkCovering + (\i => case i of + Here => Left (Here ** Refl) + There i => case cover.covers i of + Left (j ** prf) => Left (There j ** cong There prf) + Right (k ** prf) => Right (There k ** cong There prf)) + +-- Coproducts + +coprodSym : Coproduct thin1 thin2 -> Coproduct thin2 thin1 +coprodSym cp = MkCoproduct cp.right cp.left (coverSym cp.cover) + +coprodId : (thin : sx `Thins` sy) -> Coproduct Id thin +coprodId thin = + MkCoproduct + { thin1' = Id + , thin2' = thin + , factor = Id + , left = reflexive + , right = reflexive + , cover = coverId thin + } + +coprodEmpty : (thin : sx `Thins` sy) -> Coproduct Empty thin +coprodEmpty thin = + MkCoproduct + { thin1' = Empty + , thin2' = Id + , factor = thin + , left = emptyUnique (thin . Empty) Empty + , right = identityRight thin + , cover = coverSym $ coverId Empty + } + +||| Finds the coproduct of two thinnings. export -retractSingleton : Singleton sy -> sx `Thins` sy -> Singleton sx -retractSingleton s Empty = s -retractSingleton (Val (sy :< z)) (Drop thin) = retractSingleton (Val sy) thin -retractSingleton (Val (sy :< z)) (Keep thin) = pure (:< z) <*> retractSingleton (Val sy) thin +coprod : + (thin1 : sx `Thins` sz) -> + (thin2 : sy `Thins` sz) -> + Coproduct thin1 thin2 +coprod Id thin2 = coprodId thin2 +coprod Empty thin2 = coprodEmpty thin2 +coprod (Drop thin1) Id = coprodSym $ coprodId (Drop thin1) +coprod (Drop thin1) Empty = coprodSym $ coprodEmpty (Drop thin1) +coprod (Drop thin1) (Drop thin2) = + let cp = coprod thin1 thin2 in + MkCoproduct + { thin1' = cp.thin1' + , thin2' = cp.thin2' + , factor = Drop cp.factor + , left = transitive (dropLeft cp.factor cp.thin1') (dropCong cp.left) + , right = transitive (dropLeft cp.factor cp.thin2') (dropCong cp.right) + , cover = cp.cover + } +coprod (Drop thin1) (Keep thin2) = + let cp = coprod thin1 thin2 in + MkCoproduct + { thin1' = Drop cp.thin1' + , thin2' = Keep cp.thin2' + , factor = Keep cp.factor + , left = transitive (keepDrop cp.factor cp.thin1') (dropCong cp.left) + , right = transitive (keepHomo cp.factor cp.thin2') (keepCong cp.right) + , cover = coverDropKeep cp.cover + } +coprod (Keep thin1) Id = coprodSym $ coprodId (Keep thin1) +coprod (Keep thin1) Empty = coprodSym $ coprodEmpty (Keep thin1) +coprod (Keep thin1) (Drop thin2) = + let cp = coprod thin1 thin2 in + MkCoproduct + { thin1' = Keep cp.thin1' + , thin2' = Drop cp.thin2' + , factor = Keep cp.factor + , left = transitive (keepHomo cp.factor cp.thin1') (keepCong cp.left) + , right = transitive (keepDrop cp.factor cp.thin2') (dropCong cp.right) + , cover = coverKeepDrop cp.cover + } +coprod (Keep thin1) (Keep thin2) = + let cp = coprod thin1 thin2 in + MkCoproduct + { thin1' = Keep cp.thin1' + , thin2' = Keep cp.thin2' + , factor = Keep cp.factor + , left = transitive (keepHomo cp.factor cp.thin1') (keepCong cp.left) + , right = transitive (keepHomo cp.factor cp.thin2') (keepCong cp.right) + , cover = coverKeepKeep cp.cover + } + +-- Coproduct Equivalence ------------------------------------------------------- + +namespace Coproduct + public export + data (<~>) : + {0 thin1 : sx `Thins` sa} -> + {0 thin2 : sy `Thins` sa} -> + {0 thin3 : sz `Thins` sa} -> + {0 thin4 : sw `Thins` sa} -> + Coproduct thin1 thin2 -> + Coproduct thin3 thin4 -> + Type + where diff --git a/src/Total/Encoded/Util.idr b/src/Total/Encoded/Util.idr deleted file mode 100644 index f56d1bc..0000000 --- a/src/Total/Encoded/Util.idr +++ /dev/null @@ -1,444 +0,0 @@ -module Total.Encoded.Util - -import public Data.Fin -import public Data.List1 -import public Data.List.Elem -import public Data.List.Quantifiers -import public Total.Syntax - -%prefix_record_projections off - -namespace Bool - export - B : Ty - B = N - - export - true : FullTerm B [<] - true = zero - - export - false : FullTerm B [<] - false = suc zero - - export - if' : FullTerm (B ~> ty ~> ty ~> ty) [<] - if' = abs' (S $ S $ S Z) (\b, t, f => rec b t (abs $ drop f)) - -namespace Arb - export - arb : {ty : Ty} -> FullTerm ty [<] - arb {ty = N} = zero - arb {ty = ty ~> ty'} = abs (lift arb) - -namespace Union - export - (<+>) : Ty -> Ty -> Ty - N <+> N = N - N <+> (u ~> u') = u ~> u' - (t ~> t') <+> N = t ~> t' - (t ~> t') <+> (u ~> u') = (t <+> u) ~> (t' <+> u') - - export - swap : {t, u : Ty} -> FullTerm ((t <+> u) ~> (u <+> t)) [<] - swap {t = N, u = N} = id - swap {t = N, u = u ~> u'} = id - swap {t = t ~> t', u = N} = id - swap {t = t ~> t', u = u ~> u'} = abs' (S Z) (\f => drop swap . f . drop swap) - - export - injL : {t, u : Ty} -> FullTerm (t ~> (t <+> u)) [<] - export - injR : {t, u : Ty} -> FullTerm (u ~> (t <+> u)) [<] - export - prjL : {t, u : Ty} -> FullTerm ((t <+> u) ~> t) [<] - export - prjR : {t, u : Ty} -> FullTerm ((t <+> u) ~> u) [<] - - injL {t = N, u = N} = id - injL {t = N, u = u ~> u'} = abs' (S $ S Z) (\n, _ => app (lift (prjR . injL)) n) - injL {t = t ~> t', u = N} = id - injL {t = t ~> t', u = u ~> u'} = abs' (S Z) (\f => drop injL . f . drop prjL) - - injR = swap . injL - - prjL {t = N, u = N} = id - prjL {t = N, u = u ~> u'} = abs' (S Z) (\f => app (drop (prjL . injR) . f) (drop arb)) - prjL {t = t ~> t', u = N} = id - prjL {t = t ~> t', u = u ~> u'} = abs' (S Z) (\f => drop prjL . f . drop injL) - - prjR = prjL . swap - -namespace Unit - export - Unit : Ty - Unit = N - -namespace Pair - export - (*) : Ty -> Ty -> Ty - t * u = B ~> (t <+> u) - - export - pair : {t, u : Ty} -> FullTerm (t ~> u ~> (t * u)) [<] - pair = abs' (S $ S $ S Z) - (\fst, snd, b => app' (lift if') [<b, app (lift injL) fst, app (lift injR) snd]) - - export - fst : {t, u : Ty} -> FullTerm ((t * u) ~> t) [<] - fst = abs' (S Z) (\p => app (drop prjL . p) (drop true)) - - export - snd : {t, u : Ty} -> FullTerm ((t * u) ~> u) [<] - snd = abs' (S Z) (\p => app (drop prjR . p) (drop false)) - - export - mapSnd : {t, u, v : Ty} -> FullTerm ((u ~> v) ~> (t * u) ~> (t * v)) [<] - mapSnd = abs' (S $ S Z) (\f, p => app' (lift pair) [<app (lift fst) p , app (f . lift snd) p]) - - export - Product : SnocList Ty -> Ty - Product = foldl (*) Unit - - export - pair' : {tys : SnocList Ty} -> FullTerm (tys ~>* Product tys) [<] - pair' {tys = [<]} = arb - pair' {tys = tys :< ty} = abs' (S $ S Z) (\p, t => app' (lift pair) [<p, t]) .* pair' - - export - project : {tys : SnocList Ty} -> Elem ty tys -> FullTerm (Product tys ~> ty) [<] - project {tys = tys :< ty} Here = snd - project {tys = tys :< ty} (There i) = project i . fst - - export - mapProd : - {ctx, tys, tys' : SnocList Ty} -> - {auto 0 prf : SnocList.length tys = SnocList.length tys'} -> - All (flip FullTerm ctx) (zipWith (~>) tys tys') -> - FullTerm (Product tys ~> Product tys') ctx - mapProd {tys = [<], tys' = [<]} [<] = lift id - mapProd {tys = tys :< ty, tys' = tys' :< ty', prf} (fs :< f) = - abs' (S Z) - (\p => - app' (lift pair) - [<app (drop (mapProd fs {prf = injective prf}) . lift fst) p - , app (drop f . lift snd) p - ]) - - replicate : Nat -> a -> SnocList a - replicate 0 x = [<] - replicate (S n) x = replicate n x :< x - - replicateLen : (n : Nat) -> SnocList.length (replicate n x) = n - replicateLen 0 = Refl - replicateLen (S k) = cong S (replicateLen k) - - export - Vect : Nat -> Ty -> Ty - Vect n ty = Product (replicate n ty) - - zipReplicate : - {0 f : a -> b -> c} -> - {0 p : c -> Type} -> - {n : Nat} -> - p (f x y) -> - SnocList.Quantifiers.All.All p (zipWith f (replicate n x) (replicate n y)) - zipReplicate {n = 0} z = [<] - zipReplicate {n = S k} z = zipReplicate z :< z - - export - mapVect : - {n : Nat} -> - {ty, ty' : Ty} -> - FullTerm ((ty ~> ty') ~> Vect n ty ~> Vect n ty') [<] - mapVect = - abs' (S Z) - (\f => mapProd {prf = trans (replicateLen n) (sym $ replicateLen n)} $ zipReplicate f) - - export - nil : {ty : Ty} -> FullTerm (Vect 0 ty) [<] - nil = arb - - export - cons : {n : Nat} -> {ty : Ty} -> FullTerm (ty ~> Vect n ty ~> Vect (S n) ty) [<] - cons = abs' (S $ S Z) (\t, ts => app' (lift pair) [<ts, t]) - - export - head : {n : Nat} -> {ty : Ty} -> FullTerm (Vect (S n) ty ~> ty) [<] - head = snd - - export - tail : {n : Nat} -> {ty : Ty} -> FullTerm (Vect (S n) ty ~> Vect n ty) [<] - tail = fst - - export - index : {n : Nat} -> {ty : Ty} -> (i : Fin n) -> FullTerm (Vect n ty ~> ty) [<] - index FZ = head - index (FS i) = index i . tail - - export - enumerate : (n : Nat) -> FullTerm (Vect n N) [<] - enumerate 0 = arb - enumerate (S k) = app' pair [<app' mapVect [<abs' (S Z) suc, enumerate k], zero] - -namespace Sum - export - (+) : Ty -> Ty -> Ty - t + u = B * (t <+> u) - - export - left : {t, u : Ty} -> FullTerm (t ~> (t + u)) [<] - left = abs' (S Z) (\e => app' (drop pair) [<drop true, app (drop injL) e]) - - export - right : {t, u : Ty} -> FullTerm (u ~> (t + u)) [<] - right = abs' (S Z) (\e => app' (drop pair) [<drop false, app (drop injR) e]) - - export - case' : {t, u, ty : Ty} -> FullTerm ((t + u) ~> (t ~> ty) ~> (u ~> ty) ~> ty) [<] - case' = abs' (S $ S $ S Z) - (\s, f, g => - app' (lift if') - [<app (lift fst) s - , app (f . lift (prjL . snd)) s - , app (g . lift (prjR . snd)) s]) - - export - either : {t, u, ty : Ty} -> FullTerm ((t ~> ty) ~> (u ~> ty) ~> (t + u) ~> ty) [<] - either = abs' (S $ S $ S Z) (\f, g, s => app' (lift case') [<s, f, g]) - - Sum' : Ty -> List Ty -> Ty - Sum' ty [] = ty - Sum' ty (ty' :: tys) = ty + Sum' ty' tys - - export - Sum : List1 Ty -> Ty - Sum (ty ::: tys) = Sum' ty tys - - put' : - {ty, ty' : Ty} -> - {tys : List Ty} -> - (i : Elem ty (ty' :: tys)) -> - FullTerm (ty ~> Sum' ty' tys) [<] - put' {tys = []} Here = id - put' {tys = _ :: _} Here = left - put' {tys = _ :: _} (There i) = right . put' i - - export - put : {tys : List1 Ty} -> {ty : Ty} -> (i : Elem ty (forget tys)) -> FullTerm (ty ~> Sum tys) [<] - put {tys = _ ::: _} i = put' i - - any' : - {ctx : SnocList Ty} -> - {ty, ty' : Ty} -> - {tys : List Ty} -> - All (flip FullTerm ctx . (~> ty)) (ty' :: tys) -> - FullTerm (Sum' ty' tys ~> ty) ctx - any' (t :: []) = t - any' (t :: u :: ts) = app' (lift either) [<t, any' (u :: ts)] - - export - any : - {ctx : SnocList Ty} -> - {tys : List1 Ty} -> - {ty : Ty} -> - All (flip FullTerm ctx . (~> ty)) (forget tys) -> - FullTerm (Sum tys ~> ty) ctx - any {tys = _ ::: _} = any' - -namespace Nat - export - isZero : FullTerm (N ~> B) [<] - isZero = abs' (S Z) (\m => rec m (drop true) (abs (lift false))) - - export - add : FullTerm (N ~> N ~> N) [<] - add = abs' (S $ S Z) (\m, n => rec m n (abs' (S Z) suc)) - - export - sum : {n : Nat} -> FullTerm (Vect n N ~> N) [<] - sum {n = 0} = abs zero - sum {n = S k} = abs' (S Z) - (\ns => app' (lift add) [<app (lift head) ns, app (lift (sum . tail)) ns]) - - export - pred : FullTerm (N ~> N) [<] - pred = abs' (S Z) - (\m => - app' (lift case') - [<rec m - (lift $ app left (arb {ty = Unit})) - (app' (lift either) - [<abs (lift $ app right zero) - , abs' (S Z) (\n => app (lift right) (suc n)) - ]) - , abs zero - , drop id - ]) - - export - sub : FullTerm (N ~> N ~> N) [<] - sub = abs' (S $ S Z) (\m, n => rec n m (lift pred)) - - export - le : FullTerm (N ~> N ~> B) [<] - le = abs' (S Z) (\m => lift isZero . app (lift sub) m) - - export - lt : FullTerm (N ~> N ~> B) [<] - lt = abs' (S Z) (\m => app (lift le) (suc m)) - - export - cond : - {ctx : SnocList Ty} -> - {ty : Ty} -> - List (FullTerm N ctx, FullTerm (N ~> ty) ctx) -> - FullTerm (N ~> ty) ctx - cond [] = lift arb - cond ((n, v) :: xs) = - abs' (S Z) - (\t => - app' (lift if') - [<app' (lift le) [<t, drop n] - , app (drop v) t - , app (drop $ cond xs) (app' (lift sub) [<t, drop n])]) - -namespace Data - public export - Shape : Type - Shape = (Ty, Nat) - - public export - Container : Type - Container = List1 Shape - - public export - fillShape : Shape -> Ty -> Ty - fillShape (shape, n) ty = shape * Vect n ty - - public export - fill : Container -> Ty -> Ty - fill c ty = Sum (map (flip fillShape ty) c) - - export - fix : Container -> Ty - fix c = Product [<N, N ~> N, N ~> fill c N] - -- ^ ^ ^- tags and next positions - -- | |- offset - -- |- pred (number of tags in structure) - - mapShape : - {shape : Shape} -> - {ty, ty' : Ty} -> - FullTerm ((ty ~> ty') ~> fillShape shape ty ~> fillShape shape ty') [<] - mapShape {shape = (shape, n)} = mapSnd . mapVect - - gmap : - {0 f : a -> b} -> - {0 P : a -> Type} -> - {0 Q : b -> Type} -> - ({x : a} -> P x -> Q (f x)) -> - {xs : List a} -> - All P xs -> - All Q (map f xs) - gmap f [] = [] - gmap f (px :: pxs) = f px :: gmap f pxs - - forgetMap : - (0 f : a -> b) -> - (0 xs : List1 a) -> - forget (map f xs) = map f (forget xs) - forgetMap f (head ::: tail) = Refl - - calcOffsets : - {ctx : SnocList Ty} -> - {c : Container} -> - {n : Nat} -> - (ts : FullTerm (Vect n (fix c)) ctx) -> - (acc : FullTerm N ctx) -> - List (FullTerm N ctx, FullTerm (N ~> N) ctx) - calcOffsets {n = 0} ts acc = [] - calcOffsets {n = S k} ts acc = - let hd = app (lift head) ts in - let n = app (lift $ project $ There $ There Here) hd in - let offset = app (lift $ project $ There Here) hd in - (n, app (lift add) acc . offset) :: - calcOffsets - (app (lift tail) ts) - (app' (lift add) [<suc n, acc]) - - calcData : - {ctx : SnocList Ty} -> - {c : Container} -> - {n : Nat} -> - (ts : FullTerm (Vect n (fix c)) ctx) -> - (acc : FullTerm N ctx) -> - List (FullTerm N ctx, FullTerm (N ~> fill c N) ctx) - calcData {n = 0} ts acc = [] - calcData {n = S k} ts acc = - let hd = app (lift head) ts in - let n = app (lift $ project $ There $ There Here) hd in - (n, app (lift $ project Here) hd) :: - calcData - (app (lift tail) ts) - (app' (lift add) [<suc n, acc]) - - export - intro : - {c : Container} -> - {shape : Shape} -> - Elem shape (forget c) -> - FullTerm (fillShape shape (fix c) ~> fix c) [<] - intro {shape = (shape, n)} i = abs' (S Z) - (\t => - app' (lift $ pair' {tys = [<N, N ~> N, N ~> fill c N]}) - [<app (lift (sum . app mapVect (abs' (S Z) suc . project (There $ There Here)) . snd)) t - , cond ((zero, abs' (S Z) suc) :: calcOffsets (app (lift snd) t) (suc zero)) - , cond - ( (zero, - abs - (app - (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), drop t]))) - :: calcData (app (lift snd) t) (suc zero) - ) - ]) - - export - elim : - {c : Container} -> - {ctx : SnocList Ty} -> - {ty : Ty} -> - All (flip FullTerm ctx . (~> ty) . flip Data.fillShape ty) (forget c) -> - FullTerm (fix c ~> ty) ctx - elim cases = abs' (S Z) - (\t => - let tags = suc (app (lift $ project $ There $ There Here) t) in - let offset = app (lift $ project $ There Here) (drop $ drop t) in - let vals = app (lift $ project $ Here) (drop $ drop t) in - app' - (rec tags - (lift arb) - (abs' (S $ S Z) (\rec, n => - app - (any {tys = map (flip fillShape N) c} - (rewrite forgetMap (flip fillShape N) c in - gmap - (\f => - drop (drop $ drop f) . - app (lift mapShape) (rec . app (lift add) (app offset n))) - cases) . - vals) - n))) - [<zero]) - - -- elim cases (#tags-1,offset,data) = - -- let - -- step : (N -> ty) -> (N -> ty) - -- step rec n = - -- case rec n of - -- i => cases(i) . mapShape (rec . (+ offset n)) - -- in - -- rec #tags arb step 0 diff --git a/src/Total/LogRel.idr b/src/Total/LogRel.idr deleted file mode 100644 index b088e6f..0000000 --- a/src/Total/LogRel.idr +++ /dev/null @@ -1,355 +0,0 @@ -module Total.LogRel - -import Data.Singleton -import Syntax.PreorderReasoning -import Total.Reduction -import Total.Term -import Total.Term.CoDebruijn - -%prefix_record_projections off - -public export -LogRel : - {ctx : SnocList Ty} -> - (P : {ctx, ty : _} -> FullTerm ty ctx -> Type) -> - {ty : Ty} -> - (t : FullTerm ty ctx) -> - Type -LogRel p {ty = N} t = p t -LogRel p {ty = ty ~> ty'} t = - (p t, - {ctx' : SnocList Ty} -> - (thin : ctx `Thins` ctx') -> - (u : FullTerm ty ctx') -> - LogRel p u -> - LogRel p (app (wkn t thin) u)) - -export -escape : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - {ty : Ty} -> - {0 t : FullTerm ty ctx} -> - LogRel P t -> - P t -escape {ty = N} pt = pt -escape {ty = ty ~> ty'} (pt, app) = pt - -public export -record PreserveHelper - (P : {ctx, ty : _} -> FullTerm ty ctx -> Type) - (R : {ctx, ty : _} -> FullTerm ty ctx -> FullTerm ty ctx -> Type) where - constructor MkPresHelper - 0 app : - {ctx : SnocList Ty} -> - {ty, ty' : Ty} -> - (t, u : FullTerm (ty ~> ty') ctx) -> - {ctx' : SnocList Ty} -> - (thin : ctx `Thins` ctx') -> - (v : FullTerm ty ctx') -> - R t u -> - R (app (wkn t thin) v) (app (wkn u thin) v) - pres : - {0 ctx : SnocList Ty} -> - {ty : Ty} -> - {0 t, u : FullTerm ty ctx} -> - P t -> - (0 _ : R t u) -> - P u - -%name PreserveHelper help - -export -backStepHelper : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - (forall ctx, ty. {0 t, u : FullTerm ty ctx} -> P t -> (0 _ : toTerm u > toTerm t) -> P u) -> - PreserveHelper P (flip (>) `on` CoDebruijn.toTerm) -backStepHelper pres = - MkPresHelper - (\t, u, thin, v, step => - rewrite toTermApp (wkn u thin) v in - rewrite toTermApp (wkn t thin) v in - rewrite sym $ wknToTerm t thin in - rewrite sym $ wknToTerm u thin in - AppCong1 (wknStep step)) - pres - -export -preserve : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - {0 R : {ctx, ty : _} -> FullTerm ty ctx -> FullTerm ty ctx -> Type} -> - {ty : Ty} -> - {0 t, u : FullTerm ty ctx} -> - PreserveHelper P R -> - LogRel P t -> - (0 _ : R t u) -> - LogRel P u -preserve help {ty = N} pt prf = help.pres pt prf -preserve help {ty = ty ~> ty'} (pt, app) prf = - (help.pres pt prf, \thin, v, rel => preserve help (app thin v rel) (help.app _ _ thin v prf)) - -data AllLogRel : (P : {ctx, ty : _} -> FullTerm ty ctx -> Type) -> CoTerms ctx ctx' -> Type where - Lin : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - AllLogRel P [<] - (:<) : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - AllLogRel P sub -> - LogRel P t -> - AllLogRel P (sub :< t) - -%name AllLogRel allRels - -index : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - ((i : Elem ty ctx') -> LogRel P (var i)) -> - {sub : CoTerms ctx ctx'} -> - AllLogRel P sub -> - (i : Elem ty ctx) -> - LogRel P (index sub i) -index f (allRels :< rel) Here = rel -index f (allRels :< rel) (There i) = index f allRels i - -restrict : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - {0 sub : CoTerms ctx' ctx''} -> - AllLogRel P sub -> - (thin : ctx `Thins` ctx') -> - AllLogRel P (restrict sub thin) -restrict [<] Empty = [<] -restrict (allRels :< rel) (Drop thin) = restrict allRels thin -restrict (allRels :< rel) (Keep thin) = restrict allRels thin :< rel - -Valid : - (P : {ctx, ty : _} -> FullTerm ty ctx -> Type) -> - {ctx : SnocList Ty} -> - {ty : Ty} -> - (t : FullTerm ty ctx) -> - Type -Valid p t = - {ctx' : SnocList Ty} -> - (sub : CoTerms ctx ctx') -> - (allRel : AllLogRel p sub) -> - LogRel p (subst t sub) - -public export -record ValidHelper (P : {ctx, ty : _} -> FullTerm ty ctx -> Type) where - constructor MkValidHelper - var : forall ctx. Len ctx => {ty : Ty} -> (i : Elem ty ctx) -> LogRel P (var i) - abs : forall ctx, ty. {ty' : Ty} -> {0 t : FullTerm ty' (ctx :< ty)} -> LogRel P t -> P (abs t) - zero : forall ctx. Len ctx => P {ctx} zero - suc : forall ctx. {0 t : FullTerm N ctx} -> P t -> P (suc t) - rec : - {ctx : SnocList Ty} -> - {ty : Ty} -> - {0 t : FullTerm N ctx} -> - {u : FullTerm ty ctx} -> - {v : FullTerm (ty ~> ty) ctx} -> - LogRel P t -> - LogRel P u -> - LogRel P v -> - LogRel P (rec t u v) - step : forall ctx, ty. {0 t, u : FullTerm ty ctx} -> P t -> (0 _ : toTerm u > toTerm t) -> P u - wkn : forall ctx, ctx', ty. - {0 t : FullTerm ty ctx} -> - P t -> - (thin : ctx `Thins` ctx') -> - P (wkn t thin) - -%name ValidHelper help - -wknRel : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - ValidHelper P -> - {ty : Ty} -> - {0 t : FullTerm ty ctx} -> - LogRel P t -> - (thin : ctx `Thins` ctx') -> - LogRel P (wkn t thin) -wknRel help {ty = N} pt thin = help.wkn pt thin -wknRel help {ty = ty ~> ty'} (pt, app) thin = - ( help.wkn pt thin - , \thin', u, rel => - rewrite wknHomo t thin' thin in - app (thin' . thin) u rel - ) - -wknAllRel : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - ValidHelper P -> - {ctx : SnocList Ty} -> - {sub : CoTerms ctx ctx'} -> - AllLogRel P sub -> - (thin : ctx' `Thins` ctx'') -> - AllLogRel P (wknAll sub thin) -wknAllRel help [<] thin = [<] -wknAllRel help (allRels :< rel) thin = wknAllRel help allRels thin :< wknRel help rel thin - -shiftRel : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - ValidHelper P -> - {ctx, ctx' : SnocList Ty} -> - {sub : CoTerms ctx ctx'} -> - AllLogRel P sub -> - AllLogRel P (shift {ty} sub) -shiftRel help [<] = [<] -shiftRel help (allRels :< rel) = - shiftRel help allRels :< - replace {p = LogRel P} (sym $ dropIsWkn _) (wknRel help rel (Drop id)) - -liftRel : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - ValidHelper P -> - {ctx, ctx' : SnocList Ty} -> - {ty : Ty} -> - {sub : CoTerms ctx ctx'} -> - AllLogRel P sub -> - AllLogRel P (lift {ty} sub) -liftRel help allRels = shiftRel help allRels :< help.var Here - -absValid : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - ValidHelper P -> - {ctx : SnocList Ty} -> - {ty, ty' : Ty} -> - (t : CoTerm ty' (ctx ++ used)) -> - (thin : used `Thins` [<ty]) -> - (valid : {ctx' : SnocList Ty} -> - (sub : CoTerms (ctx ++ used) ctx') -> - AllLogRel P sub -> - LogRel P (subst' t sub)) -> - {ctx' : SnocList Ty} -> - (sub : CoTerms ctx ctx') -> - AllLogRel P sub -> - LogRel P (subst' (Abs (MakeBound t thin)) sub) -absValid help t (Drop Empty) valid sub allRels = - ( help.abs (valid (shift sub) (shiftRel help allRels)) - , \thin, u, rel => - preserve - (backStepHelper help.step) - (valid (wknAll sub thin) (wknAllRel help allRels thin)) - ?betaStep - ) -absValid help t (Keep Empty) valid sub allRels = - ( help.abs (valid (lift sub) (liftRel help allRels)) - , \thin, u, rel => - preserve (backStepHelper help.step) - (valid (wknAll sub thin :< u) (wknAllRel help allRels thin :< rel)) - ?betaStep' - ) - -export -allValid : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - ValidHelper P -> - (s : Singleton ctx) => - {ty : Ty} -> - (t : FullTerm ty ctx) -> - Valid P t -allValid' : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - ValidHelper P -> - (s : Singleton ctx) => - {ty : Ty} -> - (t : CoTerm ty ctx) -> - {ctx' : SnocList Ty} -> - (sub : CoTerms ctx ctx') -> - AllLogRel P sub -> - LogRel P (subst' t sub) - -allValid help (t `Over` thin) sub allRels = - allValid' help t (restrict sub thin) (restrict allRels thin) - -allValid' help Var sub allRels = index help.var allRels Here -allValid' help {s = Val ctx} (Abs {ty, ty'} (MakeBound t thin)) sub allRels = - let s' = [| Val ctx ++ retractSingleton (Val [<ty]) thin |] in - absValid help t thin (allValid' help t) sub allRels -allValid' help (App (MakePair 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 -allValid' help Zero sub allRels = help.zero -allValid' help (Suc t) sub allRels = - let pt = allValid' help t sub allRels in - help.suc pt -allValid' help (Rec (MakePair t (MakePair u v _ `Over` thin) _)) sub allRels = - let relT = allValid help t sub allRels in - let relU = allValid help u (restrict sub thin) (restrict allRels thin) in - let relV = allValid help v (restrict sub thin) (restrict allRels thin) in - help.rec relT relU relV - --- -- allValid help (Var i) sub allRels = index help.var allRels i --- -- allValid help (Abs t) sub allRels = --- -- let valid = allValid help t in --- -- (let --- -- rec = --- -- valid --- -- (wknAll sub (Drop id) :< Var Here) --- -- (wknAllRel help allRels (Drop id) :< help.var Here) --- -- in --- -- help.abs rec --- -- , \thin, u, rel => --- -- let --- -- eq : --- -- (subst --- -- (wkn (subst t (wknAll sub (Drop Thinning.id) :< Var Here)) (Keep thin)) --- -- (Base Thinning.id :< 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)) . (:< 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 (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 --- -- allValid help Zero sub allRels = help.zero --- -- allValid help (Suc t) sub allRels = --- -- let pt = allValid help t sub allRels in --- -- help.suc pt --- -- allValid help (Rec t u v) sub allRels = --- -- let relt = allValid help t sub allRels in --- -- let relu = allValid help u sub allRels in --- -- let relv = allValid help v sub allRels in --- -- help.rec relt relu relv - -idRel : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - {ctx : SnocList Ty} -> - ValidHelper P -> - AllLogRel P {ctx} (Base Thinning.id) -idRel help {ctx = [<]} = [<] -idRel help {ctx = ctx :< ty} = liftRel help (idRel help) - -export -allRel : - {0 P : {ctx, ty : _} -> FullTerm ty ctx -> Type} -> - {ctx : SnocList Ty} -> - {ty : Ty} -> - ValidHelper P -> - (t : FullTerm ty ctx) -> - P t -allRel help t = - rewrite sym $ substId t in - escape {P} $ - allValid help @{Val ctx} t (Base id) (idRel help) diff --git a/src/Total/NormalForm.idr b/src/Total/NormalForm.idr deleted file mode 100644 index a7aba57..0000000 --- a/src/Total/NormalForm.idr +++ /dev/null @@ -1,187 +0,0 @@ -module Total.NormalForm - -import Total.LogRel -import Total.Reduction -import Total.Term -import Total.Term.CoDebruijn - -%prefix_record_projections off - -public export -data Neutral' : CoTerm ty ctx -> Type -public export -data Normal' : CoTerm ty ctx -> Type - -public export -data Neutral : FullTerm ty ctx -> Type - -public export -data Normal : FullTerm ty ctx -> Type - -data Neutral' where - Var : Neutral' Var - App : Neutral t -> Normal u -> Neutral' (App (MakePair t u cover)) - Rec : - Neutral t -> - Normal u -> - Normal v -> - Neutral' (Rec (MakePair t (MakePair u v cover1 `Over` thin) cover2)) - -data Normal' where - Ntrl : Neutral' t -> Normal' t - Abs : Normal' t -> Normal' (Abs (MakeBound t thin)) - Zero : Normal' Zero - Suc : Normal' t -> Normal' (Suc t) - -data Neutral where - WrapNe : Neutral' t -> Neutral (t `Over` thin) - -data Normal where - WrapNf : Normal' t -> Normal (t `Over` thin) - -%name Neutral n, m, k -%name Normal n, m, k -%name Neutral' n, m, k -%name Normal' n, m, k - -public export -record NormalForm (0 t : FullTerm ty ctx) where - constructor MkNf - term : FullTerm ty ctx - 0 steps : toTerm t >= toTerm term - 0 normal : Normal term - -%name NormalForm nf - --- Strong Normalization Proof -------------------------------------------------- - -abs : Normal t -> Normal (abs t) - -app : Neutral t -> Normal u -> Neutral (app t u) - -suc : Normal t -> Normal (suc t) - -rec : Neutral t -> Normal u -> Normal v -> Neutral (rec t u v) - -invApp : Normal' (App x) -> Neutral' (App x) -invApp (Ntrl n) = n - -invRec : Normal' (Rec x) -> Neutral' (Rec x) -invRec (Ntrl n) = n - -invSuc : Normal' (Suc t) -> Normal' t -invSuc (Suc n) = n - -wknNe : Neutral t -> Neutral (wkn t thin) -wknNe (WrapNe n) = WrapNe n - -wknNf : Normal t -> Normal (wkn t thin) -wknNf (WrapNf n) = WrapNf n - -backStepsNf : NormalForm t -> (0 _ : toTerm u >= toTerm t) -> NormalForm u -backStepsNf nf steps = MkNf nf.term (steps ++ nf.steps) nf.normal - -backStepsRel : - {ty : Ty} -> - {0 t, u : FullTerm ty ctx} -> - LogRel (\t => NormalForm t) t -> - (0 _ : toTerm u >= toTerm t) -> - LogRel (\t => NormalForm t) u -backStepsRel = - preserve {R = flip (>=) `on` toTerm} - (MkPresHelper - (\t, u, thin, v, steps => - ?appCong1Steps) - backStepsNf) - -ntrlRel : {ty : Ty} -> {t : FullTerm ty ctx} -> (0 _ : Neutral t) -> LogRel (\t => NormalForm t) t -ntrlRel {ty = N} (WrapNe n) = MkNf t [<] (WrapNf (Ntrl n)) -ntrlRel {ty = ty ~> ty'} (WrapNe {thin = thin'} n) = - ( MkNf t [<] (WrapNf (Ntrl n)) - , \thin, u, rel => - backStepsRel - (ntrlRel (app (wknNe {thin} (WrapNe {thin = thin'} n)) (escape rel).normal)) - ?appCong2Steps - ) - -recNf'' : - {ctx : SnocList Ty} -> - {ty : Ty} -> - {u : FullTerm ty ctx} -> - {v : FullTerm (ty ~> ty) ctx} -> - (t : CoTerm N ctx') -> - (thin : ctx' `Thins` ctx) -> - (0 n : Normal' t) -> - LogRel (\t => NormalForm t) u -> - LogRel (\t => NormalForm t) v -> - LogRel (\t => NormalForm t) (rec (t `Over` thin) u v) -recNf'' Zero thin n relU relV = - backStepsRel relU [<?recZero] -recNf'' (Suc t) thin n relU relV = - let rec = recNf'' t thin (invSuc n) relU relV in - backStepsRel (snd relV id _ rec) [<?recSuc] -recNf'' t@Var thin n relU relV = - let 0 neT = WrapNe {thin} Var in - let nfU = escape relU in - let nfV = escape {ty = ty ~> ty} relV in - backStepsRel - (ntrlRel (rec neT nfU.normal nfV.normal)) - ?stepsUandV -recNf'' t@(App _) thin n relU relV = - let 0 neT = WrapNe {thin} (invApp n) in - let nfU = escape relU in - let nfV = escape {ty = ty ~> ty} relV in - backStepsRel - (ntrlRel (rec neT nfU.normal nfV.normal)) - ?stepsUandV' -recNf'' t@(Rec _) thin n relU relV = - let 0 neT = WrapNe {thin} (invRec n) in - let nfU = escape relU in - let nfV = escape {ty = ty ~> ty} relV in - backStepsRel - (ntrlRel (rec neT nfU.normal nfV.normal)) - ?stepsUandV'' - -recNf' : - {ctx : SnocList Ty} -> - {ty : Ty} -> - {u : FullTerm ty ctx} -> - {v : FullTerm (ty ~> ty) ctx} -> - (t : FullTerm N ctx) -> - (0 n : Normal t) -> - LogRel (\t => NormalForm t) u -> - LogRel (\t => NormalForm t) v -> - LogRel (\t => NormalForm t) (rec t u v) -recNf' (t `Over` thin) (WrapNf n) = recNf'' t thin n - -recNf : - {ctx : SnocList Ty} -> - {ty : Ty} -> - {0 t : FullTerm N ctx} -> - {u : FullTerm ty ctx} -> - {v : FullTerm (ty ~> ty) ctx} -> - NormalForm t -> - LogRel (\t => NormalForm t) u -> - LogRel (\t => NormalForm t) v -> - LogRel (\t => NormalForm t) (rec t u v) -recNf nf relU relV = - backStepsRel - (recNf' nf.term nf.normal relU relV) - ?recCong1Steps - -helper : ValidHelper (\t => NormalForm t) -helper = MkValidHelper - { var = \i => ntrlRel (WrapNe Var) - , abs = \rel => - let nf = escape rel in - MkNf (abs nf.term) ?absCongSteps (abs nf.normal) - , zero = MkNf zero [<] (WrapNf Zero) - , suc = \nf => MkNf (suc nf.term) ?sucCongSteps (suc nf.normal) - , rec = recNf - , step = \nf, step => backStepsNf nf [<step] - , wkn = \nf, thin => MkNf (wkn nf.term thin) ?wknSteps (wknNf nf.normal) - } - -export -normalize : {ctx : SnocList Ty} -> {ty : Ty} -> (t : FullTerm ty ctx) -> NormalForm t -normalize = allRel helper diff --git a/src/Total/Pretty.idr b/src/Total/Pretty.idr deleted file mode 100644 index eade721..0000000 --- a/src/Total/Pretty.idr +++ /dev/null @@ -1,163 +0,0 @@ -module Total.Pretty - -import public Text.PrettyPrint.Prettyprinter -import public Text.PrettyPrint.Prettyprinter.Render.Terminal - -import Data.DPair -import Data.Fin -import Data.Fin.Extra -import Data.Nat -import Data.Stream -import Data.String - -import Total.Syntax -import Total.Term - -data Syntax = Bound | Keyword - -keyword : Doc Syntax -> Doc Syntax -keyword = annotate Keyword - -bound : Doc Syntax -> Doc Syntax -bound = annotate Bound - -rec_ : Doc Syntax -rec_ = keyword "rec" - -plus : Doc Syntax -plus = keyword "+" - -arrow : Doc Syntax -arrow = keyword "=>" - -public export -interface Renderable (0 a : Type) where - fromSyntax : Syntax -> a - -export -Renderable AnsiStyle where - fromSyntax Bound = italic - fromSyntax Keyword = color BrightWhite - -startPrec, leftAppPrec, appPrec : Prec -startPrec = Open -leftAppPrec = Equal -appPrec = App - -parameters (names : Stream String) - export - prettyTerm : Len ctx -> Prec -> Term ctx ty -> Doc Syntax - prettyTerm len d (Var i) = bound (pretty $ index (minus (cast len) (S $ elemToNat i)) names) - prettyTerm len d (Abs t) = - let Evidence _ (len, t') = getLamNames (S len) t in - parenthesise (d > startPrec) $ group $ align $ hang 2 $ - backslash <+> prettyBindings len <++> arrow <+> line <+> - (prettyTerm len Open (assert_smaller t t')) - where - getLamNames : - forall ctx, ty. - Len ctx -> - Term ctx ty -> - Exists {type = Pair _ _} (\ctxTy => (Len (fst ctxTy), Term (fst ctxTy) (snd ctxTy))) - getLamNames k (Abs t) = getLamNames (S k) t - getLamNames k t@(Var _) = Evidence (_, _) (k, t) - getLamNames k t@(App _ _) = Evidence (_, _) (k, t) - getLamNames k t@Zero = Evidence (_, _) (k, t) - getLamNames k t@(Suc _) = Evidence (_, _) (k, t) - getLamNames k t@(Rec _ _ _) = Evidence (_, _) (k, t) - - prettyBindings' : Nat -> Nat -> Doc Syntax - prettyBindings' offset 0 = neutral - prettyBindings' offset 1 = bound (pretty $ index offset names) - prettyBindings' offset (S (S k)) = - bound (pretty $ index offset names) <+> comma <++> prettyBindings' (S offset) (S k) - - prettyBindings : Len ctx' -> Doc Syntax - prettyBindings k = prettyBindings' (cast len) (minus (cast k) (cast len)) - prettyTerm len d app@(App t u) = - let (f, ts) = getSpline t [prettyArg u] in - parenthesise (d >= appPrec) $ group $ align $ hang 2 $ - f <+> line <+> vsep ts - where - prettyArg : forall ty. Term ctx ty -> Doc Syntax - prettyArg v = prettyTerm len appPrec (assert_smaller app v) - - getSpline : - forall ty, ty'. - Term ctx (ty ~> ty') -> - List (Doc Syntax) -> - (Doc Syntax, List (Doc Syntax)) - getSpline (App t u) xs = getSpline t (prettyArg u :: xs) - getSpline (Rec t u v) xs = (rec_ <++> prettyArg t, prettyArg u :: prettyArg v :: xs) - getSpline t'@(Var _) xs = (prettyTerm len leftAppPrec (assert_smaller t t'), xs) - getSpline t'@(Abs _) xs = (prettyTerm len leftAppPrec (assert_smaller t t'), xs) - prettyTerm len d Zero = pretty 0 - prettyTerm len d (Suc t) = - let (lit, t') = getSucs t in - case t' of - Just t' => - parenthesise (d >= appPrec) $ group $ - pretty (S lit) <++> plus <++> prettyTerm len leftAppPrec (assert_smaller t t') - Nothing => pretty (S lit) - where - getSucs : Term ctx N -> (Nat, Maybe (Term ctx N)) - getSucs Zero = (0, Nothing) - getSucs (Suc t) = mapFst S (getSucs t) - getSucs t@(Var _) = (0, Just t) - getSucs t@(App _ _) = (0, Just t) - getSucs t@(Rec _ _ _) = (0, Just t) - prettyTerm len d (Rec t u v) = - parenthesise (d >= appPrec) $ group $ align $ hang 2 $ - rec_ <++> - prettyTerm len appPrec t <+> line <+> - prettyTerm len appPrec u <+> line <+> - prettyTerm len appPrec v - -finToChar : Fin 26 -> Char -finToChar 0 = 'x' -finToChar 1 = 'y' -finToChar 2 = 'z' -finToChar 3 = 'a' -finToChar 4 = 'b' -finToChar 5 = 'c' -finToChar 6 = 'd' -finToChar 7 = 'e' -finToChar 8 = 'f' -finToChar 9 = 'g' -finToChar 10 = 'h' -finToChar 11 = 'i' -finToChar 12 = 'j' -finToChar 13 = 'k' -finToChar 14 = 'l' -finToChar 15 = 'm' -finToChar 16 = 'n' -finToChar 17 = 'o' -finToChar 18 = 'p' -finToChar 19 = 'q' -finToChar 20 = 'r' -finToChar 21 = 's' -finToChar 22 = 't' -finToChar 23 = 'u' -finToChar 24 = 'v' -finToChar 25 = 'w' - -name : Nat -> List Char -name k = - case divMod k 26 of - Fraction k 26 0 r prf => [finToChar r] - Fraction k 26 (S q) r prf => finToChar r :: name (assert_smaller k q) - -export -canonicalNames : Stream String -canonicalNames = map (fastPack . name) nats - -export -pretty : Renderable ann => (len : Len ctx) => Term ctx ty -> Doc ann -pretty t = map fromSyntax (prettyTerm canonicalNames len Open t) - --- \x, y, z => --- rec z --- (\a, b => \c => \d => d (\d => d c) a x) --- (\a => \b => b y) --- 0 --- (\x => x) diff --git a/src/Total/Reduction.idr b/src/Total/Reduction.idr deleted file mode 100644 index a424515..0000000 --- a/src/Total/Reduction.idr +++ /dev/null @@ -1,114 +0,0 @@ -module Total.Reduction - -import Syntax.PreorderReasoning -import Total.Term - -public export -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 : - (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 - RecCong3 : v1 > v2 -> Rec t u v1 > Rec t u v2 - RecZero : Rec Zero u v > u - RecSuc : Rec (Suc t) u v > App v (Rec t u v) - -%name Reduction.(>) step - -public export -data (>=) : Term ctx ty -> Term ctx ty -> Type where - Lin : t >= t - (:<) : t >= u -> u > v -> t >= v - -%name Reduction.(>=) steps - -export -(++) : t >= u -> u >= v -> t >= v -steps ++ [<] = steps -steps ++ steps' :< step = (steps ++ steps') :< step - -export -AbsCong' : t >= u -> Abs t >= Abs u -AbsCong' [<] = [<] -AbsCong' (steps :< step) = AbsCong' steps :< AbsCong step - -export -AppCong1' : t >= u -> App t v >= App u v -AppCong1' [<] = [<] -AppCong1' (steps :< step) = AppCong1' steps :< AppCong1 step - -export -AppCong2' : u >= v -> App t u >= App t v -AppCong2' [<] = [<] -AppCong2' (steps :< step) = AppCong2' steps :< AppCong2 step - -export -SucCong' : t >= u -> Suc t >= Suc u -SucCong' [<] = [<] -SucCong' (steps :< step) = SucCong' steps :< SucCong step - -export -RecCong1' : t1 >= t2 -> Rec t1 u v >= Rec t2 u v -RecCong1' [<] = [<] -RecCong1' (steps :< step) = RecCong1' steps :< RecCong1 step - -export -RecCong2' : u1 >= u2 -> Rec t u1 v >= Rec t u2 v -RecCong2' [<] = [<] -RecCong2' (steps :< step) = RecCong2' steps :< RecCong2 step - -export -RecCong3' : v1 >= v2 -> Rec t u v1 >= Rec t u v2 -RecCong3' [<] = [<] -RecCong3' (steps :< step) = RecCong3' steps :< RecCong3 step - --- Properties ------------------------------------------------------------------ - -lemma : - (t : Term (ctx :< ty) ty') -> - (thin : ctx `Thins` ctx') -> - (u : Term ctx ty) -> - subst (wkn t (Keep thin)) (Base Thinning.id :< wkn u thin) = - wkn (subst t (Base Thinning.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 (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 @{length ctx}) :< 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 len {ctx, t, u}) {thin} = - let - 0 eq : - (subst (wkn t (Keep thin)) (Base Thinning.id :< wkn u thin) = - wkn (subst t (Base (id @{len}) :< u)) thin) - eq = rewrite lenUnique len (length ctx) in lemma t thin u - in - rewrite sym eq in - AppBeta _ -wknStep (SucCong step) = SucCong (wknStep step) -wknStep (RecCong1 step) = RecCong1 (wknStep step) -wknStep (RecCong2 step) = RecCong2 (wknStep step) -wknStep (RecCong3 step) = RecCong3 (wknStep step) -wknStep RecZero = RecZero -wknStep RecSuc = RecSuc - -export -wknSteps : t >= u -> wkn t thin >= wkn u thin -wknSteps [<] = [<] -wknSteps (steps :< step) = wknSteps steps :< wknStep step diff --git a/src/Total/Syntax.idr b/src/Total/Syntax.idr deleted file mode 100644 index fead586..0000000 --- a/src/Total/Syntax.idr +++ /dev/null @@ -1,128 +0,0 @@ -module Total.Syntax - -import public Data.List -import public Data.List.Quantifiers -import public Data.SnocList -import public Data.SnocList.Quantifiers -import public Total.Term -import public Total.Term.CoDebruijn - -infixr 20 ~>* -infixl 9 .~, .* - -public export -(~>*) : SnocList Ty -> Ty -> Ty -tys ~>* ty = foldr (~>) ty tys - -public export -0 Fun : {sx : SnocList a} -> Len sx -> (a -> Type) -> Type -> Type -Fun Z arg ret = ret -Fun (S {x = ty} k) arg ret = Fun k arg (arg ty -> ret) - -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 sx) -> - (forall x. p x -> q x) -> - Fun k q ret -> - Fun k p ret -before Z f x = x -before (S k) f x = before k f (after k (. f) x) - -export -lit : Len ctx => Nat -> FullTerm N ctx -lit 0 = Zero `Over` empty -lit (S n) = suc (lit n) - -absHelper : - (k : Len tys) -> - Fun k (flip Elem (ctx ++ tys)) (FullTerm ty (ctx ++ tys)) -> - FullTerm (tys ~>* ty) ctx -absHelper Z x = x -absHelper (S k) x = - absHelper k $ - after k (\f => CoDebruijn.abs (f SnocList.Elem.Here)) $ - before k SnocList.Elem.There x - -export -abs' : - (len : Len ctx) => - (k : Len tys) -> - Fun k (flip FullTerm (ctx ++ tys)) (FullTerm ty (ctx ++ tys)) -> - FullTerm (tys ~>* ty) ctx -abs' k = absHelper k . before k (var @{lenAppend len k}) - -export -app' : - {tys : SnocList Ty} -> - FullTerm (tys ~>* ty) ctx -> - All (flip FullTerm ctx) tys -> - FullTerm ty ctx -app' t [<] = t -app' t (us :< u) = app (app' t us) u - --- export --- compose : --- {ty, ty' : Ty} -> --- (t : FullTerm (ty' ~> ty'') ctx) -> --- (u : FullTerm (ty ~> ty') ctx) -> --- Len u.support => --- Covering Covers t.thin u.thin -> --- CoTerm (ty ~> ty'') ctx --- compose (t `Over` thin1) (u `Over` thin2) cover = --- Abs --- (MakeBound --- (App --- (MakePair --- (t `Over` Drop thin1) --- (App --- (MakePair --- (u `Over` Drop id) --- (Var `Over` Keep empty) --- (DropKeep (coverIdLeft empty))) --- `Over` Keep thin2) --- (DropKeep cover))) --- (Keep Empty)) - --- export --- (.~) : --- Len ctx => --- {ty, ty' : Ty} -> --- CoTerm (ty' ~> ty'') ctx -> --- CoTerm (ty ~> ty') ctx -> --- CoTerm (ty ~> ty'') ctx --- t .~ u = compose (t `Over` id) (u `Over` id) (coverIdLeft id) - -export -(.) : - Len ctx => - {ty, ty' : Ty} -> - FullTerm (ty' ~> ty'') ctx -> - FullTerm (ty ~> ty') ctx -> - FullTerm (ty ~> ty'') ctx -t . u = abs' (S Z) (\x => app (drop t) (app (drop u) x)) - -export -(.*) : - Len ctx => - {ty : Ty} -> - {tys : SnocList Ty} -> - FullTerm (ty ~> ty') ctx -> - FullTerm (tys ~>* ty) ctx -> - FullTerm (tys ~>* ty') ctx -(.*) {tys = [<]} t u = app t u -(.*) {tys = tys :< ty''} t u = abs' (S Z) (\f => drop t . f) .* u - -export -lift : Len ctx => FullTerm ty [<] -> FullTerm ty ctx -lift t = wkn t empty - -export -id' : CoTerm (ty ~> ty) [<] -id' = Abs (MakeBound Var (Keep Empty)) - -export -id : FullTerm (ty ~> ty) [<] -id = id' `Over` empty diff --git a/src/Total/Term.idr b/src/Total/Term.idr deleted file mode 100644 index 129662a..0000000 --- a/src/Total/Term.idr +++ /dev/null @@ -1,357 +0,0 @@ -module Total.Term - -import public Data.SnocList.Elem -import public Thinning -import Syntax.PreorderReasoning - -%prefix_record_projections off - -infixr 10 ~> - -public export -data Ty : Type where - N : Ty - (~>) : Ty -> Ty -> Ty - -%name Ty ty - -public export -data Term : SnocList Ty -> Ty -> Type where - Var : (i : Elem ty ctx) -> Term ctx ty - Abs : Term (ctx :< ty) ty' -> Term ctx (ty ~> ty') - App : {ty : Ty} -> Term ctx (ty ~> ty') -> Term ctx ty -> Term ctx ty' - Zero : Term ctx N - Suc : Term ctx N -> Term ctx N - Rec : Term ctx N -> Term ctx ty -> Term ctx (ty ~> ty) -> Term ctx ty - -%name Term t, u, v - -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 (App t u) thin = App (wkn t thin) (wkn u thin) -wkn Zero thin = Zero -wkn (Suc t) thin = Suc (wkn t thin) -wkn (Rec t u v) thin = Rec (wkn t thin) (wkn u thin) (wkn v thin) - -public export -data Terms : SnocList Ty -> SnocList Ty -> Type where - Base : ctx `Thins` ctx' -> Terms ctx' ctx - (:<) : Terms ctx' ctx -> Term ctx' ty -> Terms ctx' (ctx :< ty) - -%name Terms sub - -public export -index : Terms ctx' ctx -> Elem ty ctx -> Term ctx' ty -index (Base thin) i = Var (index thin i) -index (sub :< t) Here = t -index (sub :< t) (There i) = index sub i - -public export -wknAll : Terms ctx' ctx -> ctx' `Thins` ctx'' -> Terms ctx'' ctx -wknAll (Base thin') thin = Base (thin . thin') -wknAll (sub :< t) thin = wknAll sub thin :< wkn t thin - -public export -subst : Len ctx' => 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 (App t u) sub = App (subst t sub) (subst u sub) -subst Zero sub = Zero -subst (Suc t) sub = Suc (subst t sub) -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) (Drop thin) = restrict sub thin -restrict (sub :< t) (Keep thin) = restrict sub thin :< t - -public export -(.) : Len ctx'' => Terms ctx'' ctx' -> Terms ctx' ctx -> Terms ctx'' ctx -sub2 . (Base thin) = restrict sub2 thin -sub2 . (sub1 :< t) = sub2 . sub1 :< subst t sub2 - --- Properties ------------------------------------------------------------------ - --- Utilities - -export -cong3 : (0 f : a -> b -> c -> d) -> x1 = x2 -> y1 = y2 -> z1 = z2 -> f x1 y1 z1 = f x2 y2 z2 -cong3 f Refl Refl Refl = Refl - --- Weakening - -export -wknHomo : - (t : Term ctx ty) -> - (thin1 : ctx `Thins` ctx') -> - (thin2 : ctx' `Thins` ctx'') -> - wkn (wkn t thin1) thin2 = wkn t (thin2 . thin1) -wknHomo (Var i) thin1 thin2 = - cong Var (indexHomo thin2 thin1 i) -wknHomo (Abs t) thin1 thin2 = - 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 = - Refl -wknHomo (Suc t) thin1 thin2 = - cong Suc (wknHomo t thin1 thin2) -wknHomo (Rec t u v) thin1 thin2 = - cong3 Rec (wknHomo t thin1 thin2) (wknHomo u thin1 thin2) (wknHomo v thin1 thin2) - -export -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 -wknId (Suc t) = cong Suc (wknId t) -wknId (Rec t u v) = cong3 Rec (wknId t) (wknId u) (wknId v) - -indexWknAll : - (sub : Terms ctx' ctx) -> - (thin : ctx' `Thins` ctx'') -> - (i : Elem ty ctx) -> - index (wknAll sub thin) i = wkn (index sub i) thin -indexWknAll (Base thin') thin i = sym $ cong Var $ indexHomo thin thin' i -indexWknAll (sub :< t) thin Here = Refl -indexWknAll (sub :< t) thin (There i) = indexWknAll sub thin i - -wknAllHomo : - (sub : Terms ctx ctx''') -> - (thin1 : ctx `Thins` ctx') -> - (thin2 : ctx' `Thins` ctx'') -> - wknAll (wknAll sub thin1) thin2 = wknAll sub (thin2 . thin1) -wknAllHomo (Base thin) thin1 thin2 = cong Base (assoc thin2 thin1 thin) -wknAllHomo (sub :< t) thin1 thin2 = cong2 (:<) (wknAllHomo sub thin1 thin2) (wknHomo t thin1 thin2) - --- Restrict - -indexRestrict : - (thin : ctx `Thins` ctx') -> - (sub : Terms ctx'' ctx') -> - (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 (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 : (len : Len ctx) => (sub : Terms ctx' ctx) -> restrict sub (id @{len}) = sub -restrictId (Base thin) = cong Base (identityRight thin) -restrictId {len = S k} (sub :< t) = cong (:< t) (restrictId sub) - -restrictHomo : - (sub : Terms ctx ctx''') -> - (thin1 : ctx'' `Thins` ctx''') -> - (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) (Drop thin1) thin2 = restrictHomo sub thin1 thin2 -restrictHomo (sub :< t) (Keep thin1) (Drop thin2) = restrictHomo sub thin1 thin2 -restrictHomo (sub :< t) (Keep thin1) (Keep thin2) = cong (:< t) $ restrictHomo sub thin1 thin2 - -wknAllRestrict : - (thin1 : ctx `Thins` ctx') -> - (sub : Terms ctx'' ctx') -> - (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 (Drop thin) (sub :< t) thin2 = wknAllRestrict thin sub thin2 -wknAllRestrict (Keep thin) (sub :< t) thin2 = cong (:< wkn t thin2) (wknAllRestrict thin sub thin2) - --- Substitution & Weakening - -export -wknSubst : - (t : Term ctx ty) -> - (sub : Terms ctx' ctx) -> - (thin : ctx' `Thins` ctx'') -> - wkn (subst t sub) thin = subst t (wknAll sub thin) -wknSubst (Var i) sub thin = - sym (indexWknAll sub thin i) -wknSubst (Abs t) sub thin = - 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) - ...(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 = - Refl -wknSubst (Suc t) sub thin = - cong Suc (wknSubst t sub thin) -wknSubst (Rec t u v) sub thin = - cong3 Rec (wknSubst t sub thin) (wknSubst u sub thin) (wknSubst v sub thin) - -export -substWkn : - (t : Term ctx ty) -> - (thin : ctx `Thins` ctx') -> - (sub : Terms ctx'' ctx') -> - subst (wkn t thin) sub = subst t (restrict sub thin) -substWkn (Var i) thin sub = - sym (indexRestrict thin sub i) -substWkn (Abs t) thin sub = - cong Abs $ Calc $ - |~ 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 = - Refl -substWkn (Suc t) thin sub = - cong Suc (substWkn t thin sub) -substWkn (Rec t u v) thin sub = - cong3 Rec (substWkn t thin sub) (substWkn u thin sub) (substWkn 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) - WknAll : - (len : Len ctx) => - Equiv sub sub' -> - 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 = 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) - -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 (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) -substCong (Rec t u v) prf = cong3 Rec (substCong t prf) (substCong u prf) (substCong v prf) - -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 = - 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) -substBase (Rec t u v) thin = cong3 Rec (substBase t thin) (substBase u thin) (substBase v thin) - --- Substitution Composition - -indexComp : - (sub1 : Terms ctx' ctx) -> - (sub2 : Terms ctx'' ctx') -> - (i : Elem ty ctx) -> - index (sub2 . sub1) i = subst (index sub1 i) sub2 -indexComp (Base thin) sub2 i = indexRestrict thin sub2 i -indexComp (sub1 :< t) sub2 Here = Refl -indexComp (sub1 :< t) sub2 (There i) = indexComp sub1 sub2 i - -wknAllComp : - (sub1 : Terms ctx' ctx) -> - (sub2 : Terms ctx'' ctx') -> - (thin : ctx'' `Thins` ctx''') -> - wknAll sub2 thin . sub1 = wknAll (sub2 . sub1) thin -wknAllComp (Base thin') sub2 thin = wknAllRestrict thin' sub2 thin -wknAllComp (sub1 :< t) sub2 thin = - cong2 (:<) - (wknAllComp sub1 sub2 thin) - (sym $ wknSubst t sub2 thin) - -compDrop : - (sub1 : Terms ctx' ctx) -> - (thin : ctx' `Thins` ctx'') -> - (sub2 : Terms ctx''' ctx'') -> - sub2 . wknAll sub1 thin = restrict sub2 thin . sub1 -compDrop (Base thin') thin sub2 = restrictHomo sub2 thin thin' -compDrop (sub1 :< t) thin sub2 = cong2 (:<) (compDrop sub1 thin sub2) (substWkn t thin sub2) - -export -compWknAll : - (sub1 : Terms ctx' ctx) -> - (sub2 : Terms ctx''' ctx'') -> - (thin : ctx' `Thins` ctx'') -> - sub2 . wknAll sub1 thin = restrict sub2 thin . sub1 -compWknAll (Base thin') sub2 thin = restrictHomo sub2 thin thin' -compWknAll (sub1 :< t) sub2 thin = cong2 (:<) (compWknAll sub1 sub2 thin) (substWkn t thin sub2) - -export -baseComp : - (thin : ctx' `Thins` ctx'') -> - (sub : Terms ctx' ctx) -> - Base thin . sub = wknAll sub thin -baseComp thin (Base thin') = Refl -baseComp thin (sub :< t) = cong2 (:<) (baseComp thin sub) (substBase t thin) - --- Substitution - -export -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 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) -substId (Rec t u v) = cong3 Rec (substId t) (substId u) (substId v) - -export -substHomo : - (t : Term ctx ty) -> - (sub1 : Terms ctx' ctx) -> - (sub2 : Terms ctx'' ctx') -> - subst (subst t sub1) sub2 = subst t (sub2 . sub1) -substHomo (Var i) sub1 sub2 = - sym $ indexComp sub1 sub2 i -substHomo (Abs t) sub1 sub2 = - 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) - ...(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)) -substHomo (App t u) sub1 sub2 = - cong2 App (substHomo t sub1 sub2) (substHomo u sub1 sub2) -substHomo Zero sub1 sub2 = - Refl -substHomo (Suc t) sub1 sub2 = - cong Suc (substHomo t sub1 sub2) -substHomo (Rec t u v) sub1 sub2 = - cong3 Rec (substHomo t sub1 sub2) (substHomo u sub1 sub2) (substHomo v sub1 sub2) diff --git a/src/Total/Term/CoDebruijn.idr b/src/Total/Term/CoDebruijn.idr deleted file mode 100644 index 0efcdbb..0000000 --- a/src/Total/Term/CoDebruijn.idr +++ /dev/null @@ -1,317 +0,0 @@ -module Total.Term.CoDebruijn - -import public Data.SnocList.Elem -import public Thinning -import Syntax.PreorderReasoning -import Total.Term - -%prefix_record_projections off - --- Definition ------------------------------------------------------------------ - -public export -data CoTerm : Ty -> SnocList Ty -> Type where - Var : CoTerm ty [<ty] - Abs : Binds [<ty] (CoTerm ty') ctx -> CoTerm (ty ~> ty') ctx - App : {ty : Ty} -> Pair (CoTerm (ty ~> ty')) (CoTerm ty) ctx -> CoTerm ty' ctx - Zero : CoTerm N [<] - Suc : CoTerm N ctx -> CoTerm N ctx - Rec : Pair (CoTerm N) (Pair (CoTerm ty) (CoTerm (ty ~> ty))) ctx -> CoTerm ty ctx - -%name CoTerm t, u, v - -public export -FullTerm : Ty -> SnocList Ty -> Type -FullTerm ty ctx = Thinned (CoTerm ty) ctx - --- Smart Constructors ---------------------------------------------------------- - -public export -var : Len ctx => Elem ty ctx -> FullTerm ty ctx -var i = Var `Over` point i - -public export -abs : FullTerm ty' (ctx :< ty) -> FullTerm (ty ~> ty') ctx -abs = map Abs . MkBound (S Z) - -public export -app : {ty : Ty} -> FullTerm (ty ~> ty') ctx -> FullTerm ty ctx -> FullTerm ty' ctx -app t u = map App (MkPair t u) - -public export -zero : Len ctx => FullTerm N ctx -zero = Zero `Over` empty - -public export -suc : FullTerm N ctx -> FullTerm N ctx -suc = map Suc - -public export -rec : FullTerm N ctx -> FullTerm ty ctx -> FullTerm (ty ~> ty) ctx -> FullTerm ty ctx -rec t u v = map Rec $ MkPair t (MkPair u v) - --- Substitutions --------------------------------------------------------------- - -public export -data CoTerms : SnocList Ty -> SnocList Ty -> Type where - Lin : CoTerms [<] ctx' - (:<) : CoTerms ctx ctx' -> FullTerm ty ctx' -> CoTerms (ctx :< ty) ctx' - -%name CoTerms sub - -public export -index : CoTerms ctx ctx' -> Elem ty ctx -> FullTerm ty ctx' -index (sub :< t) Here = t -index (sub :< t) (There i) = index sub i - -public export -wknAll : CoTerms ctx ctx' -> ctx' `Thins` ctx'' -> CoTerms ctx ctx'' -wknAll [<] thin = [<] -wknAll (sub :< t) thin = wknAll sub thin :< wkn t thin - -public export -shift : CoTerms ctx ctx' -> CoTerms ctx (ctx' :< ty) -shift [<] = [<] -shift (sub :< t) = shift sub :< drop t - -public export -lift : Len ctx' => CoTerms ctx ctx' -> CoTerms (ctx :< ty) (ctx' :< ty) -lift sub = shift sub :< var Here - -public export -restrict : CoTerms ctx' ctx'' -> ctx `Thins` ctx' -> CoTerms ctx ctx'' -restrict [<] Empty = [<] -restrict (sub :< t) (Drop thin) = restrict sub thin -restrict (sub :< t) (Keep thin) = restrict sub thin :< t - -public export -Base : (len : Len ctx') => ctx `Thins` ctx' -> CoTerms ctx ctx' -Base Empty = [<] -Base {len = S k} (Drop thin) = shift (Base thin) -Base {len = S k} (Keep thin) = lift (Base thin) - --- Substitution Operation ------------------------------------------------------ - -public export -subst : Len ctx' => FullTerm ty ctx -> CoTerms ctx ctx' -> FullTerm ty ctx' -public export -subst' : Len ctx' => CoTerm ty ctx -> CoTerms ctx ctx' -> FullTerm ty ctx' - -subst (t `Over` thin) sub = subst' t (restrict sub thin) - -subst' Var sub = index sub Here -subst' (Abs (MakeBound t (Drop Empty))) sub = abs (subst' t $ shift sub) -subst' (Abs (MakeBound t (Keep Empty))) sub = abs (subst' t $ lift sub) -subst' (App (MakePair t u _)) sub = app (subst t sub) (subst u sub) -subst' Zero sub = zero -subst' (Suc t) sub = suc (subst' t sub) -subst' (Rec (MakePair t (MakePair u v _ `Over` thin) _)) sub = - rec (subst t sub) (subst u (restrict sub thin)) (subst v (restrict sub thin)) - --- Initiality ------------------------------------------------------------------ - -toTerm' : CoTerm ty ctx -> ctx `Thins` ctx' -> Term ctx' ty -toTerm' Var thin = Var (index thin Here) -toTerm' (Abs (MakeBound t (Drop Empty))) thin = Abs (toTerm' t (Drop thin)) -toTerm' (Abs (MakeBound t (Keep Empty))) thin = Abs (toTerm' t (Keep thin)) -toTerm' (App (MakePair (t `Over` thin1) (u `Over` thin2) _)) thin = - App (toTerm' t (thin . thin1)) (toTerm' u (thin . thin2)) -toTerm' Zero thin = Zero -toTerm' (Suc t) thin = Suc (toTerm' t thin) -toTerm' - (Rec - (MakePair - (t `Over` thin1) - (MakePair (u `Over` thin2) (v `Over` thin3) _ `Over` thin') _)) - thin = - Rec - (toTerm' t (thin . thin1)) - (toTerm' u ((thin . thin') . thin2)) - (toTerm' v ((thin . thin') . thin3)) - -export -toTerm : FullTerm ty ctx -> Term ctx ty -toTerm (t `Over` thin) = toTerm' t thin - -public export -toTerms : Len ctx' => CoTerms ctx ctx' -> Terms ctx' ctx -toTerms [<] = Base empty -toTerms (sub :< t) = toTerms sub :< toTerm t - -export -Cast (FullTerm ty ctx) (Term ctx ty) where - cast = toTerm - -export -Len ctx' => Cast (CoTerms ctx ctx') (Terms ctx' ctx) where - cast = toTerms - -export -Len ctx => Cast (Term ctx ty) (FullTerm ty ctx) where - cast (Var i) = Var `Over` point i - cast (Abs t) = abs (cast t) - cast (App {ty} t u) = app {ty} (cast t) (cast u) - cast Zero = zero - cast (Suc t) = suc (cast t) - cast (Rec t u v) = rec (cast t) (cast u) (cast v) - --- Properties ------------------------------------------------------------------ - -wknToTerm' : - (t : CoTerm ty ctx) -> - (thin : ctx `Thins` ctx') -> - (thin' : ctx' `Thins` ctx''') -> - wkn (toTerm' t thin) thin' = toTerm' t (thin' . thin) -wknToTerm' Var thin thin' = cong Var (indexHomo thin' thin Here) -wknToTerm' (Abs (MakeBound t (Drop Empty))) thin thin' = - cong Abs (wknToTerm' t (Drop thin) (Keep thin')) -wknToTerm' (Abs (MakeBound t (Keep Empty))) thin thin' = - cong Abs (wknToTerm' t (Keep thin) (Keep thin')) -wknToTerm' (App (MakePair (t `Over` thin1) (u `Over` thin2) _)) thin thin' = - rewrite sym $ assoc thin' thin thin1 in - rewrite sym $ assoc thin' thin thin2 in - cong2 App (wknToTerm' t (thin . thin1) thin') (wknToTerm' u (thin . thin2) thin') -wknToTerm' Zero thin thin' = Refl -wknToTerm' (Suc t) thin thin' = cong Suc (wknToTerm' t thin thin') -wknToTerm' - (Rec - (MakePair - (t `Over` thin1) - (MakePair (u `Over` thin2) (v `Over` thin3) _ `Over` thin'') _)) - thin - thin' = - rewrite sym $ assoc thin' thin thin1 in - rewrite sym $ assoc (thin' . thin) thin'' thin2 in - rewrite sym $ assoc thin' thin (thin'' . thin2) in - rewrite sym $ assoc thin thin'' thin2 in - rewrite sym $ assoc (thin' . thin) thin'' thin3 in - rewrite sym $ assoc thin' thin (thin'' . thin3) in - rewrite sym $ assoc thin thin'' thin3 in - cong3 Rec - (wknToTerm' t (thin . thin1) thin') - (wknToTerm' u (thin . (thin'' . thin2)) thin') - (wknToTerm' v (thin . (thin'' . thin3)) thin') - -export -wknToTerm : - (t : FullTerm ty ctx) -> - (thin : ctx `Thins` ctx') -> - wkn (toTerm t) thin = toTerm (wkn t thin) -wknToTerm (t `Over` thin') thin = wknToTerm' t thin' thin - -export -toTermVar : Len ctx => (i : Elem ty ctx) -> toTerm (var i) = Var i -toTermVar i = cong Var $ indexPoint i - -export -toTermApp : - (t : FullTerm (ty ~> ty') ctx) -> - (u : FullTerm ty ctx) -> - toTerm (app t u) = App (toTerm t) (toTerm u) -toTermApp (t `Over` thin1) (u `Over` thin2) = - cong2 App - (cong (toTerm' t) $ irrelevantEq $ triangleCorrect (coprod thin1 thin2).left) - (cong (toTerm' u) $ irrelevantEq $ triangleCorrect (coprod thin1 thin2).right) - -indexShift : - (sub : CoTerms ctx ctx') -> - (i : Elem ty ctx) -> - index (shift sub) i = drop (index sub i) -indexShift (sub :< t) Here = Refl -indexShift (sub :< t) (There i) = indexShift sub i - -indexBase : (thin : [<ty] `Thins` ctx') -> index (Base thin) Here = Var `Over` thin -indexBase (Drop thin) = trans (indexShift (Base thin) Here) (cong drop (indexBase thin)) -indexBase (Keep thin) = irrelevantEq $ cong ((Var `Over`) . Keep) $ emptyUnique empty thin - -restrictShift : - (sub : CoTerms ctx' ctx'') -> - (thin : ctx `Thins` ctx') -> - restrict (shift sub) thin = shift (restrict sub thin) -restrictShift [<] Empty = Refl -restrictShift (sub :< t) (Drop thin) = restrictShift sub thin -restrictShift (sub :< t) (Keep thin) = cong (:< drop t) (restrictShift sub thin) - -restrictBase : - (thin2 : ctx' `Thins` ctx'') -> - (thin1 : ctx `Thins` ctx') -> - CoDebruijn.restrict (Base thin2) thin1 = Base (thin2 . thin1) -restrictBase Empty Empty = Refl -restrictBase (Drop thin2) thin1 = - trans - (restrictShift (Base thin2) thin1) - (cong shift $ restrictBase thin2 thin1) -restrictBase (Keep thin2) (Drop thin1) = - trans - (restrictShift (Base thin2) thin1) - (cong shift $ restrictBase thin2 thin1) -restrictBase (Keep thin2) (Keep thin1) = - cong (:< (Var `Over` point Here)) $ - trans - (restrictShift (Base thin2) thin1) - (cong shift $ restrictBase thin2 thin1) - -substBase : - (t : CoTerm ty ctx) -> - (thin : ctx `Thins` ctx') -> - subst' t (Base thin) = t `Over` thin -substBase Var thin = indexBase thin -substBase (Abs (MakeBound t (Drop Empty))) thin = - Calc $ - |~ map Abs (MkBound (S Z) (subst' t (shift $ Base thin))) - ~~ map Abs (MkBound (S Z) (t `Over` Drop thin)) - ...(cong (map Abs . MkBound (S Z)) $ substBase t (Drop thin)) - ~~ map Abs (MakeBound t (Drop Empty) `Over` thin) - ...(Refl) - ~~ (Abs (MakeBound t (Drop Empty)) `Over` thin) - ...(Refl) -substBase (Abs (MakeBound t (Keep Empty))) thin = - Calc $ - |~ map Abs (MkBound (S Z) (subst' t (lift $ Base thin))) - ~~ map Abs (MkBound (S Z) (t `Over` Keep thin)) - ...(cong (map Abs . MkBound (S Z)) $ substBase t (Keep thin)) - ~~ map Abs (MakeBound t (Keep Empty) `Over` thin) - ...(Refl) - ~~ (Abs (MakeBound t (Keep Empty)) `Over` thin) - ...(Refl) -substBase (App (MakePair (t `Over` thin1) (u `Over` thin2) cover)) thin = - rewrite restrictBase thin thin1 in - rewrite restrictBase thin thin2 in - rewrite substBase t (thin . thin1) in - rewrite substBase u (thin . thin2) in - rewrite coprodEta thin cover in - Refl -substBase Zero thin = cong (Zero `Over`) $ irrelevantEq $ emptyUnique empty thin -substBase (Suc t) thin = cong (map Suc) $ substBase t thin -substBase - (Rec (MakePair - (t `Over` thin1) - (MakePair - (u `Over` thin2) - (v `Over` thin3) - cover' - `Over` thin') - cover)) - thin = - rewrite restrictBase thin thin1 in - rewrite restrictBase thin thin' in - rewrite restrictBase (thin . thin') thin2 in - rewrite restrictBase (thin . thin') thin3 in - rewrite substBase t (thin . thin1) in - rewrite substBase u ((thin . thin') . thin2) in - rewrite substBase v ((thin . thin') . thin3) in - rewrite coprodEta (thin . thin') cover' in - rewrite coprodEta thin cover in - Refl - -export -substId : (t : FullTerm ty ctx) -> subst t (Base Thinning.id) = t -substId (t `Over` thin) = - Calc $ - |~ subst' t (restrict (Base id) thin) - ~~ subst' t (Base $ id . thin) - ...(cong (subst' t) $ restrictBase id thin) - ~~ subst' t (Base thin) - ...(cong (subst' t . Base) $ identityLeft thin) - ~~ (t `Over` thin) - ...(substBase t thin) diff --git a/src/Type.idr b/src/Type.idr new file mode 100644 index 0000000..12c0a74 --- /dev/null +++ b/src/Type.idr @@ -0,0 +1,10 @@ +module Type + +infix 4 ~> + +public export +data Ty : Type where + N : Ty + (~>) : Ty -> Ty -> Ty + +%name Ty ty |