Skip to content

Commit 01a58ba

Browse files
committed
finished proof, no sorries left, but the proofs are still messy
1 parent 22eed13 commit 01a58ba

4 files changed

Lines changed: 134 additions & 58 deletions

File tree

Cslib/Languages/LambdaCalculus/LocallyNameless/Stlc/StrongNorm.lean

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -153,16 +153,6 @@ lemma multi_app_lc : ∀ {M P : Term Var} {Ns : List (Term Var)},
153153
cases lc_Ns
154154
grind
155155

156-
theorem lcAt_openRec_lcAt (M N : Term Var) (i : ℕ) :
157-
LcAt i (M⟦i ↝ N⟧) → LcAt (i + 1) M := by
158-
induction M generalizing i <;> try grind
159-
160-
lemma open_abs_lc : forall {M N : Term Var},
161-
LC (M ^ N) → LC (M.abs) := by
162-
intro M N hlc
163-
rw[←lcAt_iff_LC]
164-
rw[←lcAt_iff_LC] at hlc
165-
apply lcAt_openRec_lcAt _ _ _ hlc
166156

167157

168158
def semanticMap_saturated (τ : Ty Base) :

Cslib/Languages/LambdaCalculus/LocallyNameless/Untyped/FullBeta.lean

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,10 @@ lemma redex_subst_cong_lc (s s' t : Term Var) (x : Var) (step : s ⭢βᶠ s') (
102102

103103

104104

105+
106+
107+
108+
105109
/-- Abstracting then closing preserves a single reduction. -/
106110
lemma step_abs_close {x : Var} (step : M ⭢βᶠ M') : M⟦0 ↜ x⟧.abs ⭢βᶠ M'⟦0 ↜ x⟧.abs := by
107111
grind [abs ∅, redex_subst_cong]
@@ -127,6 +131,59 @@ theorem redex_abs_cong (xs : Finset Var) (cofin : ∀ x ∉ xs, (M ^ fvar x) ↠
127131
rw [open_close fresh M 0 ?_, open_close fresh M' 0 ?_]
128132
all_goals grind [redex_abs_close]
129133

134+
theorem redex_abs_fvar_finset_exists (xs : Finset Var)
135+
(M M' : Term Var)
136+
(step : M.abs ⭢βᶠ M'.abs) :
137+
∃ (L : Finset Var), ∀ x ∉ L, (M ^ fvar x) ⭢βᶠ (M' ^ fvar x) := by
138+
cases step
139+
case abs L cofin => exists L
140+
141+
142+
lemma step_open_cong1 (s s' t : Term Var) (L : Finset Var)
143+
(step : ∀ x ∉ L, (s ^ (fvar x)) ⭢βᶠ (s' ^ (fvar x))) (h_lc : LC t) :
144+
(s ^ t) ⭢βᶠ (s' ^ t) := by
145+
let x := fresh (L ∪ s.fv ∪ s'.fv)
146+
have H : x ∉ (L ∪ s.fv ∪ s'.fv) := fresh_notMem (L ∪ s.fv ∪ s'.fv)
147+
rw[subst_intro x t s, subst_intro x t s'] <;> simp_all[redex_subst_cong_lc]
148+
149+
lemma invert_steps_abs {s t : Term Var} (step : s.abs ↠βᶠ t) :
150+
∃ (s' : Term Var), s.abs ↠βᶠ s'.abs ∧ t = s'.abs := by
151+
induction step
152+
· case refl => aesop
153+
· case tail steps step ih =>
154+
match ih with
155+
| ⟨ s', step_s, eq⟩ =>
156+
rw[eq] at step
157+
cases step
158+
· case abs s'' L step =>
159+
apply step_abs_cong at step
160+
grind
161+
162+
lemma steps_open_cong_abs (s s' t : Term Var)
163+
(steps : s.abs↠βᶠ s'.abs) (lc_s : LC s.abs) (lc_t : LC t) :
164+
(s ^ t) ↠βᶠ (s' ^ t) := by
165+
generalize eq : s.abs = s_abs at steps
166+
generalize eq' : s'.abs = s'_abs at steps
167+
revert s s'
168+
induction steps
169+
· case refl => grind
170+
· case tail steps step ih =>
171+
intro s s'' lc_sabs eq1 eq2
172+
rw[←eq1] at steps
173+
match (invert_steps_abs steps) with
174+
| ⟨s', step_s, eq⟩ =>
175+
specialize (ih s s' lc_sabs eq1 eq.symm)
176+
transitivity
177+
· apply ih
178+
· rw[eq,←eq2] at step
179+
apply Relation.ReflTransGen.single
180+
have ⟨ L, cofin⟩ := redex_abs_fvar_finset_exists (free_union [fv] Var) s' s'' step
181+
apply step_open_cong1
182+
· assumption
183+
· assumption
184+
185+
186+
130187
end LambdaCalculus.LocallyNameless.Untyped.Term.FullBeta
131188

132189
end Cslib

Cslib/Languages/LambdaCalculus/LocallyNameless/Untyped/Properties.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ theorem subst_lc {x : Var} {e u : Term Var} (e_lc : LC e) (u_lc : LC u) : LC (e
103103
case' abs => apply LC.abs (free_union Var)
104104
all_goals grind
105105

106+
106107
/-- Opening to a term `t` is equivalent to opening to a free variable and substituting for `t`. -/
107108
lemma subst_intro (x : Var) (t e : Term Var) (mem : x ∉ e.fv) (t_lc : LC t) :
108109
e ^ t = (e ^ fvar x) [ x := t ] := by grind [subst_fresh]

Cslib/Languages/LambdaCalculus/LocallyNameless/Untyped/StrongNorm.lean

Lines changed: 76 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
module
22

33
public import Cslib.Languages.LambdaCalculus.LocallyNameless.Untyped.FullBeta
4+
public import Cslib.Languages.LambdaCalculus.LocallyNameless.Untyped.LcAt
45

56
public section
67

@@ -15,6 +16,8 @@ namespace LambdaCalculus.LocallyNameless.Untyped.Term
1516

1617
attribute [grind =] Finset.union_singleton
1718

19+
20+
1821
lemma steps_lc_l [DecidableEq Var] [HasFresh Var] {M M' : Term Var} (steps : M ↠βᶠ M') (lc_M : LC M) : LC M' := by
1922
induction steps <;> grind[FullBeta.step_lc_r]
2023

@@ -42,6 +45,7 @@ inductive multi_app_full_beta : List (Term Var) → List (Term Var) → Prop whe
4245

4346

4447

48+
4549
lemma multi_app_step_lc_r [DecidableEq Var] [HasFresh Var]
4650
{Ns Ns' : List (Term Var)} (step : Ns ⭢βᶠ Ns') : (∀ N ∈ Ns', LC N) := by
4751
induction step <;> grind[FullBeta.step_lc_r]
@@ -303,87 +307,109 @@ lemma neutral_sn {t : Term Var} (Hneut : neutral t) : SN t := by
303307
have H_neut := neutral_mst t'_neut hstep1
304308
contradiction
305309

306-
lemma redex_open_cong_lc (s s' t : Term Var) (step : s.abs ⭢βᶠ s'.abs) (h_lc : LC t) :
307-
(s ^ t) ⭢βᶠ (s' ^ t) := by sorry
308-
309-
lemma abs_sn : ∀ {M N : Term Var},
310-
SN (M ^ N) → SN (Term.abs M) := by
311-
intro M N sn_M
310+
lemma abs_sn [DecidableEq Var] [HasFresh Var] : ∀ {M N : Term Var},
311+
SN (M ^ N) → LC N → SN (Term.abs M) := by
312+
intro M N sn_M lc_N
312313
generalize h : (M ^ N) = M_open at sn_M
313314
revert N M
314315
induction sn_M with
315316
| sn M_open h_sn ih =>
316-
intro M N h
317+
intro M N lc_N h
317318
constructor
318319
intro M' h_step
319320
cases h_step with
320321
| @abs h_M_red M' L H =>
321322
specialize ih (M' ^ N)
322323
rw[←h] at ih
323324
apply ih
324-
· apply redex_open_cong_lc <;> try assumption
325-
· sorry
326-
· sorry
325+
· apply FullBeta.step_open_cong1 <;> assumption
326+
· assumption
327327
· rfl
328328

329-
/-- Substitution respects a single reduction step. -/
330-
lemma redex_subst_cong_lc (s s' t : Term Var) (x : Var) (step : s ⭢βᶠ s') (h_lc : LC t) :
331-
s [ x := t ] ⭢βᶠ s' [ x := t ] := by
329+
lemma step_subst_cong2 [DecidableEq Var] [HasFresh Var] {x : Var} (s t t' : Term Var) (step : t ⭢βᶠ t') (h_lc : LC s) :
330+
(s [ x := t ]) ↠βᶠ (s [ x := t' ]) := by
331+
induction h_lc
332+
· case fvar y =>
333+
rw[Term.subst_fvar, Term.subst_fvar]
334+
grind
335+
· case abs L N h_lc ih =>
336+
simp[subst_abs]
337+
apply FullBeta.redex_abs_cong (L ∪ {x})
338+
intro y h_fresh
339+
rw[←Term.subst_open_var, ←Term.subst_open_var] <;> try grind[FullBeta.step_lc_r, FullBeta.step_lc_l]
340+
· case app l r ih_l ih_r =>
341+
transitivity
342+
· apply FullBeta.redex_app_r_cong
343+
· apply ih_r
344+
· grind[Term.subst_lc, FullBeta.step_lc_l]
345+
· apply FullBeta.redex_app_l_cong
346+
· apply ih_l
347+
· grind[Term.subst_lc, FullBeta.step_lc_r]
348+
349+
lemma steps_subst_cong2 [DecidableEq Var] [HasFresh Var] {x : Var} (s t t' : Term Var) (step : t ↠βᶠ t') (h_lc : LC s) :
350+
(s [ x := t ]) ↠βᶠ (s [ x := t' ]) := by
332351
induction step
333-
case beta m n abs_lc n_lc =>
334-
cases abs_lc with | abs xs _ mem =>
335-
rw [subst_open x t n m (by grind)]
336-
refine beta ?_ (by grind)
337-
exact subst_lc (LC.abs xs m mem) h_lc
338-
case abs => grind [abs <| free_union Var]
339-
all_goals grind
340-
341-
342-
lemma step_open [DecidableEq Var] [HasFresh Var] : ∀ {M M' N : Term Var},
343-
LC N →
344-
M.abs ⭢βᶠ M'.abs →
345-
(M ^ N) ⭢βᶠ (M' ^ N) := by
346-
intro M M' N lc_N h_step
347-
cases h_step
348-
· case abs L h_step =>
349-
let x := fresh (L ∪ M.fv ∪ M'.fv ∪ N.fv)
350-
have x_fresh : x ∉ L ∪ M.fv ∪ M'.fv ∪ N.fv := by apply fresh_notMem
351-
specialize h_step x (by simp_all)
352-
rw[subst_intro x _ M (by simp_all) lc_N]
353-
rw[subst_intro x _ M' (by simp_all) lc_N]
354-
apply FullBeta.redex_subst_cong_lc
355-
· assumption
356-
assumption
357-
352+
· case refl => rfl
353+
· case tail t' t'' steps step ih =>
354+
transitivity
355+
· apply ih
356+
· apply step_subst_cong2 <;> assumption
357+
358+
lemma steps_open_cong_abs [DecidableEq Var] [HasFresh Var] (s s' t t' : Term Var)
359+
(step1 : t ↠βᶠ t')
360+
(step2 : s.abs ↠βᶠ s'.abs)
361+
(lc_t : LC t)
362+
(lc_s : LC s.abs) :
363+
(s ^ t) ↠βᶠ (s' ^ t') := by
364+
have lcsabs := lc_s
365+
cases lc_s
366+
· case abs _ L h_lc =>
367+
let x := fresh (L ∪ s.fv ∪ s'.fv ∪ t.fv ∪ t'.fv)
368+
have H : x ∉ (L ∪ s.fv ∪ s'.fv ∪ t.fv ∪ t'.fv) := fresh_notMem _
369+
rw[subst_intro x t s, subst_intro x t' s'] <;> try grind[steps_lc]
370+
· transitivity
371+
· apply steps_subst_cong2
372+
· assumption
373+
· grind
374+
· rw[←subst_intro, ←subst_intro] <;> try grind[steps_lc]
375+
apply FullBeta.steps_open_cong_abs <;> try grind[steps_lc]
358376

377+
theorem lcAt_openRec_lcAt (M N : Term Var) (i : ℕ) :
378+
LcAt i (M⟦i ↝ N⟧) → LcAt (i + 1) M := by
379+
induction M generalizing i <;> try grind
359380

381+
lemma open_abs_lc [HasFresh Var] : forall {M N : Term Var},
382+
LC (M ^ N) → LC (M.abs) := by
383+
intro M N hlc
384+
rw[←lcAt_iff_LC]
385+
rw[←lcAt_iff_LC] at hlc
386+
apply lcAt_openRec_lcAt _ _ _ hlc
360387

361-
lemma redex_open_cong_lc' (s s' t t' : Term Var) (step1 : t ↠βᶠ t') (step2 : s.abs ↠βᶠ s'.abs) (h_lc : LC t) :
362-
(s ^ t) ↠βᶠ (s' ^ t') := by sorry
363388

364389
lemma multi_app_sn [DecidableEq Var] [HasFresh Var] : ∀ {Ps} {M N : Term Var},
365390
SN N →
366391
SN (multi_app (M ^ N) Ps) →
392+
LC N →
367393
LC (multi_app (M ^ N) Ps) →
368394
-------------------------------------
369395
SN (multi_app ((Term.abs M).app N) Ps) := by
370396
intro P
371-
induction P <;> intros M N sn_N sn_MNPs lc_MNPs
397+
induction P <;> intros M N sn_N sn_MNPs lc_N lc_MNPs
372398
· case nil =>
373399
apply sn_app
374400
· apply abs_sn at sn_MNPs
375-
assumption
401+
simp_all
376402
· assumption
377403
· intro M' N' hstep1 hstep2
378404
rw[multi_app] at sn_MNPs
379405
have Hmst : (M ^ N) ↠βᶠ (M' ^ N') := by
380-
apply redex_open_cong_lc' <;> try assumption
381-
· sorry
406+
apply steps_open_cong_abs <;> try assumption
407+
simp_all
408+
apply open_abs_lc <;> assumption
382409
apply sn_mst <;> assumption
383410
· case cons P Ps ih =>
384411
apply sn_app
385-
· apply ih
386-
· assumption
412+
· apply ih <;> try assumption
387413
· apply sn_app_left at sn_MNPs <;> grind[multi_app_lc]
388414
· grind[multi_app_lc]
389415
· apply sn_app_right at sn_MNPs
@@ -404,8 +430,10 @@ lemma multi_app_sn [DecidableEq Var] [HasFresh Var] : ∀ {Ps} {M N : Term Var},
404430
· rw[multi_app_lc] at lc_MNPs
405431
simp_all
406432
· apply steps_multi_app_l
407-
· apply redex_open_cong_lc' <;> try assumption
408-
· sorry
433+
· rw[multi_app_lc] at lc_MNPs
434+
apply steps_open_cong_abs M M' N N' <;> try assumption
435+
· apply open_abs_lc
436+
· apply lc_MNPs.1
409437
· rw[multi_app_lc] at lc_MNPs
410438
apply multi_app_steps_lc at h_Ps_red
411439
simp_all

0 commit comments

Comments
 (0)