Skip to content

Commit 2a80adc

Browse files
committed
add first draft of an explanation of the substitutions
1 parent a58451d commit 2a80adc

File tree

1 file changed

+135
-0
lines changed

1 file changed

+135
-0
lines changed

UnderstandingSubstitutions.agda

+135
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
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

Comments
 (0)