diff options
author | Chloe Brown <chloe.brown.00@outlook.com> | 2023-06-15 16:09:42 +0100 |
---|---|---|
committer | Chloe Brown <chloe.brown.00@outlook.com> | 2023-06-15 16:09:42 +0100 |
commit | cedc6109895a53ce6ed667e0391b232bf5463387 (patch) | |
tree | cb600a2b91255586821d94dba5137a8cb746c90e /src/Subst.idr | |
parent | f910e142ce7c10f8244ecfa40e41756fb8c8a53f (diff) |
WIP : use smarter weakenings.better-thinning
Diffstat (limited to 'src/Subst.idr')
-rw-r--r-- | src/Subst.idr | 460 |
1 files changed, 460 insertions, 0 deletions
diff --git a/src/Subst.idr b/src/Subst.idr new file mode 100644 index 0000000..08220e7 --- /dev/null +++ b/src/Subst.idr @@ -0,0 +1,460 @@ +module Subst + +import Control.Order +import Control.Relation +import Syntax.PreorderReasoning +import Syntax.PreorderReasoning.Generic +import Thinning + +%prefix_record_projections off + +-- Interfaces ------------------------------------------------------------------ + +public export +interface Point (0 a : Type) (0 t : a -> SnocList a -> Type) | t where + point : {0 x : a} -> {0 sx : SnocList a} -> Elem x sx -> t x sx + +public export +interface Weaken (0 a : Type) (0 t : a -> SnocList a -> Type) | t where + wkn : + {0 x : a} -> + {0 sx, sy : SnocList a} -> + t x sx -> + sx `Thins` sy -> + t x sy + shift : {0 x, y : a} -> {0 sx : SnocList a} -> t y sx -> t y (sx :< x) + shift v = wkn v (drop (id sx) x) + +public export +interface Point a t => Weaken a t => PointWeaken a t | t where + +public export +interface Weaken a t => FullWeaken a t | t where + wknId : {0 x : a} -> {0 sx : SnocList a} -> (v : t x sx) -> wkn v (id sx) = v + wknHomo : + {0 x : a} -> + {0 sx, sy, sz : SnocList a} -> + (v : t x sx) -> + (thin1 : sx `Thins` sy) -> + (thin2 : sy `Thins` sz) -> + wkn (wkn v thin1) thin2 = wkn v (thin2 . thin1) + shiftIsWkn : + {0 x, y : a} -> + {0 sx : SnocList a} -> + (v : t y sx) -> + wkn v (drop (id sx) x) = shift v + +public export +interface Point a t => FullWeaken a t => FullPointWeaken a t | t where + wknPoint : + {0 x : a} -> + {0 sx, sy : SnocList a} -> + (i : Elem x sx) -> + (thin : sx `Thins` sy) -> + wkn {t} (point i) thin = point (index thin i) + +-- Substitutions --------------------------------------------------------------- + +public export +data Subst : (t : a -> SnocList a -> Type) -> (sx, sy : SnocList a) -> Type where + Base : sx `Thins` sy -> Subst t sx sy + (:<) : Subst t sx sy -> t x sy -> Subst t (sx :< x) sy + +%name Subst sub + +export +index : Point a t => Subst t sx sy -> Elem x sx -> t x sy +index (Base thin) i = point (index thin i) +index (sub :< v) Here = v +index (sub :< v) (There i) = index sub i + +namespace Subst + export + wkn : Weaken a t => Subst t sx sy -> sy `Thins` sz -> Subst t sx sz + wkn (Base thin') thin = Base (thin . thin') + wkn (sub :< v) thin = wkn sub thin :< wkn v thin + + export + shift : Weaken a t => Subst t sx sy -> Subst t sx (sy :< y) + shift (Base thin) = Base (drop thin y) + shift (sub :< v) = shift sub :< shift v + + public export + lift : Point a t => Weaken a t => Subst t sx sy -> Subst t (sx :< z) (sy :< z) + lift sub = shift sub :< point Here + +export +restrict : Subst t sy sz -> sx `Thins` sy -> Subst t sx sz +restrictView : + Subst t sy sz -> + t y sz -> + {0 thin : sx `Thins` sy :< y} -> + View thin -> + Subst t sx sz + +restrict (Base thin') thin = Base (thin' . thin) +restrict (sub :< v) thin = restrictView sub v (view thin) + +restrictView sub v Id = sub :< v +restrictView sub v (Drop thin z) = restrict sub thin +restrictView sub v (Keep thin z) = restrict sub thin :< v + +-- Equivalence ----------------------------------------------------------------- + +public export +record Equiv {auto 0 p : Point a t} (sub1, sub2 : Subst t sx sy) where + constructor IsEquiv + equiv : (forall x. (i : Elem x sx) -> index sub1 i = index sub2 i) + +%name Subst.Equiv e + +export +Point a t => Reflexive (Subst t sx sy) Equiv where + reflexive = IsEquiv (\i => Refl) + +export +Point a t => Symmetric (Subst t sx sy) Equiv where + symmetric e = IsEquiv (\i => sym (e.equiv i)) + +export +Point a t => Transitive (Subst t sx sy) Equiv where + transitive e e' = IsEquiv (\i => trans (e.equiv i) (e'.equiv i)) + +export +Point a t => Preorder (Subst t sx sy) Equiv where + +namespace Equiv + export + Base : + (p : Point a t) => + {0 thin1, thin2 : sx `Thins` sy} -> + thin1 = thin2 -> + Equiv @{p} (Base thin1) (Base thin2) + Base prf = IsEquiv (\i => cong (\thin => index (Base thin) i) prf) + + export + (:<) : + Point a t => + {0 sub1, sub2 : Subst t sx sy} -> + Equiv sub1 sub2 -> + u = v -> + Equiv (sub1 :< u) (sub2 :< v) + e :< prf = IsEquiv (\i => case i of Here => prf; There i => e.equiv i) + +-- Properties ------------------------------------------------------------------ + +export +irrelevantEquiv : + Point a t => + {0 sub1, sub2 : Subst t sx sy} -> + (0 _ : Equiv sub1 sub2) -> + Equiv sub1 sub2 +irrelevantEquiv e = IsEquiv (\i => irrelevantEq $ e.equiv i) + +-- Weakening + +namespace Subst + export + indexWkn : + FullPointWeaken a t => + (sub : Subst t sx sy) -> + (thin : sy `Thins` sz) -> + (i : Elem x sx) -> + wkn (index sub i) thin = index (wkn sub thin) i + indexWkn (Base thin') thin i = Calc $ + |~ wkn (point (index thin' i)) thin + ~~ point {t} (index thin (index thin' i)) ...(wknPoint (index thin' i) thin) + ~~ point (index (thin . thin') i) ...(cong point $ indexHomo thin' thin i) + indexWkn (sub :< v) thin Here = Refl + indexWkn (sub :< v) thin (There i) = indexWkn sub thin i + + export + wknCong : + FullPointWeaken a t => + {0 sub1, sub2 : Subst t sx sy} -> + {0 thin1, thin2 : sy `Thins` sz} -> + Equiv sub1 sub2 -> + thin1 = thin2 -> + Equiv (wkn sub1 thin1) (wkn sub2 thin2) + wknCong e prf = irrelevantEquiv $ IsEquiv (\i => Calc $ + |~ index (wkn sub1 thin1) i + ~~ wkn (index sub1 i) thin1 ..<(indexWkn sub1 thin1 i) + ~~ wkn (index sub2 i) thin2 ...(cong2 wkn (e.equiv i) prf) + ~~ index (wkn sub2 thin2) i ...(indexWkn sub2 thin2 i)) + + export + wknId : + FullPointWeaken a t => + (sub : Subst t sx sy) -> + Equiv (wkn sub (id sy)) sub + wknId (Base thin) = Base (identityLeft thin) + wknId (sub :< v) = wknId sub :< wknId v + + export + wknHomo : + FullPointWeaken a t => + (sub : Subst t sx sy) -> + (thin1 : sy `Thins` sz) -> + (thin2 : sz `Thins` sw) -> + Equiv (wkn (wkn sub thin1) thin2) (wkn sub (thin2 . thin1)) + wknHomo (Base thin) thin1 thin2 = Base (assoc thin2 thin1 thin) + wknHomo (sub :< v) thin1 thin2 = wknHomo sub thin1 thin2 :< wknHomo v thin1 thin2 + +-- Restrict + +export +restrictBase : + (p : Point a t) => + (thin' : sy `Thins` sz) -> + (thin : sx `Thins` sy) -> + Equiv @{p} (Base (thin' . thin)) (restrict (Base thin') thin) +restrictBase thin' thin = reflexive + +export +indexRestrict : + Point a t => + (sub : Subst t sy sz) -> + (thin : sx `Thins` sy) -> + (i : Elem x sx) -> + index sub (index thin i) = index (restrict sub thin) i +indexRestrictView : + Point a t => + (sub : Subst t sy sz) -> + (v : t y sz) -> + {0 thin : sx `Thins` sy :< y} -> + (view : View thin) -> + (i : Elem x sx) -> + index (sub :< v) (index thin i) = index (restrictView sub v view) i + +indexRestrict (Base thin') thin i = cong point (indexHomo thin thin' i) +indexRestrict (sub :< v) thin i = indexRestrictView sub v (view thin) i + +indexRestrictView sub v Id i = cong (index (sub :< v)) (indexId i) +indexRestrictView sub v (Drop thin z) i = Calc $ + |~ index (sub :< v) (index (drop thin z) i) + ~~ index (sub :< v) (There (index thin i)) ...(cong (index (sub :< v)) $ indexDrop thin i) + ~~ index sub (index thin i) ...(Refl) + ~~ index (restrict sub thin) i ...(indexRestrict sub thin i) +indexRestrictView sub v (Keep thin x) Here = cong (index (sub :< v)) (indexKeepHere thin) +indexRestrictView sub v (Keep thin z) (There i) = Calc $ + |~ index (sub :< v) (index (keep thin z) (There i)) + ~~ index (sub :< v) (There (index thin i)) ...(cong (index (sub :< v)) $ indexKeepThere thin i) + ~~ index sub (index thin i) ...(Refl) + ~~ index (restrict sub thin) i ...(indexRestrict sub thin i) + +export +restrictCong : + Point a t => + {0 sub1, sub2 : Subst t sy sz} -> + {0 thin1, thin2 : sx `Thins` sy} -> + Equiv sub1 sub2 -> + thin1 = thin2 -> + Equiv (restrict sub1 thin1) (restrict sub2 thin2) +restrictCong e prf = irrelevantEquiv $ IsEquiv (\i => Calc $ + |~ index (restrict sub1 thin1) i + ~~ index sub1 (index thin1 i) ..<(indexRestrict sub1 thin1 i) + ~~ index sub2 (index thin1 i) ...(e.equiv (index thin1 i)) + ~~ index sub2 (index thin2 i) ...(cong (\thin => index sub2 (index thin i)) prf) + ~~ index (restrict sub2 thin2) i ...(indexRestrict sub2 thin2 i)) + +export +restrictId : + Point a t => + (sub : Subst t sx sy) -> + Equiv (restrict sub (id sx)) sub +restrictId (Base thin) = Base (identityRight thin) +restrictId {sx = .(sx :< x)} (sub :< v) = + rewrite viewUnique (view (id (sx :< x))) Id in + reflexive + +export +restrictHomo : + Point a t => + (sub : Subst t sz sw) -> + (thin1 : sy `Thins` sz) -> + (thin2 : sx `Thins` sy) -> + Equiv (restrict (restrict sub thin1) thin2) (restrict sub (thin1 . thin2)) +restrictViewHomo1 : + Point a t => + (sub : Subst t sz sw) -> + (v : t z sw) -> + {0 thin1 : sy `Thins` sz :< z} -> + (view1 : View thin1) -> + (thin2 : sx `Thins` sy) -> + Equiv (restrict (restrictView sub v view1) thin2) (restrictView sub v (view (thin1 . thin2))) +restrictViewHomo2 : + Point a t => + (sub : Subst t sz sw) -> + (v : t y sw) -> + (thin1 : sy `Thins` sz) -> + {auto 0 ok : NotId thin1} -> + {0 thin2 : sx `Thins` sy :< y} -> + (view2 : View thin2) -> + Equiv + (restrictView (restrict sub thin1) v view2) + (restrictView sub v (view (keep thin1 y . thin2))) + +restrictHomo (Base thin) thin1 thin2 = symmetric $ Base (assoc thin thin1 thin2) +restrictHomo (sub :< v) thin1 thin2 = restrictViewHomo1 sub v (view thin1) thin2 + +restrictViewHomo1 sub v Id thin2 = + rewrite identityLeft thin2 in + reflexive +restrictViewHomo1 sub v (Drop thin1 z) thin2 = + rewrite dropLeft thin1 thin2 z in + rewrite viewUnique (view (drop (thin1 . thin2) z)) (Drop (thin1 . thin2) z) in + restrictHomo sub thin1 thin2 +restrictViewHomo1 sub v (Keep thin1 z) thin2 = restrictViewHomo2 sub v thin1 (view thin2) + +restrictViewHomo2 sub v thin1 Id = + rewrite identityRight (keep thin1 y) in + rewrite viewUnique (view (keep thin1 y)) (Keep thin1 y) in + reflexive +restrictViewHomo2 sub v thin1 (Drop thin2 y) = + rewrite keepDrop thin1 thin2 y in + rewrite viewUnique (view (drop (thin1 . thin2) y)) (Drop (thin1 . thin2) y) in + restrictHomo sub thin1 thin2 +restrictViewHomo2 sub v thin1 (Keep thin2 {ok = ok'} y) = + rewrite keepHomo thin1 thin2 y in + rewrite + viewUnique + (view (keep (thin1 . thin2) y)) + (Keep (thin1 . thin2) {ok = compNotId ok ok'} y) + in + restrictHomo sub thin1 thin2 :< Refl + +namespace Subst + export + wknRestrict : + FullPointWeaken a t => + (sub : Subst t sy sz) -> + (thin1 : sx `Thins` sy) -> + (thin2 : sz `Thins` sw) -> + Equiv (wkn (restrict sub thin1) thin2) (restrict (wkn sub thin2) thin1) + wknRestrictView : + FullPointWeaken a t => + (sub : Subst t sy sz) -> + (v : t y sz) -> + {0 thin1 : sx `Thins` sy :< y} -> + (view1 : View thin1) -> + (thin2 : sz `Thins` sw) -> + Equiv (wkn (restrictView sub v view1) thin2) (restrictView (wkn sub thin2) (wkn v thin2) view1) + + wknRestrict (Base thin) thin1 thin2 = Base (assoc thin2 thin thin1) + wknRestrict (sub :< v) thin1 thin2 = wknRestrictView sub v (view thin1) thin2 + + wknRestrictView sub v Id thin2 = reflexive + wknRestrictView sub v (Drop thin1 y) thin2 = wknRestrict sub thin1 thin2 + wknRestrictView sub v (Keep thin1 y) thin2 = wknRestrict sub thin1 thin2 :< Refl + +-- Shift + + export + shiftIsWkn : + Point a t => + FullWeaken a t => + (sub : Subst t sx sy) -> + Equiv (wkn sub (drop (id sy) y)) (shift sub) + shiftIsWkn (Base thin) = + Base $ trans + (dropLeft (id sy) thin y) + (cong (\thin => drop thin y) $ identityLeft thin) + shiftIsWkn (sub :< v) = shiftIsWkn sub :< shiftIsWkn v + +export +shiftCong : + FullPointWeaken a t => + {0 sub1, sub2 : Subst t sx sy} -> + Equiv sub1 sub2 -> + Equiv (shift {y} sub1) (shift sub2) +shiftCong e = irrelevantEquiv $ CalcWith $ + |~ shift sub1 + <~ wkn sub1 (drop (id sy) y) ..<(shiftIsWkn sub1) + <~ wkn sub2 (drop (id sy) y) ...(wknCong e reflexive) + <~ shift sub2 ...(shiftIsWkn sub2) + +export +wknShiftKeep : + FullPointWeaken a t => + (sub : Subst t sx sy) -> + (thin : sy `Thins` sz) -> + Equiv (wkn (shift sub) (keep thin y)) (shift (wkn sub thin)) +wknShiftKeep sub thin = CalcWith $ + |~ wkn (shift sub) (keep thin y) + <~ wkn (wkn sub (drop (id sy) y)) (keep thin y) ..<(wknCong (shiftIsWkn sub) reflexive) + <~ wkn sub (keep thin y . drop (id sy) y) ...(wknHomo sub (drop (id sy) y) (keep thin y)) + ~~ wkn sub (drop (thin . (id sy)) y) ...(cong (wkn sub) (keepDrop thin (id sy) y)) + ~~ wkn sub (drop thin y) ...(cong (\thin => wkn sub (drop thin y)) (identityRight thin)) + ~~ wkn sub (drop (id sz . thin) y) ..<(cong (\thin => wkn sub (drop thin y)) (identityLeft thin)) + <~ wkn sub (drop (id sz) y . thin) ..<(wknCong reflexive (dropLeft (id sz) thin y)) + <~ wkn (wkn sub thin) (drop (id sz) y) ..<(wknHomo sub thin (drop (id sz) y)) + <~ shift (wkn sub thin) ...(shiftIsWkn (wkn sub thin)) + + +export +restrictShift : + FullPointWeaken a t => + (sub : Subst t sy sz) -> + (thin : sx `Thins` sy) -> + Equiv (restrict (shift {y = z} sub) thin) (shift (restrict sub thin)) +restrictShift sub thin = CalcWith $ + |~ restrict (shift sub) thin + <~ restrict (wkn sub (drop (id sz) z)) thin ..<(restrictCong (shiftIsWkn sub) reflexive) + <~ wkn (restrict sub thin) (drop (id sz) z) ..<(wknRestrict sub thin (drop (id sz) z)) + <~ shift (restrict sub thin) ...(shiftIsWkn (restrict sub thin)) + +-- Lift + +namespace Subst + export + liftCong : + FullPointWeaken a t => + {0 sub1, sub2 : Subst t sx sy} -> + Equiv sub1 sub2 -> + Equiv (lift sub1) (lift sub2) + liftCong e = shiftCong e :< Refl + + export + wknLift : + FullPointWeaken a t => + (sub : Subst t sx sy) -> + (thin : sy `Thins` sz) -> + Equiv (wkn (lift sub) (keep thin z)) (lift (wkn sub thin)) + wknLift sub thin = + wknShiftKeep sub thin :< + trans + (wknPoint Here (keep thin z)) + (cong point $ indexKeepHere thin) + + restrictLiftView : + FullPointWeaken a t => + (sub : Subst t sy sz) -> + {0 thin : sx `Thins` sy} -> + (view : View thin) -> + Equiv (restrict (lift sub) (keep thin y)) (lift (restrict sub thin)) + restrictLiftView sub Id = + rewrite keepId sy y in + rewrite viewUnique (view (id (sy :< y))) Id in + symmetric (shiftCong (restrictId sub)) :< Refl + restrictLiftView sub (Drop thin z) = + rewrite + viewUnique + (view (keep (drop thin z) y)) + (Keep (drop thin z) {ok = dropNotId thin z} y) + in + restrictShift sub (drop thin z) :< Refl + restrictLiftView sub (Keep thin z) = + rewrite + viewUnique + (view (keep (keep thin z) y)) + (Keep (keep thin z) {ok = keepNotId thin z} y) + in + restrictShift sub (keep thin z) :< Refl + + export + restrictLift : + FullPointWeaken a t => + (sub : Subst t sy sz) -> + (thin : sx `Thins` sy) -> + Equiv (restrict (lift sub) (keep thin y)) (lift (restrict sub thin)) + restrictLift sub thin = restrictLiftView sub (view thin) |