import TabularTypes.Lemmas.InstanceEnvironment import TabularTypes.Semantics.Program import TabularTypes.Theorems.Term namespace TabularTypes open «F⊗⊕ω» open Std instance : Inhabited TypeClass where default := .zero in instance : Inhabited Method where default := .zero in instance : Inhabited TypeScheme where default := .qual (.mono (.row [] none)) in instance : Inhabited «F⊗⊕ω».Kind where default := .star in theorem Program.TypingAndElaboration.soundness (pte : [[Γᵢ; Γc ⊢ pgm : σ ⇝ E]]) (Γᵢw : [[Γc ⊢ Γᵢ]] := by exact .empty) (Γcw : [[⊢c Γc]] := by exact .empty) (σke : [[Γc; ε ⊢ σ : * ⇝ A]]) : [[ε ⊢ E : A]] := match pte with | .cls TC'in TCnin mnin σ₀ke p'te (κ := κ) (A' := A') => let ⟨_, κe⟩ := κ.Elaboration_total let Aki := (σ₀ke · |>.soundness Γcw (.typeExt .empty nofun κe) .star) let ⟨_, TC'in'⟩ := Range.skolem TC'in let ⟨A'', TC'in''⟩ := Range.skolem TC'in' let ⟨nₛ, TC'in'''⟩ := Range.skolem TC'in'' let ⟨_, TC'in''''⟩ := Range.skolem TC'in''' let ⟨_, TC'in'''''⟩ := Range.skolem TC'in'''' let ⟨_, TC'in''''''⟩ := Range.skolem TC'in''''' let TCake i mem a : TypeScheme.KindingAndElaboration _ _ _ _ ((A' i).TypeVar_open a) := by let ⟨Aeq, TC'in'''''''⟩ := TC'in'''''' i mem rw [Aeq, Type.TypeVar_open, Type.TypeVar_open, List.mapMem_eq_map, List.map_cons, List.map_map, ← Range.map, Type.TypeVar_open_eq_Type_open_var, Range.map_eq_of_eq_of_mem'' (by intro j mem' rw [Function.comp, Type.TypeVar_open_eq_Type_open_var] )] exact .tc TC'in''''''' (.var .head (Γ := .typeExt .empty a κ)) let Γc'w := Γcw.ext TCnin mnin κe σ₀ke Aki TCake (TCake · · · |>.soundness Γcw (.typeExt .empty nofun κe) .constr) p'te.soundness (Γᵢw.weakening Γc'w (Γc' := .ext .empty ..)) Γc'w <| σke.class_weakening Γc'w (Γc' := .ext .empty ..) | .inst γcin ψke TC'τce τke Mte p'te (TC' := TC') (A' := A') (σ₀ := σ₀) (A := A) (κ' := κ') (l := l) (o := o) => by apply p'te.soundness _ Γcw σke let ⟨K₁, κ'e⟩ := Classical.skolem.mp (κ' · |>.Elaboration_total) let ⟨_, κ₀e, σke, _, TC'ke, _⟩ := Γcw.In_inversion γcin apply Γᵢw.ext γcin ψke τke fun i _ => κ'e i · intro a x let aκ'we := TypeEnvironment.WellFormednessAndElaboration.empty.multiTypeExt (fun _ => nofun) a.property (fun i _ => κ'e i) (n := o) (Γc := Γc) let aκ'ψ'xwe := aκ'we.multiConstrExt (by intro _ rw [TypeEnvironment.TermVarNotInDom, TypeEnvironment.termVarDom_multiTypeExt, TypeEnvironment.termVarDom] nofun ) x.property (ψke · · a) (n := l) apply Mte a x |>.soundness _ Γᵢw Γcw aκ'ψ'xwe let ⟨a', a'nin⟩ := σ₀.freeTypeVars ++ ↑A.freeTypeVars ++ [[(ε,, )]].typeVarDom |>.exists_fresh let ⟨a'ninσ₀A, a'ninaκ'⟩ := List.not_mem_append'.mp a'nin let ⟨a'ninσ₀, a'ninA⟩ := List.not_mem_append'.mp a'ninσ₀A let aκ'a'we := aκ'we.typeExt a'ninaκ' κ₀e let σke' := σke a' rw [← TypeEnvironment.empty_append (.multiTypeExt ..)] at aκ'a'we rw [← TypeEnvironment.empty_append (.typeExt ..)] at σke' let σke'' := σke'.weakening aκ'a'we (Γ := .empty) (Γ'' := .typeExt .empty ..) rw [TypeEnvironment.empty_append] at σke'' aκ'a'we rw [TypeEnvironment.append, TypeEnvironment.append] at σke'' rw [← TypeEnvironment.append_empty (.multiConstrExt ..), TypeEnvironment.multiConstrExt_eq_append (Γ' := .empty)] at aκ'ψ'xwe have := σke''.Monotype_open_preservation Γcw aκ'a'we nofun a'ninσ₀ a'ninA (τke a) (Γ' := .empty) |>.weakening aκ'ψ'xwe (Γ := .multiTypeExt .empty ..) (Γ' := .multiConstrExt .empty ..) (Γ'' := .empty) rw [← TypeEnvironment.multiConstrExt_eq_append (Γ' := .empty), TypeEnvironment.append_empty] at this exact this · intro i mem a x let aκ'we := TypeEnvironment.WellFormednessAndElaboration.empty.multiTypeExt (fun _ => nofun) a.property (fun i _ => κ'e i) (n := o) (Γc := Γc) let aκ'ψ'xwe := aκ'we.multiConstrExt (by intro _ rw [TypeEnvironment.TermVarNotInDom, TypeEnvironment.termVarDom_multiTypeExt, TypeEnvironment.termVarDom] nofun ) x.property (ψke · · a) (n := l) apply TC'τce i mem a x |>.soundness _ Γᵢw Γcw aκ'ψ'xwe let ⟨a', a'nin⟩ := ↑(A' i).freeTypeVars ++ [[(ε,, )]].typeVarDom |>.exists_fresh let ⟨a'ninA'ᵢ, a'ninaκ'⟩ := List.not_mem_append'.mp a'nin let aκ'a'we := aκ'we.typeExt a'ninaκ' κ₀e rw [← TypeEnvironment.empty_append (.multiTypeExt ..)] at aκ'a'we let TC'a'ke := TC'ke a' i mem |>.weakening aκ'a'we (Γ := .empty) (Γ'' := .typeExt .empty ..) rw [TypeEnvironment.empty_append] at TC'a'ke aκ'a'we have : Monotype.typeClass (TC' i) (.var (.free a')) = (.TypeVar_open (.typeClass (TC' i) (.var (.bound 0))) a') := by simp [Monotype.TypeVar_open] rw [this, ← QualifiedType.TypeVar_open, ← TypeScheme.TypeVar_open] at TC'a'ke rw [← TypeEnvironment.append_empty (.multiConstrExt ..), TypeEnvironment.multiConstrExt_eq_append (Γ' := .empty)] at aκ'ψ'xwe let this := TC'a'ke.Monotype_open_preservation Γcw aκ'a'we nofun (by rw [TypeScheme.freeTypeVars, QualifiedType.freeTypeVars, Monotype.freeTypeVars, Monotype.freeTypeVars] nofun ) a'ninA'ᵢ (τke a) (Γ' := .empty) |>.weakening aκ'ψ'xwe (Γ := .multiTypeExt .empty ..) (Γ' := .multiConstrExt .empty ..) (Γ'' := .empty) rw [← TypeEnvironment.multiConstrExt_eq_append (Γ' := .empty), TypeEnvironment.append_empty, TypeScheme.Monotype_open, QualifiedType.Monotype_open, Monotype.Monotype_open, Monotype.Monotype_open, if_pos rfl] at this exact this | .term Mte => Mte.soundness σke Γᵢw Γcw .empty end TabularTypes