-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTerm.lean
More file actions
553 lines (546 loc) · 31.4 KB
/
Term.lean
File metadata and controls
553 lines (546 loc) · 31.4 KB
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
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
import TabularTypes.«F⊗⊕ω».Semantics.Term
import TabularTypes.Lemmas.ClassEnvironment
import TabularTypes.Lemmas.TypeEnvironment
import TabularTypes.Semantics.InstanceEnvironment
import TabularTypes.Semantics.Term
import TabularTypes.Theorems.Type
namespace TabularTypes
open «F⊗⊕ω»
open Std
namespace Term.TypingAndElaboration
instance : Inhabited Monotype where
default := .row [] none
in
instance : Inhabited «Type» where
default := .list [] none
in
theorem to_Kinding (Mte : [[Γᵢ; Γc; Γ ⊢ M : σ ⇝ E]]) (Γᵢw : [[Γc ⊢ Γᵢ]]) (Γcw : [[⊢c Γc]])
(Γwe : [[Γc ⊢ Γ ⇝ Δ]]) : ∃ A, [[Γc; Γ ⊢ σ : * ⇝ A]] := by
induction Mte generalizing Δ with
| var xinΓ => exact Γwe.KindingAndElaboration_of_TermVarIn xinΓ
| lam I _ τ₀ke ih =>
rename TypeEnvironment => Γ
let ⟨x, xnin⟩ := I ++ Γ.termVarDom |>.exists_fresh
let ⟨xninI, xninΓ⟩ := List.not_mem_append'.mp xnin
let ⟨_, τ₁ke⟩ := ih x xninI Γᵢw Γcw <| Γwe.termExt xninΓ τ₀ke
exact ⟨_, τ₀ke.arr <| τ₁ke.TermVar_drop (Γ' := .empty)⟩
| app _ _ ϕih τih =>
let ⟨_, .arr _ τ₁ke⟩ := ϕih Γᵢw Γcw Γwe
exact ⟨_, τ₁ke⟩
| qualI I ψke _ ih =>
rename TypeEnvironment => Γ
let ⟨x, xnin⟩ := I ++ Γ.termVarDom |>.exists_fresh
let ⟨xninI, xninΓ⟩ := List.not_mem_append'.mp xnin
let ⟨_, γke⟩ := ih x xninI Γᵢw Γcw <| Γwe.constrExt xninΓ ψke
exact ⟨_, ψke.qual (γke.Constr_drop (Γ' := .empty))⟩
| qualE _ _ γih =>
let ⟨_, .qual _ γke⟩ := γih Γᵢw Γcw Γwe
exact ⟨_, γke⟩
| schemeI I _ κe ih =>
rename TypeScheme => σ'
rename TypeEnvironment => Γ
let ⟨a, anin⟩ := I ++ Γ.typeVarDom ++ σ'.freeTypeVars |>.exists_fresh
let ⟨aninIΓ, aninσ'⟩ := List.not_mem_append'.mp anin
let ⟨aninI, aninΓ⟩ := List.not_mem_append'.mp aninIΓ
let Γawe := Γwe.typeExt aninΓ κe
let ⟨_, σ'ke⟩ := ih a aninI Γᵢw Γcw Γawe
let Alc := σ'ke.soundness Γcw Γawe .star |>.TypeVarLocallyClosed_of
rw [← Alc.TypeVar_open_TypeVar_close_id (a := a)] at σ'ke
exact ⟨_, .scheme (I ++ ↑a :: Γ.typeVarDom) (by
intro a' a'nin
let ⟨a'ninI, a'ninΓa⟩ := List.not_mem_append'.mp a'nin
let ⟨a'nea, a'ninΓ⟩ := List.not_mem_cons.mp a'ninΓa
let Γa'awe := Γwe.typeExt a'ninΓ κe |>.typeExt (List.not_mem_cons.mpr ⟨a'nea.symm, aninΓ⟩) κe
let σ'ke' := σ'ke.weakening Γa'awe (Γ' := .typeExt .empty ..) (Γ'' := .typeExt .empty ..)
have := σ'ke'.Monotype_open_preservation Γcw Γa'awe nofun aninσ'
Type.not_mem_freeTypeVars_TypeVar_close (.var .head) (Γ' := .empty)
rw [← TypeScheme.TypeVar_open_eq_Monotype_open_var,
← Type.TypeVar_open_eq_Type_open_var] at this
exact this) κe⟩
| schemeE _ τke σih =>
rename TypeEnvironment => Γ
rename TypeScheme => σ'
let ⟨_, σke⟩ := σih Γᵢw Γcw Γwe
let .scheme I σ'opke κ₀e (A := A) := σke
let ⟨a, anin⟩ := Γ.typeVarDom ++ σ'.freeTypeVars ++ ↑A.freeTypeVars ++ I |>.exists_fresh
let ⟨aninΓσ'A, aninI⟩ := List.not_mem_append'.mp anin
let ⟨aninΓσ', aninA⟩ := List.not_mem_append'.mp aninΓσ'A
let ⟨aninΓ, aninσ'⟩ := List.not_mem_append'.mp aninΓσ'
let σ'opke' := σ'opke a aninI
let Γawe := Γwe.typeExt aninΓ κ₀e
exact ⟨_, σ'opke'.Monotype_open_preservation Γcw Γawe nofun aninσ' aninA τke (Γ' := .empty)⟩
| «let» I _ σ₀ke _ _ σ₁ih =>
rename TypeEnvironment => Γ
let ⟨x, xnin⟩ := Γ.termVarDom ++ I |>.exists_fresh
let ⟨xninΓ, xninI⟩ := List.not_mem_append'.mp xnin
let ⟨_, σ₁ke⟩ := σ₁ih _ xninI Γᵢw Γcw <| Γwe.termExt xninΓ σ₀ke
exact ⟨_, σ₁ke.TermVar_drop (Γ' := .empty)⟩
| annot _ ih => exact ih Γᵢw Γcw Γwe
| label => exact ⟨_, .floor .label⟩
| prod _ _ ξih τih =>
let ⟨_, .floor ξke⟩ := ξih Γᵢw Γcw Γwe
let ⟨_, τke⟩ := τih Γᵢw Γcw Γwe
exact ⟨_, .prod .comm (.singleton_row ξke τke)⟩
| sum _ _ ξih τih =>
let ⟨_, .floor ξke⟩ := ξih Γᵢw Γcw Γwe
let ⟨_, τke⟩ := τih Γᵢw Γcw Γwe
exact ⟨_, .sum .comm <| .singleton_row ξke τke⟩
| unlabelProd _ _ prodih _ =>
let ⟨_, .prod μke rowke⟩ := prodih Γᵢw Γcw Γwe
rcases rowke.singleton_row_inversion with ⟨_, _, κeq, _, rfl, τke⟩
cases Kind.row.inj κeq
exact ⟨_, τke⟩
| unlabelSum _ _ _ sumih _ =>
let ⟨_, .sum μke rowke⟩ := sumih Γᵢw Γcw Γwe
rcases rowke.singleton_row_inversion with ⟨_, _, κeq, _, rfl, τke⟩
cases Kind.row.inj κeq
exact ⟨_, τke⟩
| «prj» _ containce prodke =>
let ⟨_, .prod μke ρ₀ke⟩ := prodke Γᵢw Γcw Γwe
let ⟨_, .contain _ ρ₁ke ρ₀ke' _⟩ := containce.to_Kinding Γᵢw Γcw Γwe
let ⟨κeq, _⟩ := ρ₀ke.deterministic ρ₀ke'
cases Kind.row.inj κeq
exact ⟨_, .prod μke ρ₁ke⟩
| concat _ _ concatce prod₀ih =>
let ⟨_, .prod μke ρ₀ke⟩ := prod₀ih Γᵢw Γcw Γwe
let ⟨_, .concat _ ρ₀ke' _ ρ₂ke _ _ _⟩ := concatce.to_Kinding Γᵢw Γcw Γwe
let ⟨κeq, _⟩ := ρ₀ke.deterministic ρ₀ke'
cases Kind.row.inj κeq
exact ⟨_, .prod μke ρ₂ke⟩
| «inj» _ containce sumih =>
let ⟨_, .sum μke ρ₀ke⟩ := sumih Γᵢw Γcw Γwe
let ⟨_, .contain _ ρ₀ke' ρ₁ke _⟩ := containce.to_Kinding Γᵢw Γcw Γwe
let ⟨κeq, _⟩ := ρ₀ke.deterministic ρ₀ke'
cases Kind.row.inj κeq
exact ⟨_, .sum μke ρ₁ke⟩
| elim _ _ concatce τke sum₀ih =>
let ⟨_, .arr (.sum μke ρ₀ke) _⟩ := sum₀ih Γᵢw Γcw Γwe
let ⟨_, .concat _ ρ₀ke' _ ρ₂ke _ _ _⟩ := concatce.to_Kinding Γᵢw Γcw Γwe
let ⟨κeq, _⟩ := ρ₀ke.deterministic ρ₀ke'
cases Kind.row.inj κeq
exact ⟨_, .arr (.sum μke ρ₂ke) τke⟩
| sub _ σ₀₁se ih =>
let ⟨_, σ₀ke⟩ := ih Γᵢw Γcw Γwe
let ⟨_, _, _, σ₀ke', σ₁ke⟩ := σ₀₁se.to_Kinding Γcw Γwe
rcases σ₀ke.deterministic σ₀ke' with ⟨rfl, _⟩
exact ⟨_, σ₁ke⟩
| method γcin TCτce =>
rename TypeEnvironment => Γ
rename Kind => κ
rename TypeScheme => σ'
rename «Type» => A
let ⟨_, .tc γcin' τke⟩ := TCτce.to_Kinding Γᵢw Γcw Γwe
rcases ClassEnvironmentEntry.mk.inj <| γcin.deterministic γcin' rfl with ⟨_, _, rfl, _⟩
let ⟨_, κe, σ'ke, _⟩ := Γcw.In_inversion γcin
let ⟨a, anin⟩ := Γ.typeVarDom ++ σ'.freeTypeVars ++ ↑A.freeTypeVars |>.exists_fresh
let ⟨aninΓσ', aninA⟩ := List.not_mem_append'.mp anin
let ⟨aninΓ, aninσ'⟩ := List.not_mem_append'.mp aninΓσ'
let Γawe := Γwe.typeExt aninΓ κe
rw [← Γ.empty_append] at Γawe
let σ'ke' := σ'ke a |>.weakening Γawe (Γ' := Γ) (Γ'' := .typeExt .empty ..)
rw [TypeEnvironment.empty_append] at Γawe σ'ke'
exact ⟨_, σ'ke'.Monotype_open_preservation Γcw Γawe nofun aninσ' aninA τke (Γ' := .empty)⟩
| «ind» Iₘ Iₛ ρke τke _ _ κe =>
rename TypeEnvironment => Γ
rename Monotype => τ
rename «Type» => B
let ⟨a, anin⟩ := Γ.typeVarDom ++ τ.freeTypeVars ++ ↑B.freeTypeVars ++ Iₘ |>.exists_fresh
let ⟨aninΓτB, aninI⟩ := List.not_mem_append'.mp anin
let ⟨aninΓτ, aninB⟩ := List.not_mem_append'.mp aninΓτB
let ⟨aninΓ, aninτ⟩ := List.not_mem_append'.mp aninΓτ
let Γawe := Γwe.typeExt aninΓ κe.row
let τke' := τke a aninI
rw [← QualifiedType.TypeVar_open, ← TypeScheme.TypeVar_open] at τke'
exact ⟨_, τke'.Monotype_open_preservation Γcw Γawe nofun aninτ aninB ρke (Γ' := .empty)⟩
theorem soundness (Mte : [[Γᵢ; Γc; Γ ⊢ M : σ ⇝ E]]) (σke : [[Γc; Γ ⊢ σ : * ⇝ A]])
(Γᵢw : [[Γc ⊢ Γᵢ]]) (Γcw : [[⊢c Γc]]) (Γwe : [[Γc ⊢ Γ ⇝ Δ]]) : [[Δ ⊢ E : A]] := by
induction Mte generalizing Δ A with
| var xinΓ => exact .var (Γwe.soundness Γcw) <| Γwe.TermVarIn_preservation xinΓ σke
| lam I Mte τ₀ke ih =>
let .arr τ₀ke' τ₁ke := σke
rcases τ₀ke.deterministic τ₀ke' with ⟨_, rfl⟩
rename TypeEnvironment => Γ
apply Typing.lam <| I ++ Γ.termVarDom
intro x xnin
let ⟨xninI, xninΓ⟩ := List.not_mem_append'.mp xnin
let Γxwe := Γwe.termExt xninΓ τ₀ke
let τ₁ke' := τ₁ke.weakening Γxwe (Γ' := .termExt .empty ..) (Γ'' := .empty)
exact ih _ xninI τ₁ke' Γᵢw Γcw Γxwe
| app Mte _ Mih Nih =>
let ⟨_, arrke@(.arr τ₀ke τ₁ke)⟩ := Mte.to_Kinding Γᵢw Γcw Γwe
rcases σke.deterministic τ₁ke with ⟨_, rfl⟩
exact .app (Mih arrke Γᵢw Γcw Γwe) (Nih τ₀ke Γᵢw Γcw Γwe)
| qualI I ψke _ ih =>
let .qual ψke' γke := σke
rcases ψke.deterministic ψke' with ⟨_, rfl⟩
rename TypeEnvironment => Γ
apply Typing.lam <| I ++ Γ.termVarDom
intro x xnin
let ⟨xninI, xninΓ⟩ := List.not_mem_append'.mp xnin
let Γxwe := Γwe.constrExt xninΓ ψke
let γke' := γke.weakening Γxwe (Γ' := .constrExt .empty ..) (Γ'' := .empty)
exact ih _ xninI γke' Γᵢw Γcw Γxwe
| qualE ψce Mte qualih =>
let ⟨_, qualke@(.qual ψke γke)⟩ := Mte.to_Kinding Γᵢw Γcw Γwe
rcases σke.deterministic γke with ⟨_, rfl⟩
exact .app (qualih qualke Γᵢw Γcw Γwe) (ψce.soundness ψke Γᵢw Γcw Γwe)
| schemeI I _ κe ih =>
let .scheme I' σ'ke κe' := σke
cases κe.deterministic κe'
rename TypeEnvironment => Γ
apply Typing.typeLam <| I ++ I' ++ Γ.typeVarDom
intro a anin
let ⟨aninII', aninΓ⟩ := List.not_mem_append'.mp anin
let ⟨aninI, aninI'⟩ := List.not_mem_append'.mp aninII'
exact ih _ aninI (σ'ke _ aninI') Γᵢw Γcw (Γwe.typeExt aninΓ κe)
| schemeE Mte τke ih =>
let ⟨_, schemeke@(.scheme I σ'ke κ₀e)⟩ := Mte.to_Kinding Γᵢw Γcw Γwe
rename TypeEnvironment => Γ
rename TypeScheme => σ'
rename «Type» => A
let ⟨a, anin⟩ := I ++ σ'.freeTypeVars ++ ↑A.freeTypeVars ++ Γ.typeVarDom |>.exists_fresh
let ⟨aninIσ'A, aninΓ⟩ := List.not_mem_append'.mp anin
let ⟨aninIσ', aninA⟩ := List.not_mem_append'.mp aninIσ'A
let ⟨aninI, aninσ'⟩ := List.not_mem_append'.mp aninIσ'
let Γawe := Γwe.typeExt aninΓ κ₀e
let σke' := σ'ke a aninI |>.Monotype_open_preservation Γcw Γawe nofun aninσ' aninA τke
(Γ' := .empty)
rcases σke.deterministic σke' with ⟨_, rfl⟩
exact .typeApp (ih schemeke Γᵢw Γcw Γwe) (τke.soundness Γcw Γwe κ₀e)
| «let» I Mte σ₀ke Nte Mih Nih =>
apply Typing.app _ <| Mih σ₀ke Γᵢw Γcw Γwe
rename TypeEnvironment => Γ
apply Typing.lam <| I ++ Γ.termVarDom
intro x xnin
let ⟨xninI, xninΓ⟩ := List.not_mem_append'.mp xnin
let Γxwe := Γwe.termExt xninΓ σ₀ke
let σ₁ke := σke.weakening Γxwe (Γ' := .termExt .empty ..) (Γ'' := .empty)
exact Nih _ xninI σ₁ke Γᵢw Γcw Γxwe
| annot _ ih => exact ih σke Γᵢw Γcw Γwe
| label =>
let .floor _ := σke
exact .prodIntro' (Γwe.soundness Γcw) (by simp) (.inr rfl) rfl
| prod _ _ _ ih =>
let .prod _ rowke := σke
rcases rowke.singleton_row_inversion with ⟨_, _, κeq, _, rfl, τke⟩
cases Kind.row.inj κeq
exact .singleton <| ih τke Γᵢw Γcw Γwe
| sum _ _ _ ih =>
let .sum _ rowke := σke
rcases rowke.singleton_row_inversion with ⟨_, _, κeq, _, rfl, τke⟩
cases Kind.row.inj κeq
rw [← Range.map_get!_eq (as := [_]), List.length_singleton]
let mem : 0 ∈ [0:1] := ⟨Nat.le.refl, Nat.one_pos, Nat.mod_one _⟩
apply Typing.sumIntro mem (ih τke Γᵢw Γcw Γwe) _ (.inl nofun) (b := false)
intro i mem
let 0 := i
rw [List.get!_cons_zero]
exact τke.soundness Γcw Γwe .star
| unlabelProd Mte _ ih =>
let ⟨_, prodke@(.prod _ rowke)⟩ := Mte.to_Kinding Γᵢw Γcw Γwe
rcases rowke.singleton_row_inversion with ⟨_, _, κeq, _, rfl, τke⟩
cases Kind.row.inj κeq
rcases σke.deterministic τke with ⟨_, rfl⟩
apply Typing.prodElim _ ⟨Nat.le.refl, Nat.one_pos, Nat.mod_one _⟩ (A := fun _ => A) (b := false)
rw [Range.map, Range.toList, if_pos Nat.one_pos, Range.toList, Nat.zero_add,
if_neg (Nat.not_lt_of_le Nat.le.refl), List.map_singleton]
exact ih prodke Γᵢw Γcw Γwe
| unlabelSum Mte _ τke ih =>
let ⟨_, sumke@(.sum _ rowke)⟩ := Mte.to_Kinding Γᵢw Γcw Γwe
rcases rowke.singleton_row_inversion with ⟨_, _, κeq, _, rfl, τke'⟩
cases Kind.row.inj κeq
rcases σke.deterministic τke with ⟨_, rfl⟩
rcases σke.deterministic τke' with ⟨_, rfl⟩
apply Typing.sumElim' (ih sumke Γᵢw Γcw Γwe) _ (τke.soundness Γcw Γwe .star) (b := false) <| by
rw [List.length_singleton, List.length_singleton]
intro _ mem
rw [List.zip_cons_cons, List.zip_nil_left] at mem
cases List.mem_singleton.mp mem
conv => simp_match
exact .id (Γwe.soundness Γcw) <| τke.soundness Γcw Γwe .star
| «prj» Mte containce Mih =>
let ⟨_, prodke@(.prod μke ρ₀ke)⟩ := Mte.to_Kinding Γᵢw Γcw Γwe
apply Typing.app _ <| Mih prodke Γᵢw Γcw Γwe
let .prod _ ρ₁ke := σke
let Fty := containce.soundness (.contain μke ρ₁ke ρ₀ke .star) Γᵢw Γcw Γwe
rw [← Range.map_get!_eq (as := [_, _])] at Fty
let πty := Fty.prodElim ⟨Nat.le.refl, Nat.two_pos, Nat.mod_one _⟩ (b := false)
rw [List.length_cons, List.length_singleton, List.get!_cons_zero] at πty
simp only at πty
have := πty.typeApp .id (B := [[λ a : *. a$0]])
simp [Type.Type_open] at this
rw [ρ₀ke.soundness Γcw Γwe (.row .star) |>.TypeVarLocallyClosed_of.Type_open_id,
ρ₁ke.soundness Γcw Γwe (.row .star) |>.TypeVarLocallyClosed_of.Type_open_id] at this
exact .equiv this <| .arr
(.prod <| .listAppId <| ρ₀ke.soundness Γcw Γwe <| .row .star)
(.prod <| .listAppId <| ρ₁ke.soundness Γcw Γwe <| .row .star)
| concat Mte Nte concatce Mih Nih =>
let ⟨_, prod₀ke⟩ := Mte.to_Kinding Γᵢw Γcw Γwe
let ⟨_, prod₁ke⟩ := Nte.to_Kinding Γᵢw Γcw Γwe
apply Typing.app _ <| Nih prod₁ke Γᵢw Γcw Γwe
apply Typing.app _ <| Mih prod₀ke Γᵢw Γcw Γwe
let .prod μke ρ₀ke := prod₀ke
let .prod _ ρ₁ke := prod₁ke
let .prod _ ρ₂ke := σke
let Fty := concatce.soundness (.concat μke ρ₀ke ρ₁ke ρ₂ke .star (.contain μke ρ₀ke ρ₂ke .star)
(.contain μke ρ₁ke ρ₂ke .star)) Γᵢw Γcw Γwe
rw [← Range.map_get!_eq (as := [_, _, _, _])] at Fty
let πty := Fty.prodElim ⟨Nat.le.refl, Nat.le.refl.step.step.step, Nat.mod_one _⟩ (b := false)
rw [List.length_cons, List.length_cons, List.length_cons, List.length_singleton,
List.get!_cons_zero] at πty
simp only at πty
have := πty.typeApp .id (B := [[λ a : *. a$0]])
simp [Type.Type_open] at this
rw [ρ₀ke.soundness Γcw Γwe (.row .star) |>.TypeVarLocallyClosed_of.Type_open_id,
ρ₁ke.soundness Γcw Γwe (.row .star) |>.TypeVarLocallyClosed_of.Type_open_id,
ρ₂ke.soundness Γcw Γwe (.row .star) |>.TypeVarLocallyClosed_of.Type_open_id] at this
exact .equiv this <| .arr
(.prod <| .listAppId <| ρ₀ke.soundness Γcw Γwe <| .row .star)
(.arr (.prod <| .listAppId <| ρ₁ke.soundness Γcw Γwe <| .row .star)
(.prod <| .listAppId <| ρ₂ke.soundness Γcw Γwe <| .row .star))
| «inj» Mte containce Mih =>
let ⟨_, sumke@(.sum μke ρ₀ke)⟩ := Mte.to_Kinding Γᵢw Γcw Γwe
apply Typing.app _ <| Mih sumke Γᵢw Γcw Γwe
let .sum _ ρ₁ke := σke
let Fty := containce.soundness (.contain μke ρ₀ke ρ₁ke .star) Γᵢw Γcw Γwe
rw [← Range.map_get!_eq (as := [_, _])] at Fty
let πty := Fty.prodElim ⟨Nat.le.refl.step, Nat.le.refl, Nat.mod_one _⟩ (b := false)
rw [List.length_cons, List.length_singleton, List.get!_cons_succ, List.get!_cons_zero] at πty
simp only at πty
have := πty.typeApp .id (B := [[λ a : *. a$0]])
simp [Type.Type_open] at this
rw [ρ₀ke.soundness Γcw Γwe (.row .star) |>.TypeVarLocallyClosed_of.Type_open_id,
ρ₁ke.soundness Γcw Γwe (.row .star) |>.TypeVarLocallyClosed_of.Type_open_id] at this
exact .equiv this <| .arr
(.sum <| .listAppId <| ρ₀ke.soundness Γcw Γwe <| .row .star)
(.sum <| .listAppId <| ρ₁ke.soundness Γcw Γwe <| .row .star)
| elim Mte Nte concatce τke Mih Nih =>
let ⟨_, arr₀ke⟩ := Mte.to_Kinding Γᵢw Γcw Γwe
let ⟨_, arr₁ke⟩ := Nte.to_Kinding Γᵢw Γcw Γwe
apply Typing.app _ <| Nih arr₁ke Γᵢw Γcw Γwe
apply Typing.app _ <| Mih arr₀ke Γᵢw Γcw Γwe
let .arr (.sum μke ρ₀ke) τke' := arr₀ke
rcases τke.deterministic τke' with ⟨_, rfl⟩
let .arr (.sum _ ρ₁ke) τke'' := arr₁ke
rcases τke.deterministic τke'' with ⟨_, rfl⟩
let .arr (.sum _ ρ₂ke) τke''' := σke
rcases τke.deterministic τke''' with ⟨_, rfl⟩
let Fty := concatce.soundness (.concat μke ρ₀ke ρ₁ke ρ₂ke .star (.contain μke ρ₀ke ρ₂ke .star)
(.contain μke ρ₁ke ρ₂ke .star)) Γᵢw Γcw Γwe
rw [← Range.map_get!_eq (as := [_, _, _, _])] at Fty
let πty := Fty.prodElim ⟨Nat.le.refl.step, Nat.le.refl.step.step, Nat.mod_one _⟩ (b := false)
rw [List.length_cons, List.length_cons, List.length_cons, List.length_singleton,
List.get!_cons_succ, List.get!_cons_zero] at πty
simp only at πty
have := πty.typeApp .id (B := [[λ a : *. a$0]])
simp [Type.Type_open] at this
let A₀lc := ρ₀ke.soundness Γcw Γwe (.row .star) |>.TypeVarLocallyClosed_of
let A₁lc := ρ₁ke.soundness Γcw Γwe (.row .star) |>.TypeVarLocallyClosed_of
let A₂lc := ρ₂ke.soundness Γcw Γwe (.row .star) |>.TypeVarLocallyClosed_of
rw [A₀lc.weaken (n := 1).Type_open_id, A₁lc.weaken (n := 1).Type_open_id,
A₂lc.weaken (n := 1).Type_open_id] at this
have := this.typeApp <| τke.soundness Γcw Γwe .star
simp [Type.Type_open] at this
rw [A₀lc.Type_open_id, A₁lc.Type_open_id, A₂lc.Type_open_id] at this
exact .equiv this <| .arr
(.arr (.sum <| .listAppId <| ρ₀ke.soundness Γcw Γwe <| .row .star) .refl) <|
.arr
(.arr (.sum <| .listAppId <| ρ₁ke.soundness Γcw Γwe <| .row .star) .refl) <| .arr
(.sum <| .listAppId <| ρ₂ke.soundness Γcw Γwe <| .row .star) .refl
| sub Mte σse ih =>
let ⟨_, σ₀ke⟩ := Mte.to_Kinding Γᵢw Γcw Γwe
let ⟨_, _, _, σ₀ke', σ₁ke⟩ := σse.to_Kinding Γcw Γwe
rcases σ₀ke.deterministic σ₀ke' with ⟨rfl, rfl⟩
rcases σke.deterministic σ₁ke with ⟨_, rfl⟩
exact .app (σse.soundness Γcw Γwe σ₀ke σ₁ke .star) (ih σ₀ke Γᵢw Γcw Γwe)
| method γcin TCce =>
rename_i A' _ _ _ _ _ _
let ⟨_, TCke@(.tc γcin' τke)⟩ := TCce.to_Kinding Γᵢw Γcw Γwe
rcases ClassEnvironmentEntry.mk.inj <| γcin.deterministic γcin' rfl
with ⟨_, _, rfl, rfl, rfl, rfl⟩
rcases Γcw.In_inversion γcin with ⟨_, κe, σ'ke, Aki, TCₛke, Aₛki⟩
rename TypeEnvironment => Γ
rename TypeScheme => σ'
let ⟨a, anin⟩ := Γ.typeVarDom ++ σ'.freeTypeVars ++ ↑A'.freeTypeVars |>.exists_fresh
let ⟨aninΓσ', aninA'⟩ := List.not_mem_append'.mp anin
let ⟨aninΓ, aninσ'⟩ := List.not_mem_append'.mp aninΓσ'
let Γawe := Γwe.typeExt aninΓ κe
rw [← Γ.empty_append] at Γawe
let σ'ke' := σ'ke a |>.weakening Γawe (Γ'' := .typeExt .empty ..)
rw [TypeEnvironment.empty_append] at Γawe σ'ke'
let σke' := σ'ke'.Monotype_open_preservation Γcw Γawe nofun aninσ' aninA' τke (Γ' := .empty)
rcases σke.deterministic σke' with ⟨_, rfl⟩
let Ety := TCce.soundness TCke Γᵢw Γcw Γwe
rw [← Range.map_get!_eq (as := _ :: _)] at Ety
let πty := Ety.prodElim
⟨Nat.le.refl, by rw [List.length_cons]; exact Nat.succ_pos _, Nat.mod_one _⟩ (b := false)
rw [List.length_cons, List.length_map, Range.length_toList, Nat.sub_zero,
List.get!_cons_zero] at πty
simp only at πty
exact πty
| «ind» Iₘ Iₛ ρke τke Mte Nte κe indce Mih Nih =>
rename_i Γc Γ ρ κ τ B K _ _ _ _ _ _
let ⟨a, anin⟩ := Γ.typeVarDom ++ τ.freeTypeVars ++ ↑B.freeTypeVars ++ Iₘ |>.exists_fresh
let ⟨aninΓτB, aninI⟩ := List.not_mem_append'.mp anin
let ⟨aninΓτ, aninB⟩ := List.not_mem_append'.mp aninΓτB
let ⟨aninΓ, aninτ⟩ := List.not_mem_append'.mp aninΓτ
let Γawe := Γwe.typeExt aninΓ κe.row
let τke' := τke _ aninI
rw [← QualifiedType.TypeVar_open, ← TypeScheme.TypeVar_open] at τke'
let τopρke := τke'.Monotype_open_preservation Γcw Γawe nofun aninτ aninB ρke (Γ' := .empty)
rcases τopρke.deterministic σke with ⟨_, rfl⟩
let τopemptyke := τke'.Monotype_open_preservation Γcw Γawe nofun aninτ aninB (Γ' := .empty)
<| .empty_row κe
apply Typing.app _ <| Nih τopemptyke Γᵢw Γcw Γwe
let ⟨_, indke@(.ind I₀ I₁ ρke' κe' keBₗ keBᵣ)⟩ := indce.to_Kinding Γᵢw Γcw Γwe
rename_i Bₗ Bᵣ _ _ _
rcases ρke.deterministic ρke' with ⟨κeq, rfl⟩
cases Kind.row.inj κeq
cases κe.deterministic κe'
let Fty := indce.soundness indke Γᵢw Γcw Γwe
have := Fty.typeApp <| .lam (Iₘ ++ Γ.typeVarDom) fun a anin =>
let ⟨aninI, aninΓ⟩ := List.not_mem_append'.mp anin
τke a aninI |>.soundness Γcw (Γwe.typeExt aninΓ κe.row) .star
simp [Type.Type_open] at this
rw [ρke.soundness Γcw Γwe κe.row |>.TypeVarLocallyClosed_of.Type_open_id] at this
apply Typing.app <| this.equiv <| .arr .refl <| .arr (.lamApp (.lam (Iₘ ++ Γ.typeVarDom) (by
intro a anin
let ⟨aninIₘ, aninΓ⟩ := List.not_mem_append'.mp anin
exact τke a aninIₘ |>.soundness Γcw (Γwe.typeExt aninΓ κe.row) .star
)) .empty_list) <| .lamApp (.lam (Iₘ ++ Γ.typeVarDom) (by
intro a anin
let ⟨aninIₘ, aninΓ⟩ := List.not_mem_append'.mp anin
exact τke a aninIₘ |>.soundness Γcw (Γwe.typeExt aninΓ κe.row) .star
)) <| ρke'.soundness Γcw Γwe κe.row
apply Typing.typeLam <| Γ.typeVarDom ++ I₀ ++ Iₛ
intro aₗ aₗnin
let ⟨aₗninΓI₀, aₗninIₛ⟩ := List.not_mem_append'.mp aₗnin
let ⟨aₗninΓ, aₗninI₀⟩ := List.not_mem_append'.mp aₗninΓI₀
simp [«F⊗⊕ω».Term.TypeVar_open, Type.TypeVar_open]
apply Typing.typeLam <| ↑aₗ :: Γ.typeVarDom ++ ↑aₗ :: I₀ ++ ↑aₗ :: Iₛ
intro aₜ aₜnin
let ⟨aₜninΓI₀, aₜninIₛ⟩ := List.not_mem_append'.mp aₜnin
let ⟨aₜninΓ, aₜninI₀⟩ := List.not_mem_append'.mp aₜninΓI₀
simp [«F⊗⊕ω».Term.TypeVar_open, Type.TypeVar_open]
apply Typing.typeLam <| ↑aₜ :: ↑aₗ :: Γ.typeVarDom ++ ↑aₜ :: ↑aₗ :: I₀ ++ Iₘ ++ ↑aₜ :: ↑aₗ :: Iₛ
intro aₚ aₚnin
let ⟨aₚninΓI₀ₘ, aₚninIₛ⟩ := List.not_mem_append'.mp aₚnin
let ⟨aₚninΓI₀, aₚninIₘ⟩ := List.not_mem_append'.mp aₚninΓI₀ₘ
let ⟨aₚninΓ, aₚninI₀⟩ := List.not_mem_append'.mp aₚninΓI₀
simp [«F⊗⊕ω».Term.TypeVar_open, Type.TypeVar_open]
apply Typing.typeLam <| ↑aₚ :: ↑aₜ :: ↑aₗ :: Γ.typeVarDom ++ Γ.typeVarDom ++
↑aₚ :: ↑aₜ :: ↑aₗ :: I₀ ++ I₁ ++ Iₘ ++ ↑aₚ :: ↑aₜ :: ↑aₗ :: Iₛ
intro aᵢ aᵢnin
let ⟨aᵢninΓΓ'I₀₁ₘ, aᵢninIₛ⟩ := List.not_mem_append'.mp aᵢnin
let ⟨aᵢninΓΓ'I₀₁, aᵢninIₘ⟩ := List.not_mem_append'.mp aᵢninΓΓ'I₀₁ₘ
let ⟨aᵢninΓΓ'I₀, aᵢninI₁⟩ := List.not_mem_append'.mp aᵢninΓΓ'I₀₁
let ⟨aᵢninΓΓ', aᵢninI₀⟩ := List.not_mem_append'.mp aᵢninΓΓ'I₀
let ⟨aᵢninΓ, aᵢninΓ'⟩ := List.not_mem_append'.mp aᵢninΓΓ'
simp [«F⊗⊕ω».Term.TypeVar_open, Type.TypeVar_open]
apply Typing.typeLam <| ↑aᵢ :: ↑aₚ :: ↑aₜ :: ↑aₗ :: Γ.typeVarDom ++ ↑aᵢ :: Γ.typeVarDom ++
↑aᵢ :: I₁ ++ ↑aᵢ :: ↑aₚ :: ↑aₜ :: ↑aₗ :: Iₛ
intro aₙ aₙnin
let ⟨aₙninΓΓ'I₁, aₙninIₛ⟩ := List.not_mem_append'.mp aₙnin
let ⟨aₙninΓΓ', aₙninI₁⟩ := List.not_mem_append'.mp aₙninΓΓ'I₁
let ⟨aₙninΓ, aₙninΓ'⟩ := List.not_mem_append'.mp aₙninΓΓ'
simp [«F⊗⊕ω».Term.TypeVar_open, Type.TypeVar_open]
let Γaₗₜₚᵢwe := Γwe.typeExt aₗninΓ .label |>.typeExt aₜninΓ κe |>.typeExt aₚninΓ κe.row
|>.typeExt aᵢninΓ κe.row
let Γaₗₜₚᵢₙwe := Γaₗₜₚᵢwe.typeExt aₙninΓ κe.row
let aₚneaᵢ := List.ne_of_not_mem_cons aᵢninΓ
let aₚneaₙ := List.ne_of_not_mem_cons <| List.not_mem_of_not_mem_cons aₙninΓ
let aᵢneaₙ := List.ne_of_not_mem_cons aₙninΓ
symm at aₚneaᵢ aₚneaₙ aᵢneaₙ
apply Typing.equiv _ <| .arr .refl <| .arr .refl <| .arr .refl <| .arr
(.symm <| .lamApp (.lam
((aₙ :: aᵢ :: aₚ :: aₜ :: aₗ :: Δ.typeVarDom) ++ B.freeTypeVars ++ ↑Iₘ ++ ↑Γ.typeVarDom) (by
intro a anin
let ⟨aninΔBIₘ, aninΓ⟩ := List.not_mem_append'.mp anin
let ⟨aninΔB, aninIₘ⟩ := List.not_mem_append'.mp aninΔBIₘ
let ⟨aninΔ, aninB⟩ := List.not_mem_append'.mp aninΔB
let Bki := τke a aninIₘ |>.soundness Γcw (Γwe.typeExt aninΓ κe.row) .star
let Blc := Bki.TypeVarLocallyClosed_of.TypeVar_close_inc (a := a)
rw [Type.TypeVar_close_TypeVar_open_eq_of_not_mem_freeTypeVars aninB] at Blc
rw [Blc.weaken (n := 4).TypeVar_open_id, Blc.weaken (n := 3).TypeVar_open_id,
Blc.weaken (n := 2).TypeVar_open_id, Blc.weaken (n := 1).TypeVar_open_id,
Blc.TypeVar_open_id]
exact Bki.weakening (Γaₗₜₚᵢₙwe.soundness Γcw |>.typeVarExt aninΔ) (Δ'' := .typeExt .empty ..)
(Δ' := .typeExt (.typeExt (.typeExt (.typeExt (.typeExt .empty ..) ..) ..) ..) ..)
)) <| .var <| .typeVarExt (.typeVarExt .head aₚneaᵢ) aₚneaₙ)
(.symm <| .lamApp (.lam
((aₙ :: aᵢ :: aₚ :: aₜ :: aₗ :: Δ.typeVarDom) ++ B.freeTypeVars ++ ↑Iₘ ++ ↑Γ.typeVarDom) (by
intro a anin
let ⟨aninΔBIₘ, aninΓ⟩ := List.not_mem_append'.mp anin
let ⟨aninΔB, aninIₘ⟩ := List.not_mem_append'.mp aninΔBIₘ
let ⟨aninΔ, aninB⟩ := List.not_mem_append'.mp aninΔB
let Bki := τke a aninIₘ |>.soundness Γcw (Γwe.typeExt aninΓ κe.row) .star
let Blc := Bki.TypeVarLocallyClosed_of.TypeVar_close_inc (a := a)
rw [Type.TypeVar_close_TypeVar_open_eq_of_not_mem_freeTypeVars aninB] at Blc
rw [Blc.weaken (n := 4).TypeVar_open_id, Blc.weaken (n := 3).TypeVar_open_id,
Blc.weaken (n := 2).TypeVar_open_id, Blc.weaken (n := 1).TypeVar_open_id,
Blc.TypeVar_open_id]
exact Bki.weakening (Γaₗₜₚᵢₙwe.soundness Γcw |>.typeVarExt aninΔ) (Δ'' := .typeExt .empty ..)
(Δ' := .typeExt (.typeExt (.typeExt (.typeExt (.typeExt .empty ..) ..) ..) ..) ..)
)) <| .var <| .typeVarExt .head aᵢneaₙ)
apply Mih _ aₗninIₛ _ aₜninIₛ _ aₚninIₛ _ aᵢninIₛ _ aₙninIₛ _ Γᵢw Γcw Γaₗₜₚᵢₙwe
open TypeScheme.KindingAndElaboration in
let keBₗ' := keBₗ _ aₗninI₀ _ aₜninI₀ _ aₚninI₀ _ aᵢninI₀
let Γaₗₜₚwe := Γwe.typeExt aₗninΓ .label |>.typeExt aₜninΓ κe |>.typeExt aₚninΓ κe.row
let Γaₗₜₚᵢwe := Γaₗₜₚwe.typeExt aᵢninΓ κe.row
let Γaₗₜₚᵢₙwe := Γaₗₜₚᵢwe.typeExt aₙninΓ κe.row
let Bₗlc := keBₗ'.soundness Γcw Γaₗₜₚᵢwe .constr |>.TypeVarLocallyClosed_of.weaken (n := 5)
|>.TypeVar_open_drop Nat.le.refl.step.step.step
|>.TypeVar_open_drop Nat.le.refl.step.step
|>.TypeVar_open_drop Nat.le.refl.step
|>.TypeVar_open_drop Nat.le.refl
let keBᵣ' := keBᵣ _ aᵢninI₁ _ aₙninI₁
let Γaᵢₙwe := Γwe.typeExt aᵢninΓ' κe.row |>.typeExt aₙninΓ' κe.row
let Bᵣlc := keBᵣ'.soundness Γcw Γaᵢₙwe .constr |>.TypeVarLocallyClosed_of.weaken (n := 2)
|>.TypeVar_open_drop Nat.le.refl.step
|>.TypeVar_open_drop Nat.le.refl
rw [Bₗlc.Type_open_id, Bᵣlc.weaken (n := 3).Type_open_id] at this ⊢
rw [Bᵣlc.weaken (n := 2).TypeVar_open_id, Bᵣlc.weaken (n := 1).TypeVar_open_id,
Bᵣlc.TypeVar_open_id]
let keBₗ'' := keBₗ'.weakening Γaₗₜₚᵢₙwe (Γ' := .typeExt .empty ..) (Γ'' := .empty)
rw [keBₗ''.soundness Γcw Γaₗₜₚᵢₙwe .constr |>.TypeVarLocallyClosed_of.TypeVar_open_id]
apply qual keBₗ''
let keBᵣ'' := keBᵣ'.weakening Γaₗₜₚᵢₙwe (Γ' := .typeExt (.typeExt (.typeExt .empty ..) ..) ..)
(Γ'' := .typeExt (.typeExt .empty ..) ..)
let .qual (.mono ρlc) := ρke.TypeVarLocallyClosed_of
apply qual keBᵣ''
let aₗneaₙ := List.ne_of_not_mem_cons <| List.not_mem_of_not_mem_cons <|
List.not_mem_of_not_mem_cons <| List.not_mem_of_not_mem_cons aₙninΓ
let aₗneaᵢ := List.ne_of_not_mem_cons <| List.not_mem_of_not_mem_cons <|
List.not_mem_of_not_mem_cons aᵢninΓ
let aₗneaₚ := List.ne_of_not_mem_cons <| List.not_mem_of_not_mem_cons aₚninΓ
let aₗneaₜ := List.ne_of_not_mem_cons aₜninΓ
symm at aₗneaₙ aₗneaᵢ aₗneaₚ aₗneaₜ
apply arr <| floor <| .var <| .typeExt aₗneaₙ <| .typeExt aₗneaᵢ <| .typeExt aₗneaₚ <|
.typeExt aₗneaₜ .head
rw [← Type.TypeVar_open_eq_Type_open_var, ← Type.TypeVar_open_eq_Type_open_var,
Type.TypeVar_open_comm _ Nat.one_ne_zero (m := 1) (n := 0),
Type.TypeVar_open_comm _ Nat.one_ne_zero (m := 1) (n := 0),
Type.TypeVar_open_comm _ (Nat.succ_ne_zero _) (m := 2) (n := 0),
Type.TypeVar_open_comm _ (Nat.succ_ne_zero _) (m := 2) (n := 0),
Type.TypeVar_open_comm _ (Nat.succ_ne_zero _) (m := 3) (n := 0),
Type.TypeVar_open_comm _ (Nat.succ_ne_zero _) (m := 3) (n := 0),
Type.TypeVar_open_comm _ (Nat.succ_ne_zero _) (m := 4) (n := 0),
Type.TypeVar_open_comm _ (Nat.succ_ne_zero _) (m := 4) (n := 0),
Type.TypeVar_open_comm _ (Nat.succ_ne_zero _) (m := 5) (n := 0),
Type.TypeVar_open_comm _ (Nat.succ_ne_zero _) (m := 5) (n := 0)]
let τopaₚke := τke _ aₚninIₘ
|>.weakening Γaₗₜₚwe (Γ' := .typeExt (.typeExt .empty ..) ..) (Γ'' := .typeExt .empty ..)
|>.weakening Γaₗₜₚᵢₙwe (Γ' := .typeExt (.typeExt .empty ..) ..) (Γ'' := .empty)
let Bopaₚlc := τopaₚke.soundness Γcw Γaₗₜₚᵢₙwe .star |>.TypeVarLocallyClosed_of
let τopaᵢke := τke _ aᵢninIₘ
|>.weakening Γaₗₜₚᵢwe (Γ' := .typeExt (.typeExt (.typeExt .empty ..) ..) ..) (Γ'' := .typeExt .empty ..)
|>.weakening Γaₗₜₚᵢₙwe (Γ' := .typeExt .empty ..) (Γ'' := .empty)
let Bopaᵢlc := τopaᵢke.soundness Γcw Γaₗₜₚᵢₙwe .star |>.TypeVarLocallyClosed_of
rw [Bopaₚlc.weaken (n := 5).TypeVar_open_id, Bopaₚlc.weaken (n := 4).TypeVar_open_id,
Bopaₚlc.weaken (n := 3).TypeVar_open_id, Bopaₚlc.weaken (n := 2).TypeVar_open_id,
Bopaₚlc.weaken (n := 1).TypeVar_open_id, Bopaᵢlc.weaken (n := 5).TypeVar_open_id,
Bopaᵢlc.weaken (n := 4).TypeVar_open_id, Bopaᵢlc.weaken (n := 3).TypeVar_open_id,
Bopaᵢlc.weaken (n := 2).TypeVar_open_id, Bopaᵢlc.weaken (n := 1).TypeVar_open_id]
exact arr τopaₚke τopaᵢke
end Term.TypingAndElaboration
end TabularTypes