-
Notifications
You must be signed in to change notification settings - Fork 0
/
lemmas-freshness.agda
392 lines (375 loc) · 17.8 KB
/
lemmas-freshness.agda
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
open import List
open import Nat
open import Prelude
open import binders-disjointness
open import contexts
open import core
open import freshness
open import lemmas-contexts
open import patterns-core
open import result-judgements
open import statics-core
module lemmas-freshness where
-- the emitted context Γp contains only variables
-- occuring in the pattern
unbound-in-p-apart-Γp : ∀{p τ ξ Γp Δp x} →
Δp ⊢ p :: τ [ ξ ]⊣ Γp →
unbound-in-p x p →
x # Γp
unbound-in-p-apart-Γp PTUnit UBPUnit = refl
unbound-in-p-apart-Γp PTNum UBPNum = refl
unbound-in-p-apart-Γp PTVar (UBPVar x≠y) =
neq-apart-singleton x≠y
unbound-in-p-apart-Γp (PTInl pt) (UBPInl ub) =
unbound-in-p-apart-Γp pt ub
unbound-in-p-apart-Γp (PTInr pt) (UBPInr ub) =
unbound-in-p-apart-Γp pt ub
unbound-in-p-apart-Γp {x = x}
(PTPair {Γ1 = Γ1} {Γ2 = Γ2}
disj pt1 pt2)
(UBPPair ub1 ub2) =
apart-parts Γ1 Γ2 x
(unbound-in-p-apart-Γp pt1 ub1)
(unbound-in-p-apart-Γp pt2 ub2)
unbound-in-p-apart-Γp (PTEHole w∈Δp) UBPEHole = refl
unbound-in-p-apart-Γp (PTHole w∈Δp pt) (UBPHole ub) =
unbound-in-p-apart-Γp pt ub
unbound-in-p-apart-Γp PTWild UBPWild = refl
-- if a pattern is binders disjoint from a term,
-- then anything in the emitted context Γp is
-- unbound in said term. that is, every binder in
-- the pattern occurs in Γp
dom-Γp-unbound-in : ∀{p τ ξ Γp Δp x T t} →
{{_ : UnboundIn T}} →
Δp ⊢ p :: τ [ ξ ]⊣ Γp →
dom Γp x →
binders-disjoint-p {T = T} p t →
unbound-in x t
dom-Γp-unbound-in PTVar x∈Γp (BDPVar {x = y} ub)
with dom-singleton-eq x∈Γp
... | refl = ub
dom-Γp-unbound-in (PTInl pt) x∈Γp (BDPInl bd) =
dom-Γp-unbound-in pt x∈Γp bd
dom-Γp-unbound-in (PTInr pt) x∈Γp (BDPInr bd) =
dom-Γp-unbound-in pt x∈Γp bd
dom-Γp-unbound-in {x = x} (PTPair {Γ1 = Γ1} {Γ2 = Γ2}
Γ1##Γ2 pt1 pt2)
(τ , x∈Γp)
(BDPPair bd1 bd2)
with dom-union-part Γ1 Γ2 x τ x∈Γp
... | Inl x∈Γ1 = dom-Γp-unbound-in pt1 (τ , x∈Γ1) bd1
... | Inr x∈Γ2 = dom-Γp-unbound-in pt2 (τ , x∈Γ2) bd2
dom-Γp-unbound-in (PTEHole w∈Δp) () BDPEHole
dom-Γp-unbound-in (PTHole w∈Δp pt) x∈Γp (BDPHole bd) =
dom-Γp-unbound-in pt x∈Γp bd
-- anything apart from the emitted context is not in the pattern
apart-Γp-unbound-in-p : ∀{p τ ξ Γp Δp x} →
Δp ⊢ p :: τ [ ξ ]⊣ Γp →
x # Γp →
unbound-in-p x p
apart-Γp-unbound-in-p PTUnit x#Γp = UBPUnit
apart-Γp-unbound-in-p PTNum x#Γp = UBPNum
apart-Γp-unbound-in-p {τ = τ} {x = x} (PTVar {x = y}) x#Γp =
UBPVar (apart-singleton-neq x#Γp)
apart-Γp-unbound-in-p (PTInl pt) x#Γp =
UBPInl (apart-Γp-unbound-in-p pt x#Γp)
apart-Γp-unbound-in-p (PTInr pt) x#Γp =
UBPInr (apart-Γp-unbound-in-p pt x#Γp)
apart-Γp-unbound-in-p {x = x}
(PTPair {Γ1 = Γ1} {Γ2 = Γ2}
Γ1##Γ2 pt1 pt2)
x#Γp =
UBPPair (apart-Γp-unbound-in-p pt1
(apart-union-l Γ1 Γ2 x x#Γp))
(apart-Γp-unbound-in-p pt2
(apart-union-r Γ1 Γ2 x x#Γp))
apart-Γp-unbound-in-p (PTEHole w∈Δp) x#Γp = UBPEHole
apart-Γp-unbound-in-p (PTHole w∈Δp pt) x#Γp =
UBPHole (apart-Γp-unbound-in-p pt x#Γp)
apart-Γp-unbound-in-p PTWild x#Γp = UBPWild
-- a variable is unbound in a combined list of
-- substitutions if its unbound in each part
substs-concat-unbound-in : ∀{x θ1 θ2} →
unbound-in-θ x θ1 →
unbound-in-θ x θ2 →
unbound-in-θ x (θ1 ++ θ2)
substs-concat-unbound-in UBθEmpty ub2 = ub2
substs-concat-unbound-in (UBθExtend xubd x≠y ub1) ub2 =
UBθExtend xubd x≠y (substs-concat-unbound-in ub1 ub2)
-- for a well-typed list of substitutions, anything
-- unbound in the list is unbound in the type Γθ
-- recording all substitutions
unbound-in-θ-apart-Γθ : ∀{Γ Δ Δp θ Γθ x} →
Γ , Δ , Δp ⊢ θ :sl: Γθ →
unbound-in-θ x θ →
x # Γθ
unbound-in-θ-apart-Γθ STEmpty UBθEmpty = refl
unbound-in-θ-apart-Γθ {x = x}
(STExtend {Γθ = Γθ} y#Γ wst wt)
(UBθExtend xubd x≠y xubθ) =
neq-apart-extend Γθ x≠y
(unbound-in-θ-apart-Γθ wst xubθ)
-- a match expression only emits substitutions involing
-- variables bound in the pattern
unbound-in-mat-substs : ∀{x e τ p θ} →
unbound-in-e x e →
unbound-in-p x p →
e ·: τ ▹ p ⊣ θ →
unbound-in-θ x θ
unbound-in-mat-substs ube UBPUnit MUnit = UBθEmpty
unbound-in-mat-substs ube UBPNum MNum = UBθEmpty
unbound-in-mat-substs ube (UBPVar x≠y) MVar =
UBθExtend ube x≠y UBθEmpty
unbound-in-mat-substs (UBInl ube) (UBPInl ubp) (MInl mat) =
unbound-in-mat-substs ube ubp mat
unbound-in-mat-substs (UBInr ube) (UBPInr ubp) (MInr mat) =
unbound-in-mat-substs ube ubp mat
unbound-in-mat-substs ube (UBPPair ubp1 ubp2) (MPair mat1 mat2)
with ube
... | UBPair ube1 ube2 =
substs-concat-unbound-in
(unbound-in-mat-substs ube1 ubp1 mat1)
(unbound-in-mat-substs ube2 ubp2 mat2)
unbound-in-mat-substs ube (UBPPair ubp1 ubp2)
(MNotIntroPair ni mat1 mat2) =
substs-concat-unbound-in
(unbound-in-mat-substs (UBFst ube) ubp1 mat1)
(unbound-in-mat-substs (UBSnd ube) ubp2 mat2)
unbound-in-mat-substs ube UBPWild MWild = UBθEmpty
-- analogues of the above results, but for pattern holes
apart-Δp-hole-unbound-in-p : ∀{u p τ ξ Γp Δp} →
Δp ⊢ p :: τ [ ξ ]⊣ Γp →
u # Δp →
hole-unbound-in-p u p
apart-Δp-hole-unbound-in-p PTUnit u#Δp = HUBPUnit
apart-Δp-hole-unbound-in-p PTNum u#Δp = HUBPNum
apart-Δp-hole-unbound-in-p PTVar u#Δp = HUBPVar
apart-Δp-hole-unbound-in-p (PTInl pt) u#Δp =
HUBPInl (apart-Δp-hole-unbound-in-p pt u#Δp)
apart-Δp-hole-unbound-in-p (PTInr pt) u#Δp =
HUBPInr (apart-Δp-hole-unbound-in-p pt u#Δp)
apart-Δp-hole-unbound-in-p {u = u}
(PTPair Γ1##Γ2 pt1 pt2)
u#Δp =
HUBPPair (apart-Δp-hole-unbound-in-p pt1 u#Δp)
(apart-Δp-hole-unbound-in-p pt2 u#Δp)
apart-Δp-hole-unbound-in-p {u = u}
(PTEHole {w = w} {τ = τ} w∈Δp)
u#Δp =
HUBPEHole λ{refl → abort (some-not-none (! w∈Δp · u#Δp))}
apart-Δp-hole-unbound-in-p {u = u}
(PTHole {w = w} {τ = τ}
w∈Δp pt)
u#Δp =
HUBPHole (λ{refl → abort (some-not-none (! w∈Δp · u#Δp))})
(apart-Δp-hole-unbound-in-p pt u#Δp)
apart-Δp-hole-unbound-in-p PTWild u#Δp = HUBPWild
-- if a term is well-typed, then any free variable must
-- appear in the context. thus, if something is both
-- apart from the typing context and unbound in the expression,
-- it must be fresh in the expression
mutual
binders-fresh-r : ∀{Γ Δ Δp r τ1 ξ τ2 x} →
Γ , Δ , Δp ⊢ r :: τ1 [ ξ ]=> τ2 →
unbound-in-r x r →
x # Γ →
fresh-r x r
binders-fresh-r {Γ = Γ} {x = x}
(RTRule {Γp = Γp} pt Γ##Γp wt)
(UBRule xubp xube) x#Γ =
FRule xubp
(binders-fresh wt xube
(apart-parts Γ Γp x x#Γ
(unbound-in-p-apart-Γp pt xubp)))
binders-fresh-rs : ∀{Γ Δ Δp rs τ1 ξ τ2 x} →
Γ , Δ , Δp ⊢ rs ::s τ1 [ ξ ]=> τ2 →
unbound-in-rs x rs →
x # Γ →
fresh-rs x rs
binders-fresh-rs (RTOneRule rt) (UBRules xubr _) x#Γ =
FRules (binders-fresh-r rt xubr x#Γ) FNoRules
binders-fresh-rs (RTRules rt rst)
(UBRules xubr xubrs) x#Γ =
FRules (binders-fresh-r rt xubr x#Γ)
(binders-fresh-rs rst xubrs x#Γ)
binders-fresh-σ : ∀{Γ Δ Δp σ Γ' x} →
Γ , Δ , Δp ⊢ σ :se: Γ' →
unbound-in-σ x σ →
x # Γ →
fresh-σ x σ
binders-fresh-σ {Γ' = Γ'} {x = x} (STId Γ'⊆Γ) UBσId x#Γ =
FσId x#Γ'
where
x#Γ' : x # Γ'
x#Γ' with Γ' x in Γ'x
... | Some τ =
abort (some-not-none (! (Γ'⊆Γ x τ Γ'x) · x#Γ))
... | None = refl
binders-fresh-σ {Γ = Γ} (STSubst st wt) (UBσSubst ub x≠y ubσ) x#Γ =
FσSubst (binders-fresh wt ub x#Γ)
x≠y
(binders-fresh-σ st ubσ (neq-apart-extend Γ x≠y x#Γ))
binders-fresh-θ : ∀{Γ Δ Δp θ Γ' x} →
Γ , Δ , Δp ⊢ θ :sl: Γ' →
unbound-in-θ x θ →
x # Γ →
fresh-θ x θ
binders-fresh-θ STEmpty ub x#Γ = FθEmpty
binders-fresh-θ (STExtend y#Γ wst wt)
(UBθExtend ubd x≠y ubθ) x#Γ =
FθExtend (binders-fresh wt ubd x#Γ)
x≠y
(binders-fresh-θ wst ubθ x#Γ)
binders-fresh : ∀{Γ Δ Δp e τ x} →
Γ , Δ , Δp ⊢ e :: τ →
unbound-in x e →
x # Γ →
fresh x e
binders-fresh TUnit UBUnit x#Γ = FUnit
binders-fresh TNum UBNum x#Γ = FNum
binders-fresh (TVar {x = y} y∈Γ) UBVar x#Γ =
FVar (λ{ refl → some-not-none ((! y∈Γ) · x#Γ) })
binders-fresh {Γ = Γ} (TLam {x = y} y#Γ wt)
(UBLam x≠y xub) x#Γ =
FLam x≠y (binders-fresh wt xub (neq-apart-extend Γ x≠y x#Γ))
binders-fresh (TAp wt1 wt2) (UBAp ub1 ub2) x#Γ =
FAp (binders-fresh wt1 ub1 x#Γ) (binders-fresh wt2 ub2 x#Γ)
binders-fresh (TInl wt) (UBInl ub) x#Γ =
FInl (binders-fresh wt ub x#Γ)
binders-fresh (TInr wt) (UBInr ub) x#Γ =
FInr (binders-fresh wt ub x#Γ)
binders-fresh (TMatchZPre {r = p => d} wt (RTOneRule rt))
(UBMatch xube (UBZRules UBNoRules
(UBRules ubr _))) x#Γ =
FMatch (binders-fresh wt xube x#Γ)
(FZRules FNoRules
(FRules (binders-fresh-r rt ubr x#Γ)
FNoRules))
binders-fresh (TMatchZPre {r = p => d} wt (RTRules rt rst))
(UBMatch xube (UBZRules _ (UBRules ubr xubrs))) x#Γ =
FMatch (binders-fresh wt xube x#Γ)
(FZRules FNoRules
(FRules (binders-fresh-r rt ubr x#Γ)
(binders-fresh-rs rst xubrs x#Γ)))
binders-fresh (TMatchNZPre wt fin pret (RTOneRule rt) ¬red)
(UBMatch xube
(UBZRules xubpre
(UBRules xubr xubpost))) x#Γ =
FMatch (binders-fresh wt xube x#Γ)
(FZRules (binders-fresh-rs pret xubpre x#Γ)
(FRules (binders-fresh-r rt xubr x#Γ)
FNoRules))
binders-fresh (TMatchNZPre wt fin pret
(RTRules rt postt) ¬red)
(UBMatch xube
(UBZRules xubpre
(UBRules xubr xubpost))) x#Γ =
FMatch (binders-fresh wt xube x#Γ)
(FZRules (binders-fresh-rs pret xubpre x#Γ)
(FRules (binders-fresh-r rt xubr x#Γ)
(binders-fresh-rs postt xubpost x#Γ)))
binders-fresh (TPair wt1 wt2) (UBPair ub1 ub2) x#Γ =
FPair (binders-fresh wt1 ub1 x#Γ)
(binders-fresh wt2 ub2 x#Γ)
binders-fresh (TFst wt) (UBFst ub) x#Γ =
FFst (binders-fresh wt ub x#Γ)
binders-fresh (TSnd wt) (UBSnd ub) x#Γ =
FSnd (binders-fresh wt ub x#Γ)
binders-fresh (TEHole u∈Δ st) (UBEHole ubσ) x#Γ =
FEHole (binders-fresh-σ st ubσ x#Γ)
binders-fresh (THole u∈Δ st wt) (UBHole ubσ ub) x#Γ =
FHole (binders-fresh-σ st ubσ x#Γ) (binders-fresh wt ub x#Γ)
mutual
hole-binders-fresh-r : ∀{Γ Δ Δp r τ1 ξ τ2 u} →
Γ , Δ , Δp ⊢ r :: τ1 [ ξ ]=> τ2 →
hole-unbound-in-r u r →
u # Δ →
hole-fresh-r u r
hole-binders-fresh-r {Δ = Δ} {u = u}
(RTRule {Δp = Δp} pt Γ##Γp wt)
(HUBRule ubp ube) u#Δ =
HFRule ubp
(hole-binders-fresh wt ube u#Δ)
hole-binders-fresh-rs : ∀{Γ Δ Δp rs τ1 ξ τ2 u} →
Γ , Δ , Δp ⊢ rs ::s τ1 [ ξ ]=> τ2 →
hole-unbound-in-rs u rs →
u # Δ →
hole-fresh-rs u rs
hole-binders-fresh-rs (RTOneRule rt) (HUBRules ubr _) u#Δ =
HFRules (hole-binders-fresh-r rt ubr u#Δ) HFNoRules
hole-binders-fresh-rs (RTRules rt rst)
(HUBRules ubr ubrs) u#Δ =
HFRules (hole-binders-fresh-r rt ubr u#Δ)
(hole-binders-fresh-rs rst ubrs u#Δ)
hole-binders-fresh-σ : ∀{Γ Δ Δp σ Γ' u} →
Γ , Δ , Δp ⊢ σ :se: Γ' →
hole-unbound-in-σ u σ →
u # Δ →
hole-fresh-σ u σ
hole-binders-fresh-σ (STId Γ⊆Γ') HUBσId u#Δ = HFσId
hole-binders-fresh-σ (STSubst st wt) (HUBσSubst ub ubσ) u#Δ =
HFσSubst (hole-binders-fresh wt ub u#Δ)
(hole-binders-fresh-σ st ubσ u#Δ)
hole-binders-fresh : ∀{Γ Δ Δp e τ u} →
Γ , Δ , Δp ⊢ e :: τ →
hole-unbound-in u e →
u # Δ →
hole-fresh u e
hole-binders-fresh TUnit HUBUnit u#Δ = HFUnit
hole-binders-fresh TNum HUBNum u#Δ = HFNum
hole-binders-fresh (TVar x∈Γ) HUBVar u#Δ = HFVar
hole-binders-fresh (TLam x#Γ wt) (HUBLam ub) u#Δ =
HFLam (hole-binders-fresh wt ub u#Δ)
hole-binders-fresh (TAp wt1 wt2) (HUBAp ub1 ub2) u#Δ =
HFAp (hole-binders-fresh wt1 ub1 u#Δ)
(hole-binders-fresh wt2 ub2 u#Δ)
hole-binders-fresh (TInl wt) (HUBInl ub) u#Δ =
HFInl (hole-binders-fresh wt ub u#Δ)
hole-binders-fresh (TInr wt) (HUBInr ub) u#Δ =
HFInr (hole-binders-fresh wt ub u#Δ)
hole-binders-fresh (TMatchZPre {r = p => d} wt (RTOneRule rt))
(HUBMatch ube
(HUBZRules HUBNoRules (HUBRules ubr _)))
u#Δ =
HFMatch (hole-binders-fresh wt ube u#Δ)
(HFZRules HFNoRules
(HFRules (hole-binders-fresh-r rt ubr u#Δ)
HFNoRules))
hole-binders-fresh (TMatchZPre {r = p => d} wt
(RTRules rt rst))
(HUBMatch ube (HUBZRules _ (HUBRules ubr ubrs))) u#Δ =
HFMatch (hole-binders-fresh wt ube u#Δ)
(HFZRules HFNoRules
(HFRules (hole-binders-fresh-r rt ubr u#Δ)
(hole-binders-fresh-rs rst ubrs u#Δ)))
hole-binders-fresh (TMatchNZPre wt fin pret
(RTOneRule rt) ¬red)
(HUBMatch ube (HUBZRules ubpre (HUBRules ubr ubpost)))
u#Δ =
HFMatch (hole-binders-fresh wt ube u#Δ)
(HFZRules (hole-binders-fresh-rs pret ubpre u#Δ)
(HFRules (hole-binders-fresh-r rt ubr u#Δ)
HFNoRules))
hole-binders-fresh (TMatchNZPre wt fin pret
(RTRules rt postt) ¬red)
(HUBMatch ube (HUBZRules ubpre (HUBRules ubr ubpost)))
u#Δ =
HFMatch (hole-binders-fresh wt ube u#Δ)
(HFZRules (hole-binders-fresh-rs pret ubpre u#Δ)
(HFRules (hole-binders-fresh-r rt ubr u#Δ)
(hole-binders-fresh-rs postt ubpost u#Δ)))
hole-binders-fresh (TPair wt1 wt2) (HUBPair ub1 ub2) u#Δ =
HFPair (hole-binders-fresh wt1 ub1 u#Δ)
(hole-binders-fresh wt2 ub2 u#Δ)
hole-binders-fresh (TFst wt) (HUBFst ub) u#Δ =
HFFst (hole-binders-fresh wt ub u#Δ)
hole-binders-fresh (TSnd wt) (HUBSnd ub) u#Δ =
HFSnd (hole-binders-fresh wt ub u#Δ)
hole-binders-fresh (TEHole {u = u'} u'∈Δ st) (HUBEHole ubσ) u#Δ =
HFEHole (λ{refl → some-not-none (! u'∈Δ · u#Δ)})
(hole-binders-fresh-σ st ubσ u#Δ)
hole-binders-fresh (THole {u = u'} u'∈Δ st wt)
(HUBHole ubσ ub) u#Δ =
HFHole (λ{refl → some-not-none (! u'∈Δ · u#Δ)})
(hole-binders-fresh-σ st ubσ u#Δ)
(hole-binders-fresh wt ub u#Δ)