|
| 1 | +module UnderstandingSubstitutions where |
| 2 | + |
| 3 | +open import Study |
| 4 | +open HSub |
| 5 | + |
| 6 | +-- Here I will do a personal rewrite of Conor's hereditary substitution, to |
| 7 | +-- understand it better. |
| 8 | + |
| 9 | +-------------------------------------------------------------------------------- |
| 10 | +-- Weakening substitutions |
| 11 | +-------------------------------------------------------------------------------- |
| 12 | +-- Crucially, φ indicates which iz of the jz occur in the source term. So the |
| 13 | +-- point here is that all the variables in iz are added to the passive variables |
| 14 | +-- while the active variables remain the same, and passive and active are |
| 15 | +-- similarly extended. Also the partition is updated to note that all the iz |
| 16 | +-- have gone in the passive variables. The other significant change is that all |
| 17 | +-- the images have been thinned to account for the fact that they are throwing |
| 18 | +-- away the things in jz (that they don't need). |
| 19 | +wkHSub' : ∀ {I}{D : I → Desc I}{src trg bnd iz jz} |
| 20 | + → HSub D src trg bnd |
| 21 | + → iz <= jz |
| 22 | + → HSub D (src ++ iz) (trg ++ jz) bnd |
| 23 | +wkHSub' {iz = iz} {jz = jz} h φ = |
| 24 | + record |
| 25 | + { pass = pass h ++ iz |
| 26 | + ; act = act h |
| 27 | + ; passive = passive h <++= oi {kz = iz} |
| 28 | + ; active = active h <++= oe {kz = iz} |
| 29 | + ; parti = bindPassive iz |
| 30 | + ; passTrg = passTrg h <++= φ |
| 31 | + ; actBnd = actBnd h |
| 32 | + ; images = all (thin/ (oi <++= oe {kz = jz})) (images h) |
| 33 | + } |
| 34 | + where |
| 35 | + -- bindPassive extends the partition with a cs' for each variable in iz |
| 36 | + -- (because they are active) |
| 37 | + bindPassive : forall iz -> Cover ff (passive h <++= oi {kz = iz}) (active h <++= oe {kz = iz}) |
| 38 | + bindPassive B0 = parti h |
| 39 | + bindPassive (iz - _) = bindPassive iz cs' |
| 40 | + |
| 41 | +-------------------------------------------------------------------------------- |
| 42 | +-- Whittling them down |
| 43 | +-------------------------------------------------------------------------------- |
| 44 | +mutual |
| 45 | + -- The type of this is fairly straightforward, and the implementation |
| 46 | + -- essentially uses selPart' |
| 47 | + selHSub' : forall {I}{D : I -> Desc I}{src src' trg bnd} |
| 48 | + -> src <= src' -> HSub D src' trg bnd -> HSub D src trg bnd |
| 49 | + selHSub' ψ s with selPart' ψ (parti s) |
| 50 | + selHSub' ψ s | iz , jz , th , ph , ps0 , ps1 , c |
| 51 | + = record |
| 52 | + { pass = iz |
| 53 | + ; act = jz |
| 54 | + ; passive = th |
| 55 | + ; active = ph |
| 56 | + ; parti = c |
| 57 | + ; passTrg = ps0 <&= passTrg s |
| 58 | + ; actBnd = ps1 <&= actBnd s |
| 59 | + ; images = ps1 <?= images s |
| 60 | + } |
| 61 | + |
| 62 | + -- A bit difficult to read here because Sg is the paper's internal notation |
| 63 | + -- for Σ, but the gist of it is that if I give you a kz <= kz' and a |
| 64 | + -- partitioning of kz' in th' and ph', then I can give you a partitioning of |
| 65 | + -- kz, just "reading" the corresponding choices in kz'. This function, in |
| 66 | + -- retrospective, is obvious. |
| 67 | + selPart' : forall {K}{iz' jz' kz kz' : Bwd K}{th' : iz' <= kz'}{ph' : jz' <= kz'} |
| 68 | + (ps : kz <= kz') |
| 69 | + -> Cover ff th' ph' |
| 70 | + -> Sg _ \ iz |
| 71 | + -> Sg _ \ jz |
| 72 | + -> Sg (iz <= kz) \ th |
| 73 | + -> Sg (jz <= kz) \ ph |
| 74 | + -> Sg (iz <= iz') \ ps0 |
| 75 | + -> Sg (jz <= jz') \ ps1 |
| 76 | + -> Cover ff th ph |
| 77 | + -- ps o' means that the new element is not in kz, the cover specifies where it was in kz' |
| 78 | + selPart' (ps o') (c' c's) = let ! ! ! ! ps0 , ps1 , c = selPart' ps c' in ! ! ! ! ps0 , ps1 o' , c |
| 79 | + selPart' (ps o') (c' cs') = let ! ! ! ! ps0 , ps1 , c = selPart' ps c' in ! ! ! ! ps0 o' , ps1 , c |
| 80 | + selPart' (ps o') (_css {both = ()} _) |
| 81 | + selPart' (ps os) (c' c's) = let ! ! ! ! ps0 , ps1 , c = selPart' ps c' in ! ! ! ! ps0 , ps1 os , c c's |
| 82 | + selPart' (ps os) (c' cs') = let ! ! ! ! ps0 , ps1 , c = selPart' ps c' in ! ! ! ! ps0 os , ps1 , c cs' |
| 83 | + selPart' (ps os) (_css {both = ()} _) |
| 84 | + selPart' oz czz = ! ! ! ! oz , oz , czz |
| 85 | + |
| 86 | +-------------------------------------------------------------------------------- |
| 87 | +-- allLeft |
| 88 | +-------------------------------------------------------------------------------- |
| 89 | +-- If the right part of a partition is empty, then the left must be full. The |
| 90 | +-- proof is simple induction. |
| 91 | +allLeft' : forall {K}{iz kz : Bwd K}{ov}{th : iz <= kz}{ph : B0 <= kz} -> Cover ov th ph -> iz == kz |
| 92 | +allLeft' czz = refl |
| 93 | +allLeft' (c cs') rewrite allLeft' c = refl |
| 94 | + |
| 95 | +-------------------------------------------------------------------------------- |
| 96 | +-- The main functions |
| 97 | +-------------------------------------------------------------------------------- |
| 98 | + |
| 99 | +-- hSub is the main operation on terms: given a substitution between contexts, |
| 100 | +-- and a term, it applies the substitution. Let's notice here that the term uses |
| 101 | +-- all his variables in a relevant way, while the resulting term may not use all |
| 102 | +-- of them. |
| 103 | +hSub' : forall {I D src trg bnd}{i : I} |
| 104 | + -> HSub D src trg bnd -> TmR D i src -> TmR D i / trg |
| 105 | +-- This function is used to apply a substitution to a description in the |
| 106 | +-- co-de-Bruijn syntax. |
| 107 | +hSubs' : forall {I D src trg bnd}(S : Desc I) |
| 108 | + -> HSub D src trg bnd -> [! S !! TmR D !]R src -> [! S !! TmR D !]R / trg |
| 109 | +-- This is the lifted version of the preceding function: the source term doesn't |
| 110 | +-- need to use all the variables in src. |
| 111 | +hSubs/' : forall {I D src trg bnd}(S : Desc I) |
| 112 | + -> HSub D src trg bnd -> [! S !! TmR D !]R / src -> [! S !! TmR D !]R / trg |
| 113 | +-- This is to substitute the variable hereditarily: it is the part that |
| 114 | +-- explicitly involves the spine construction |
| 115 | +hered' : forall {I D jz trg bnd}{i : I} |
| 116 | + -> (jz !- TmR D i) / trg -> B0 - (jz => i) <= bnd -> [! SpD jz !! TmR D !]R / trg -> TmR D i / trg |
| 117 | + |
| 118 | +-- We can have two constructs here: a syntax construct or a variable. In the |
| 119 | +-- first case, we will continue substituting into the structure. In the second |
| 120 | +-- case, we have to understand whether the variable we're talking about is |
| 121 | +-- passive or active, so we pattern match on selHSub', with a first argument, |
| 122 | +-- th, which has been refined enough to admit only one variable (the other |
| 123 | +-- argument is of course the substitution). We also compute the substitution in |
| 124 | +-- the spine, via hSubs/'. Next, if the variable is passive, we just return the |
| 125 | +-- variable with the new computed interpretation of the spine, while if the |
| 126 | +-- variable is active, we substitute hereditarily using the image. |
| 127 | +hSub' {D = D}{i = i} h [ ts ] = map/ [_] (hSubs' (D i) h ts) |
| 128 | +hSub' h (# {jz} (pair (only ^ th) ts _)) with selHSub' th h | hSubs/' (SpD jz) h ts |
| 129 | +... | record { parti = _css {both = ()} _ } | ts' |
| 130 | +... | record { parti = czz cs' ; passTrg = ph } | ts' = map/ # (vaR ph ,R ts') |
| 131 | +... | record { parti = czz c's ; actBnd = th' ; images = B0 - im } | ts' = hered im th' ts' |
| 132 | + |
| 133 | +hSubs' = {!!} |
| 134 | +hSubs/' = {!!} |
| 135 | +hered' = {!!} |
0 commit comments