3.4. Metatheory
The rest of the file records the first general facts about typing. The visible proof steps are intended to be mathematical statements; automation is used to discharge the routine bookkeeping inside those steps.
theorem typing_independent_of_context
(hlookup : ∀x ∈ L1.FV e, lookup x Γ = lookup x Δ)
(ht : Γ ⊢ e : A)
: Δ ⊢ e : A :=
e:L1Γ:ContextΔ:ContextA:Tyhlookup:∀ (x : String), x ∈ e.FV → lookup x Γ = lookup x Δht:Γ ⊢ e : A⊢ Δ ⊢ e : A
e:L1Γ:ContextA:Tyx✝:StringΓ✝:ContextA✝:Tya✝:lookup x✝ Γ✝ = some A✝Δ:Contexthlookup:∀ (x : String), x ∈ (L1.var x✝).FV → lookup x Γ✝ = lookup x Δ⊢ Δ ⊢ L1.var x✝ : A✝e:L1Γ:ContextA:Tyx✝:StringA✝:TyΓ✝:List (String × Ty)body✝:L1B✝:Tya✝:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝a_ih✝:∀ {Δ : Context}, (∀ (x : String), x ∈ body✝.FV → lookup x ((x✝, A✝) :: Γ✝) = lookup x Δ) → Δ ⊢ body✝ : B✝Δ:Contexthlookup:∀ (x : String), x ∈ (L1.lam x✝ body✝).FV → lookup x Γ✝ = lookup x Δ⊢ Δ ⊢ L1.lam x✝ body✝ : A✝ ⇒ B✝e:L1Γ:ContextA:TyΓ✝:Contextfn✝:L1A✝:TyB✝:Tyarg✝:L1a✝¹:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝a✝:Γ✝ ⊢ arg✝ : A✝a_ih✝¹:∀ {Δ : Context}, (∀ (x : String), x ∈ fn✝.FV → lookup x Γ✝ = lookup x Δ) → Δ ⊢ fn✝ : A✝ ⇒ B✝a_ih✝:∀ {Δ : Context}, (∀ (x : String), x ∈ arg✝.FV → lookup x Γ✝ = lookup x Δ) → Δ ⊢ arg✝ : A✝Δ:Contexthlookup:∀ (x : String), x ∈ (fn✝.app arg✝).FV → lookup x Γ✝ = lookup x Δ⊢ Δ ⊢ fn✝.app arg✝ : B✝
case var x Γ A h e:L1Γ✝:ContextA✝:Tyx:StringΓ:ContextA:Tyh:lookup x✝ Γ✝ = some A✝Δ:Contexthlookup:∀ (x : String), x ∈ (L1.var x✝).FV → lookup x Γ✝ = lookup x Δ⊢ Δ ⊢ L1.var x✝ : A✝
have : x ∈ L1.FV (L1.var x) := e:L1Γ:ContextΔ:ContextA:Tyhlookup:∀ (x : String), x ∈ e.FV → lookup x Γ = lookup x Δht:Γ ⊢ e : A⊢ Δ ⊢ e : A
All goals completed! 🐙
have : lookup x Δ = some A := e:L1Γ:ContextΔ:ContextA:Tyhlookup:∀ (x : String), x ∈ e.FV → lookup x Γ = lookup x Δht:Γ ⊢ e : A⊢ Δ ⊢ e : A
All goals completed! 🐙
All goals completed! 🐙
case lam x A Γ body B hbody ih e:L1Γ✝:ContextA✝:Tyx:StringA:TyΓ:List (String × Ty)body:L1B:Tyhbody:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝ih:∀ {Δ : Context}, (∀ (x : String), x ∈ body✝.FV → lookup x ((x✝, A✝) :: Γ✝) = lookup x Δ) → Δ ⊢ body✝ : B✝Δ:Contexthlookup:∀ (x : String), x ∈ (L1.lam x✝ body✝).FV → lookup x Γ✝ = lookup x Δ⊢ Δ ⊢ L1.lam x✝ body✝ : A✝ ⇒ B✝
have : ∀z ∈ L1.FV body,
lookup z ((x, A) :: Γ) = lookup z ((x, A) :: Δ) := e:L1Γ:ContextΔ:ContextA:Tyhlookup:∀ (x : String), x ∈ e.FV → lookup x Γ = lookup x Δht:Γ ⊢ e : A⊢ Δ ⊢ e : A
intro z e:L1Γ✝:ContextA✝:Tyx:StringA:TyΓ:List (String × Ty)body:L1B:Tyhbody:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝ih:∀ {Δ : Context}, (∀ (x : String), x ∈ body✝.FV → lookup x ((x✝, A✝) :: Γ✝) = lookup x Δ) → Δ ⊢ body✝ : B✝Δ:Contexthlookup:∀ (x : String), x ∈ (L1.lam x✝ body✝).FV → lookup x Γ✝ = lookup x Δz:Stringhz:z ∈ body.FV⊢ lookup z ((x, A) :: Γ) = lookup z ((x, A) :: Δ)
e:L1Γ✝:ContextA✝:Tyx:StringA:TyΓ:List (String × Ty)body:L1B:Tyhbody:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝ih:∀ {Δ : Context}, (∀ (x : String), x ∈ body✝.FV → lookup x ((x✝, A✝) :: Γ✝) = lookup x Δ) → Δ ⊢ body✝ : B✝Δ:Contexthlookup:∀ (x : String), x ∈ (L1.lam x✝ body✝).FV → lookup x Γ✝ = lookup x Δz:Stringhz:z ∈ body.FVh✝:z = x⊢ lookup z ((x, A) :: Γ) = lookup z ((x, A) :: Δ)e:L1Γ✝:ContextA✝:Tyx:StringA:TyΓ:List (String × Ty)body:L1B:Tyhbody:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝ih:∀ {Δ : Context}, (∀ (x : String), x ∈ body✝.FV → lookup x ((x✝, A✝) :: Γ✝) = lookup x Δ) → Δ ⊢ body✝ : B✝Δ:Contexthlookup:∀ (x : String), x ∈ (L1.lam x✝ body✝).FV → lookup x Γ✝ = lookup x Δz:Stringhz:z ∈ body.FVh✝:¬z = x⊢ lookup z ((x, A) :: Γ) = lookup z ((x, A) :: Δ)
e:L1Γ✝:ContextA✝:Tyx:StringA:TyΓ:List (String × Ty)body:L1B:Tyhbody:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝ih:∀ {Δ : Context}, (∀ (x : String), x ∈ body✝.FV → lookup x ((x✝, A✝) :: Γ✝) = lookup x Δ) → Δ ⊢ body✝ : B✝Δ:Contexthlookup:∀ (x : String), x ∈ (L1.lam x✝ body✝).FV → lookup x Γ✝ = lookup x Δz:Stringhz:z ∈ body.FVh✝:z = x⊢ lookup z ((x, A) :: Γ) = lookup z ((x, A) :: Δ) All goals completed! 🐙
e:L1Γ✝:ContextA✝:Tyx:StringA:TyΓ:List (String × Ty)body:L1B:Tyhbody:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝ih:∀ {Δ : Context}, (∀ (x : String), x ∈ body✝.FV → lookup x ((x✝, A✝) :: Γ✝) = lookup x Δ) → Δ ⊢ body✝ : B✝Δ:Contexthlookup:∀ (x : String), x ∈ (L1.lam x✝ body✝).FV → lookup x Γ✝ = lookup x Δz:Stringhz:z ∈ body.FVh✝:¬z = x⊢ lookup z ((x, A) :: Γ) = lookup z ((x, A) :: Δ) have : z ∈ L1.FV (L1.lam x body) := e:L1Γ:ContextΔ:ContextA:Tyhlookup:∀ (x : String), x ∈ e.FV → lookup x Γ = lookup x Δht:Γ ⊢ e : A⊢ Δ ⊢ e : A
All goals completed! 🐙
All goals completed! 🐙
have : (x, A) :: Δ ⊢ body : B := e:L1Γ:ContextΔ:ContextA:Tyhlookup:∀ (x : String), x ∈ e.FV → lookup x Γ = lookup x Δht:Γ ⊢ e : A⊢ Δ ⊢ e : A
All goals completed! 🐙
All goals completed! 🐙
case app Γ fn A B arg htfn htarg ihfn iharg e:L1Γ✝:ContextA✝:TyΓ:Contextfn:L1A:TyB:Tyarg:L1htfn:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝htarg:Γ✝ ⊢ arg✝ : A✝ihfn:∀ {Δ : Context}, (∀ (x : String), x ∈ fn✝.FV → lookup x Γ✝ = lookup x Δ) → Δ ⊢ fn✝ : A✝ ⇒ B✝iharg:∀ {Δ : Context}, (∀ (x : String), x ∈ arg✝.FV → lookup x Γ✝ = lookup x Δ) → Δ ⊢ arg✝ : A✝Δ:Contexthlookup:∀ (x : String), x ∈ (fn✝.app arg✝).FV → lookup x Γ✝ = lookup x Δ⊢ Δ ⊢ fn✝.app arg✝ : B✝
have : ∀z ∈ L1.FV fn, lookup z Γ = lookup z Δ := e:L1Γ:ContextΔ:ContextA:Tyhlookup:∀ (x : String), x ∈ e.FV → lookup x Γ = lookup x Δht:Γ ⊢ e : A⊢ Δ ⊢ e : A
intro z e:L1Γ✝:ContextA✝:TyΓ:Contextfn:L1A:TyB:Tyarg:L1htfn:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝htarg:Γ✝ ⊢ arg✝ : A✝ihfn:∀ {Δ : Context}, (∀ (x : String), x ∈ fn✝.FV → lookup x Γ✝ = lookup x Δ) → Δ ⊢ fn✝ : A✝ ⇒ B✝iharg:∀ {Δ : Context}, (∀ (x : String), x ∈ arg✝.FV → lookup x Γ✝ = lookup x Δ) → Δ ⊢ arg✝ : A✝Δ:Contexthlookup:∀ (x : String), x ∈ (fn✝.app arg✝).FV → lookup x Γ✝ = lookup x Δz:Stringhz:z ∈ fn.FV⊢ lookup z Γ = lookup z Δ
All goals completed! 🐙
have : Δ ⊢ fn : A ⇒ B := e:L1Γ:ContextΔ:ContextA:Tyhlookup:∀ (x : String), x ∈ e.FV → lookup x Γ = lookup x Δht:Γ ⊢ e : A⊢ Δ ⊢ e : A
All goals completed! 🐙
have : ∀z ∈ L1.FV arg, lookup z Γ = lookup z Δ := e:L1Γ:ContextΔ:ContextA:Tyhlookup:∀ (x : String), x ∈ e.FV → lookup x Γ = lookup x Δht:Γ ⊢ e : A⊢ Δ ⊢ e : A
intro z e:L1Γ✝:ContextA✝:TyΓ:Contextfn:L1A:TyB:Tyarg:L1htfn:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝htarg:Γ✝ ⊢ arg✝ : A✝ihfn:∀ {Δ : Context}, (∀ (x : String), x ∈ fn✝.FV → lookup x Γ✝ = lookup x Δ) → Δ ⊢ fn✝ : A✝ ⇒ B✝iharg:∀ {Δ : Context}, (∀ (x : String), x ∈ arg✝.FV → lookup x Γ✝ = lookup x Δ) → Δ ⊢ arg✝ : A✝Δ:Contexthlookup:∀ (x : String), x ∈ (fn✝.app arg✝).FV → lookup x Γ✝ = lookup x Δthis✝:∀ (z : String), z ∈ fn.FV → lookup z Γ = lookup z Δthis:Δ ⊢ fn : A ⇒ Bz:Stringhz:z ∈ arg.FV⊢ lookup z Γ = lookup z Δ
All goals completed! 🐙
have : Δ ⊢ arg : A := e:L1Γ:ContextΔ:ContextA:Tyhlookup:∀ (x : String), x ∈ e.FV → lookup x Γ = lookup x Δht:Γ ⊢ e : A⊢ Δ ⊢ e : A
All goals completed! 🐙
All goals completed! 🐙theorem neutrality
(hΓ : ∀x A B, lookup x Γ ≠ some (A ⇒ B))
(hn : L1.Neutral e)
(ht : Γ ⊢ e : A)
: ∃x, e = L1.var x ∧ lookup x Γ = some A :=
Γ:Contexte:L1A:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:e.Neutralht:Γ ⊢ e : A⊢ ∃ x, e = L1.var x ∧ lookup x Γ = some A x✝:StringΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:(L1.var x✝).Neutralht:Γ ⊢ L1.var x✝ : A⊢ ∃ x, L1.var x✝ = L1.var x ∧ lookup x Γ = some Ax✝:Stringbody✝:L1body_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
body✝.Neutral → (Γ ⊢ body✝ : A) → ∃ x, body✝ = L1.var x ∧ lookup x Γ = some AΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:(L1.lam x✝ body✝).Neutralht:Γ ⊢ L1.lam x✝ body✝ : A⊢ ∃ x, L1.lam x✝ body✝ = L1.var x ∧ lookup x Γ = some Afn✝:L1arg✝:L1fn_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
fn✝.Neutral → (Γ ⊢ fn✝ : A) → ∃ x, fn✝ = L1.var x ∧ lookup x Γ = some Aarg_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
arg✝.Neutral → (Γ ⊢ arg✝ : A) → ∃ x, arg✝ = L1.var x ∧ lookup x Γ = some AΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:(fn✝.app arg✝).Neutralht:Γ ⊢ fn✝.app arg✝ : A⊢ ∃ x, fn✝.app arg✝ = L1.var x ∧ lookup x Γ = some A x✝:StringΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:(L1.var x✝).Neutralht:Γ ⊢ L1.var x✝ : A⊢ ∃ x, L1.var x✝ = L1.var x ∧ lookup x Γ = some Ax✝:Stringbody✝:L1body_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
body✝.Neutral → (Γ ⊢ body✝ : A) → ∃ x, body✝ = L1.var x ∧ lookup x Γ = some AΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:(L1.lam x✝ body✝).Neutralht:Γ ⊢ L1.lam x✝ body✝ : A⊢ ∃ x, L1.lam x✝ body✝ = L1.var x ∧ lookup x Γ = some Afn✝:L1arg✝:L1fn_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
fn✝.Neutral → (Γ ⊢ fn✝ : A) → ∃ x, fn✝ = L1.var x ∧ lookup x Γ = some Aarg_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
arg✝.Neutral → (Γ ⊢ arg✝ : A) → ∃ x, arg✝ = L1.var x ∧ lookup x Γ = some AΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:(fn✝.app arg✝).Neutralht:Γ ⊢ fn✝.app arg✝ : A⊢ ∃ x, fn✝.app arg✝ = L1.var x ∧ lookup x Γ = some A fn✝:L1arg✝:L1fn_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
fn✝.Neutral → (Γ ⊢ fn✝ : A) → ∃ x, fn✝ = L1.var x ∧ lookup x Γ = some Aarg_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
arg✝.Neutral → (Γ ⊢ arg✝ : A) → ∃ x, arg✝ = L1.var x ∧ lookup x Γ = some AΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)ht:Γ ⊢ fn✝.app arg✝ : Aa✝¹:fn✝.Neutrala✝:arg✝.Normal⊢ ∃ x, fn✝.app arg✝ = L1.var x ∧ lookup x Γ = some A x✝:StringΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)ht:Γ ⊢ L1.var x✝ : A⊢ ∃ x, L1.var x✝ = L1.var x ∧ lookup x Γ = some Afn✝:L1arg✝:L1fn_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
fn✝.Neutral → (Γ ⊢ fn✝ : A) → ∃ x, fn✝ = L1.var x ∧ lookup x Γ = some Aarg_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
arg✝.Neutral → (Γ ⊢ arg✝ : A) → ∃ x, arg✝ = L1.var x ∧ lookup x Γ = some AΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)ht:Γ ⊢ fn✝.app arg✝ : Aa✝¹:fn✝.Neutrala✝:arg✝.Normal⊢ ∃ x, fn✝.app arg✝ = L1.var x ∧ lookup x Γ = some A fn✝:L1arg✝:L1fn_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
fn✝.Neutral → (Γ ⊢ fn✝ : A) → ∃ x, fn✝ = L1.var x ∧ lookup x Γ = some Aarg_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
arg✝.Neutral → (Γ ⊢ arg✝ : A) → ∃ x, arg✝ = L1.var x ∧ lookup x Γ = some AΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)a✝³:fn✝.Neutrala✝²:arg✝.NormalA✝:Tya✝¹:Γ ⊢ arg✝ : A✝a✝:Γ ⊢ fn✝ : A✝ ⇒ A⊢ ∃ x, fn✝.app arg✝ = L1.var x ∧ lookup x Γ = some A x✝:StringΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)a✝:lookup x✝ Γ = some A⊢ ∃ x, L1.var x✝ = L1.var x ∧ lookup x Γ = some Afn✝:L1arg✝:L1fn_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
fn✝.Neutral → (Γ ⊢ fn✝ : A) → ∃ x, fn✝ = L1.var x ∧ lookup x Γ = some Aarg_ih✝:∀ {Γ : Context} {A : Ty},
(∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)) →
arg✝.Neutral → (Γ ⊢ arg✝ : A) → ∃ x, arg✝ = L1.var x ∧ lookup x Γ = some AΓ:ContextA:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)a✝³:fn✝.Neutrala✝²:arg✝.NormalA✝:Tya✝¹:Γ ⊢ arg✝ : A✝a✝:Γ ⊢ fn✝ : A✝ ⇒ A⊢ ∃ x, fn✝.app arg✝ = L1.var x ∧ lookup x Γ = some A All goals completed! 🐙theorem normal_arrow_is_lam
(hΓ : ∀x A B, lookup x Γ ≠ some (A ⇒ B))
(hn : L1.Normal e)
(ht : Γ ⊢ e : A ⇒ B)
: ∃x body, e = L1.lam x body ∧ L1.Normal body ∧ ((x, A) :: Γ) ⊢ body : B :=
Γ:Contexte:L1A:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:e.Normalht:Γ ⊢ e : A ⇒ B⊢ ∃ x body, e = L1.lam x body ∧ body.Normal ∧ (x, A) :: Γ ⊢ body : B
have : ¬ L1.Neutral e := Γ:Contexte:L1A:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:e.Normalht:Γ ⊢ e : A ⇒ B⊢ ∃ x body, e = L1.lam x body ∧ body.Normal ∧ (x, A) :: Γ ⊢ body : B All goals completed! 🐙
obtain_by x b : e = L1.lam x b ∧ L1.Normal b := Γ:Contexte:L1A:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:e.Normalht:Γ ⊢ e : A ⇒ Bthis:¬e.Neutral⊢ ∃ x b, e = L1.lam x b ∧ b.Normal Γ:ContextA:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)body:L1x:Stringa:body.Normalht:Γ ⊢ L1.lam x body : A ⇒ Bthis:¬(L1.lam x body).Neutral⊢ ∃ x_1 b, L1.lam x body = L1.lam x_1 b ∧ b.NormalΓ:Contexte:L1A:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)ht:Γ ⊢ e : A ⇒ Bthis:¬e.Neutrala:e.Neutral⊢ ∃ x b, e = L1.lam x b ∧ b.Normal Γ:ContextA:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)body:L1x:Stringa:body.Normalht:Γ ⊢ L1.lam x body : A ⇒ Bthis:¬(L1.lam x body).Neutral⊢ ∃ x_1 b, L1.lam x body = L1.lam x_1 b ∧ b.NormalΓ:Contexte:L1A:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)ht:Γ ⊢ e : A ⇒ Bthis:¬e.Neutrala:e.Neutral⊢ ∃ x b, e = L1.lam x b ∧ b.Normal All goals completed! 🐙
have : ((x, A) :: Γ) ⊢ b : B := Γ:Contexte:L1A:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)hn:e.Normalht:Γ ⊢ e : A ⇒ B⊢ ∃ x body, e = L1.lam x body ∧ body.Normal ∧ (x, A) :: Γ ⊢ body : B Γ:ContextA:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)x:Stringb:L1h1:b.Normalx✝:Stringhn:(L1.var x✝).Normalthis:¬(L1.var x✝).Neutralh0:L1.var x✝ = L1.lam x ba✝:lookup x✝ Γ = some (A ⇒ B)⊢ (x, A) :: Γ ⊢ b : BΓ:ContextA:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)x:Stringb:L1h1:b.Normalx✝:Stringbody✝:L1hn:(L1.lam x✝ body✝).Normalthis:¬(L1.lam x✝ body✝).Neutralh0:L1.lam x✝ body✝ = L1.lam x ba✝:(x✝, A) :: Γ ⊢ body✝ : B⊢ (x, A) :: Γ ⊢ b : BΓ:ContextA:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)x:Stringb:L1h1:b.Normalfn✝:L1A✝:Tyarg✝:L1a✝¹:Γ ⊢ arg✝ : A✝hn:(fn✝.app arg✝).Normalthis:¬(fn✝.app arg✝).Neutralh0:fn✝.app arg✝ = L1.lam x ba✝:Γ ⊢ fn✝ : A✝ ⇒ A ⇒ B⊢ (x, A) :: Γ ⊢ b : B Γ:ContextA:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)x:Stringb:L1h1:b.Normalx✝:Stringhn:(L1.var x✝).Normalthis:¬(L1.var x✝).Neutralh0:L1.var x✝ = L1.lam x ba✝:lookup x✝ Γ = some (A ⇒ B)⊢ (x, A) :: Γ ⊢ b : BΓ:ContextA:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)x:Stringb:L1h1:b.Normalx✝:Stringbody✝:L1hn:(L1.lam x✝ body✝).Normalthis:¬(L1.lam x✝ body✝).Neutralh0:L1.lam x✝ body✝ = L1.lam x ba✝:(x✝, A) :: Γ ⊢ body✝ : B⊢ (x, A) :: Γ ⊢ b : BΓ:ContextA:TyB:TyhΓ:∀ (x : String) (A B : Ty), lookup x Γ ≠ some (A ⇒ B)x:Stringb:L1h1:b.Normalfn✝:L1A✝:Tyarg✝:L1a✝¹:Γ ⊢ arg✝ : A✝hn:(fn✝.app arg✝).Normalthis:¬(fn✝.app arg✝).Neutralh0:fn✝.app arg✝ = L1.lam x ba✝:Γ ⊢ fn✝ : A✝ ⇒ A ⇒ B⊢ (x, A) :: Γ ⊢ b : B All goals completed! 🐙
All goals completed! 🐙theorem boolean_normal_forms
(hc : L1.Closed e)
(hn : L1.Normal e)
(ht : Γ ⊢ e : #α ⇒ #α ⇒ #α)
: (e =α₁ L1.T) ∨ (e =α₁ L1.F)
:= e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"⊢ e =α₁ L1.T ∨ e =α₁ L1.F
have : [] ⊢ e : #α ⇒ #α ⇒ #α
:= e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"⊢ e =α₁ L1.T ∨ e =α₁ L1.F All goals completed! 🐙
obtain_by x y e₂ : e = L1[λ{x}. λ{y}. {e₂}] ∧ L1.Normal e₂ ∧ [(y, #α), (x, #α)] ⊢ e₂ : #α
:= e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"⊢ ∃ x y e₂, e = L1.lam x (L1.lam y e₂) ∧ e₂.Normal ∧ [(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α" All goals completed! 🐙
have : L1.Neutral e₂
:= e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"⊢ e =α₁ L1.T ∨ e =α₁ L1.F e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringx✝:Stringh0:e = L1.lam x (L1.lam y (L1.var x✝))h1:(L1.var x✝).Normala✝:lookup x✝ [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")⊢ (L1.var x✝).Neutrale:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringfn✝:L1A✝:Tyarg✝:L1a✝¹:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ arg✝ : A✝h0:e = L1.lam x (L1.lam y (fn✝.app arg✝))h1:(fn✝.app arg✝).Normala✝:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ fn✝ : A✝ ⇒ Ty.base "α"⊢ (fn✝.app arg✝).Neutral e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringx✝:Stringh0:e = L1.lam x (L1.lam y (L1.var x✝))h1:(L1.var x✝).Normala✝:lookup x✝ [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")⊢ (L1.var x✝).Neutrale:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringfn✝:L1A✝:Tyarg✝:L1a✝¹:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ arg✝ : A✝h0:e = L1.lam x (L1.lam y (fn✝.app arg✝))h1:(fn✝.app arg✝).Normala✝:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ fn✝ : A✝ ⇒ Ty.base "α"⊢ (fn✝.app arg✝).Neutral e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringfn✝:L1A✝:Tyarg✝:L1a✝²:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ arg✝ : A✝h0:e = L1.lam x (L1.lam y (fn✝.app arg✝))a✝¹:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ fn✝ : A✝ ⇒ Ty.base "α"a✝:(fn✝.app arg✝).Neutral⊢ (fn✝.app arg✝).Neutral e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringx✝:Stringh0:e = L1.lam x (L1.lam y (L1.var x✝))a✝¹:lookup x✝ [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")a✝:(L1.var x✝).Neutral⊢ (L1.var x✝).Neutrale:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringfn✝:L1A✝:Tyarg✝:L1a✝²:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ arg✝ : A✝h0:e = L1.lam x (L1.lam y (fn✝.app arg✝))a✝¹:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ fn✝ : A✝ ⇒ Ty.base "α"a✝:(fn✝.app arg✝).Neutral⊢ (fn✝.app arg✝).Neutral All goals completed! 🐙
obtain_by z : e₂ = L1.var z ∧ lookup z [(y, #α), (x, #α)] = some #α
:= e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0:e = L1.lam x (L1.lam y e₂)h1:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutral⊢ ∃ z, e₂ = L1.var z ∧ lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α") All goals completed! 🐙
cases_or : (z = x) ∨ (z = y) := e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"⊢ e =α₁ L1.T ∨ e =α₁ L1.F All goals completed! 🐙
| inl =>
e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0✝:e = L1.lam x (L1.lam y e₂)h1✝:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutralz:Stringh0:e₂ = L1.var zh1:lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")h✝¹:z = xh✝:x = y⊢ e =α₁ L1.T ∨ e =α₁ L1.Fe:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0✝:e = L1.lam x (L1.lam y e₂)h1✝:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutralz:Stringh0:e₂ = L1.var zh1:lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")h✝¹:z = xh✝:¬x = y⊢ e =α₁ L1.T ∨ e =α₁ L1.F
e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0✝:e = L1.lam x (L1.lam y e₂)h1✝:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutralz:Stringh0:e₂ = L1.var zh1:lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")h✝¹:z = xh✝:x = y⊢ e =α₁ L1.T ∨ e =α₁ L1.F e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0✝:e = L1.lam x (L1.lam y e₂)h1✝:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutralz:Stringh0:e₂ = L1.var zh1:lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")h✝¹:z = xh✝:x = y⊢ e =α₁ L1.F; e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0✝:e = L1.lam x (L1.lam y e₂)h1✝:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutralz:Stringh0:e₂ = L1.var zh1:lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")h✝¹:z = xh✝:x = y⊢ e =α₁ L1.lam "x" (L1.lam "y" (L1.var "y")); All goals completed! 🐙
e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0✝:e = L1.lam x (L1.lam y e₂)h1✝:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutralz:Stringh0:e₂ = L1.var zh1:lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")h✝¹:z = xh✝:¬x = y⊢ e =α₁ L1.T ∨ e =α₁ L1.F e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0✝:e = L1.lam x (L1.lam y e₂)h1✝:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutralz:Stringh0:e₂ = L1.var zh1:lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")h✝¹:z = xh✝:¬x = y⊢ e =α₁ L1.T; e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0✝:e = L1.lam x (L1.lam y e₂)h1✝:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutralz:Stringh0:e₂ = L1.var zh1:lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")h✝¹:z = xh✝:¬x = y⊢ e =α₁ L1.lam "x" (L1.lam "y" (L1.var "x")); All goals completed! 🐙
| inr =>
e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0✝:e = L1.lam x (L1.lam y e₂)h1✝:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutralz:Stringh0:e₂ = L1.var zh1:lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")h✝:z = y⊢ e =α₁ L1.F; e:L1Γ:Contexthc:e.Closedhn:e.Normalht:Γ ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"this✝:[] ⊢ e : Ty.base "α" ⇒ Ty.base "α" ⇒ Ty.base "α"x:Stringy:Stringe₂:L1h0✝:e = L1.lam x (L1.lam y e₂)h1✝:e₂.Normalh2:[(y, Ty.base "α"), (x, Ty.base "α")] ⊢ e₂ : Ty.base "α"this:e₂.Neutralz:Stringh0:e₂ = L1.var zh1:lookup z [(y, Ty.base "α"), (x, Ty.base "α")] = some (Ty.base "α")h✝:z = y⊢ e =α₁ L1.lam "x" (L1.lam "y" (L1.var "y")); All goals completed! 🐙theorem progress_in
(ht : Γ ⊢ e : A)
: L1.Normal e ∨ L1.ReducibleIn ρ e :=
Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e
Γ:Contexte:L1A:Tyx✝:StringΓ✝:ContextA✝:Tya✝:lookup x✝ Γ✝ = some A✝ρ:List String⊢ (L1.var x✝).Normal ∨ L1.ReducibleIn ρ (L1.var x✝)Γ:Contexte:L1A:Tyx✝:StringA✝:TyΓ✝:List (String × Ty)body✝:L1B✝:Tya✝:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝a_ih✝:∀ {ρ : List String}, body✝.Normal ∨ L1.ReducibleIn ρ body✝ρ:List String⊢ (L1.lam x✝ body✝).Normal ∨ L1.ReducibleIn ρ (L1.lam x✝ body✝)Γ:Contexte:L1A:TyΓ✝:Contextfn✝:L1A✝:TyB✝:Tyarg✝:L1a✝¹:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝a✝:Γ✝ ⊢ arg✝ : A✝a_ih✝¹:∀ {ρ : List String}, fn✝.Normal ∨ L1.ReducibleIn ρ fn✝a_ih✝:∀ {ρ : List String}, arg✝.Normal ∨ L1.ReducibleIn ρ arg✝ρ:List String⊢ (fn✝.app arg✝).Normal ∨ L1.ReducibleIn ρ (fn✝.app arg✝)
case var x _ _ _ Γ:Contexte:L1A:Tyx:StringΓ✝:ContextA✝:Tya✝:lookup x✝ Γ✝ = some A✝ρ:List String⊢ (L1.var x✝).Normal ∨ L1.ReducibleIn ρ (L1.var x✝)
have : L1.Normal (L1.var x) := Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e All goals completed! 🐙
All goals completed! 🐙
case lam x _ _ body _ _ ih Γ:Contexte:L1A:Tyx:StringA✝:TyΓ✝:List (String × Ty)body:L1B✝:Tya✝:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝ih:∀ {ρ : List String}, body✝.Normal ∨ L1.ReducibleIn ρ body✝ρ:List String⊢ (L1.lam x✝ body✝).Normal ∨ L1.ReducibleIn ρ (L1.lam x✝ body✝)
cases_or : (L1.Normal body) ∨ (L1.ReducibleIn (x :: ρ) body) := Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e All goals completed! 🐙
| inl Γ:Contexte:L1A:Tyx:StringA✝:TyΓ✝:List (String × Ty)body:L1B✝:Tya✝:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝ih:∀ {ρ : List String}, body✝.Normal ∨ L1.ReducibleIn ρ body✝ρ:List String⊢ (L1.lam x✝ body✝).Normal ∨ L1.ReducibleIn ρ (L1.lam x✝ body✝)
have : L1.Normal (L1.lam x body) := Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e All goals completed! 🐙
All goals completed! 🐙
| inr Γ:Contexte:L1A:Tyx:StringA✝:TyΓ✝:List (String × Ty)body:L1B✝:Tya✝:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝ih:∀ {ρ : List String}, body✝.Normal ∨ L1.ReducibleIn ρ body✝ρ:List String⊢ (L1.lam x✝ body✝).Normal ∨ L1.ReducibleIn ρ (L1.lam x✝ body✝)
have : L1.ReducibleIn ρ (L1.lam x body) := Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e
Γ:Contexte:L1A:Tyx:StringA✝:TyΓ✝:List (String × Ty)body:L1B✝:Tya✝:(x✝, A✝) :: Γ✝ ⊢ body✝ : B✝ρ:List Stringih:∀ {ρ : List String}, body.Normal ∨ ∃ e', L1.toL0With ρ body →β₀ e'h✝:∃ e', L1.toL0With (x :: ρ) body →β₀ e'⊢ ∃ e', (L1.toL0With (x :: ρ) body).lam →β₀ e'
All goals completed! 🐙
All goals completed! 🐙
case app _ fn _ _ arg _ _ ihfn iharg Γ:Contexte:L1A:TyΓ✝:Contextfn:L1A✝:TyB✝:Tyarg:L1a✝¹:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝a✝:Γ✝ ⊢ arg✝ : A✝ihfn:∀ {ρ : List String}, fn✝.Normal ∨ L1.ReducibleIn ρ fn✝iharg:∀ {ρ : List String}, arg✝.Normal ∨ L1.ReducibleIn ρ arg✝ρ:List String⊢ (fn✝.app arg✝).Normal ∨ L1.ReducibleIn ρ (fn✝.app arg✝)
cases_or : (L1.Normal fn) ∨ (L1.ReducibleIn ρ fn) := Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e All goals completed! 🐙
| inl Γ:Contexte:L1A:TyΓ✝:Contextfn:L1A✝:TyB✝:Tyarg:L1a✝¹:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝a✝:Γ✝ ⊢ arg✝ : A✝ihfn:∀ {ρ : List String}, fn✝.Normal ∨ L1.ReducibleIn ρ fn✝iharg:∀ {ρ : List String}, arg✝.Normal ∨ L1.ReducibleIn ρ arg✝ρ:List String⊢ (fn✝.app arg✝).Normal ∨ L1.ReducibleIn ρ (fn✝.app arg✝)
cases_or : (L1.Normal arg) ∨ (L1.ReducibleIn ρ arg) := Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e All goals completed! 🐙
| inl Γ:Contexte:L1A:TyΓ✝:Contextfn:L1A✝:TyB✝:Tyarg:L1a✝¹:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝a✝:Γ✝ ⊢ arg✝ : A✝ihfn:∀ {ρ : List String}, fn✝.Normal ∨ L1.ReducibleIn ρ fn✝iharg:∀ {ρ : List String}, arg✝.Normal ∨ L1.ReducibleIn ρ arg✝ρ:List String⊢ (fn✝.app arg✝).Normal ∨ L1.ReducibleIn ρ (fn✝.app arg✝)
cases ‹L1.Normal fn› with
Γ:Contexte:L1A:TyΓ✝:Contextfn:L1A✝:TyB✝:Tyarg:L1a✝²:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝a✝¹:Γ✝ ⊢ arg✝ : A✝ihfn:∀ {ρ : List String}, fn✝.Normal ∨ L1.ReducibleIn ρ fn✝iharg:∀ {ρ : List String}, arg✝.Normal ∨ L1.ReducibleIn ρ arg✝ρ:List Stringh✝:arg.Normala✝:fn.Neutral⊢ (fn.app arg).Normal ∨ L1.ReducibleIn ρ (fn.app arg)
have : L1.Normal (L1.app fn arg) := Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e
All goals completed! 🐙
All goals completed! 🐙
Γ:Contexte:L1A:TyΓ✝:ContextA✝:TyB✝:Tyarg:L1a✝¹:Γ✝ ⊢ arg✝ : A✝iharg:∀ {ρ : List String}, arg✝.Normal ∨ L1.ReducibleIn ρ arg✝ρ:List Stringh✝:arg.Normalb:L1x:Stringnb:b.Normala✝:Γ✝ ⊢ L1.lam x b : A✝ ⇒ B✝ihfn:∀ {ρ : List String}, (L1.lam x b).Normal ∨ L1.ReducibleIn ρ (L1.lam x b)⊢ ((L1.lam x b).app arg).Normal ∨ L1.ReducibleIn ρ ((L1.lam x b).app arg)
have : L1.ReducibleIn ρ ((L1.lam x b).app arg) := Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e
Γ:Contexte:L1A:TyΓ✝:ContextA✝:TyB✝:Tyarg:L1a✝¹:Γ✝ ⊢ arg✝ : A✝ρ:List Stringh✝:arg.Normalb:L1x:Stringnb:b.Normala✝:Γ✝ ⊢ L1.lam x b : A✝ ⇒ B✝ihfn:∀ {ρ : List String}, (L1.lam x b).Normal ∨ ∃ e', (L1.toL0With (x :: ρ) b).lam →β₀ e'⊢ ∃ e', (L1.toL0With (x :: ρ) b).lam.app (L1.toL0With ρ arg) →β₀ e'
All goals completed! 🐙
All goals completed! 🐙
| inr Γ:Contexte:L1A:TyΓ✝:Contextfn:L1A✝:TyB✝:Tyarg:L1a✝¹:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝a✝:Γ✝ ⊢ arg✝ : A✝ihfn:∀ {ρ : List String}, fn✝.Normal ∨ L1.ReducibleIn ρ fn✝iharg:∀ {ρ : List String}, arg✝.Normal ∨ L1.ReducibleIn ρ arg✝ρ:List String⊢ (fn✝.app arg✝).Normal ∨ L1.ReducibleIn ρ (fn✝.app arg✝)
have : L1.ReducibleIn ρ (L1.app fn arg) := Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e
Γ:Contexte:L1A:TyΓ✝:Contextfn:L1A✝:TyB✝:Tyarg:L1a✝¹:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝a✝:Γ✝ ⊢ arg✝ : A✝ρ:List Stringiharg:∀ {ρ : List String}, arg.Normal ∨ ∃ e', L1.toL0With ρ arg →β₀ e'h✝¹:fn.Normalh✝:∃ e', L1.toL0With ρ arg →β₀ e'⊢ ∃ e', (L1.toL0With ρ fn).app (L1.toL0With ρ arg) →β₀ e'
All goals completed! 🐙
All goals completed! 🐙
| inr Γ:Contexte:L1A:TyΓ✝:Contextfn:L1A✝:TyB✝:Tyarg:L1a✝¹:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝a✝:Γ✝ ⊢ arg✝ : A✝ihfn:∀ {ρ : List String}, fn✝.Normal ∨ L1.ReducibleIn ρ fn✝iharg:∀ {ρ : List String}, arg✝.Normal ∨ L1.ReducibleIn ρ arg✝ρ:List String⊢ (fn✝.app arg✝).Normal ∨ L1.ReducibleIn ρ (fn✝.app arg✝)
have : L1.ReducibleIn ρ (L1.app fn arg) := Γ:Contexte:L1A:Tyρ:List Stringht:Γ ⊢ e : A⊢ e.Normal ∨ L1.ReducibleIn ρ e
Γ:Contexte:L1A:TyΓ✝:Contextfn:L1A✝:TyB✝:Tyarg:L1a✝¹:Γ✝ ⊢ fn✝ : A✝ ⇒ B✝a✝:Γ✝ ⊢ arg✝ : A✝ρ:List Stringihfn:∀ {ρ : List String}, fn.Normal ∨ ∃ e', L1.toL0With ρ fn →β₀ e'iharg:∀ {ρ : List String}, arg.Normal ∨ ∃ e', L1.toL0With ρ arg →β₀ e'h✝:∃ e', L1.toL0With ρ fn →β₀ e'⊢ ∃ e', (L1.toL0With ρ fn).app (L1.toL0With ρ arg) →β₀ e'
All goals completed! 🐙
All goals completed! 🐙end L2