|
|
|
|
From stdpp Require Import gmap base relations.
|
|
|
|
|
From iris Require Import prelude.
|
|
|
|
|
From semantics.ts.stlc_extended Require Import lang notation parallel_subst types bigstep.
|
|
|
|
|
From semantics.ts.stlc_extended Require Import lang notation parallel_subst types bigstep.
|
|
|
|
|
From Equations Require Export Equations.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(** * Logical relation for the extended STLC *)
|
|
|
|
|
|
|
|
|
|
Implicit Types
|
|
|
|
|
(Γ : typing_context)
|
|
|
|
|
(v : val)
|
|
|
|
|
(e : expr)
|
|
|
|
|
(A : type).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(* *** Definition of the logical relation. *)
|
|
|
|
|
|
|
|
|
|
Inductive val_or_expr : Type :=
|
|
|
|
|
| inj_val : val → val_or_expr
|
|
|
|
|
| inj_expr : expr → val_or_expr.
|
|
|
|
|
|
|
|
|
|
Equations type_size (A : type) : nat :=
|
|
|
|
|
type_size Int := 1;
|
|
|
|
|
type_size (A → B) := type_size A + type_size B + 1;
|
|
|
|
|
type_size (A × B) := type_size A + type_size B + 1;
|
|
|
|
|
type_size (A + B) := max (type_size A) (type_size B) + 1.
|
|
|
|
|
Equations mut_measure (ve : val_or_expr) (t : type) : nat :=
|
|
|
|
|
mut_measure (inj_val _) t := type_size t;
|
|
|
|
|
mut_measure (inj_expr _) t := 1 + type_size t.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Equations type_interp (ve : val_or_expr) (t : type) : Prop by wf (mut_measure ve t) := {
|
|
|
|
|
type_interp (inj_val v) Int =>
|
|
|
|
|
∃ z : Z, v = #z ;
|
|
|
|
|
type_interp (inj_val v) (A × B) =>
|
|
|
|
|
∃ v₁ v₂,
|
|
|
|
|
v = @PairV v₁ v₂
|
|
|
|
|
∧ type_interp (inj_val v₁) A
|
|
|
|
|
∧ type_interp (inj_val v₂) B
|
|
|
|
|
;
|
|
|
|
|
type_interp (inj_val v) (A + B) =>
|
|
|
|
|
(∃ v₁, v = @InjLV v₁ ∧ type_interp (inj_val v₁) A)
|
|
|
|
|
∨ (∃ v₂, v = @InjRV v₂ ∧ type_interp (inj_val v₂) B);
|
|
|
|
|
type_interp (inj_val v) (A → B) =>
|
|
|
|
|
∃ x e, v = @LamV x e ∧ closed (x :b: nil) e ∧
|
|
|
|
|
∀ v',
|
|
|
|
|
type_interp (inj_val v') A →
|
|
|
|
|
type_interp (inj_expr (subst' x v' e)) B;
|
|
|
|
|
|
|
|
|
|
type_interp (inj_expr e) t =>
|
|
|
|
|
∃ v, big_step e v ∧ type_interp (inj_val v) t
|
|
|
|
|
}.
|
|
|
|
|
Next Obligation.
|
|
|
|
|
repeat simp mut_measure; simp type_size; lia.
|
|
|
|
|
Qed.
|
|
|
|
|
Next Obligation.
|
|
|
|
|
simp mut_measure. simp type_size.
|
|
|
|
|
destruct A; repeat simp mut_measure; repeat simp type_size; lia.
|
|
|
|
|
Qed.
|
|
|
|
|
(* Uncomment the following once you have amended the type interpretation to
|
|
|
|
|
solve the new obligations: *)
|
|
|
|
|
|
|
|
|
|
Next Obligation. repeat simp mut_measure; simp type_size; lia. Qed.
|
|
|
|
|
Next Obligation. repeat simp mut_measure; simp type_size; lia. Qed.
|
|
|
|
|
Next Obligation. repeat simp mut_measure; simp type_size; lia. Qed.
|
|
|
|
|
Next Obligation. repeat simp mut_measure; simp type_size; lia. Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Notation sem_val_rel t v := (type_interp (inj_val v) t).
|
|
|
|
|
Notation sem_expr_rel t e := (type_interp (inj_expr e) t).
|
|
|
|
|
|
|
|
|
|
Notation 𝒱 t v := (sem_val_rel t v).
|
|
|
|
|
Notation ℰ t v := (sem_expr_rel t v).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(* *** Semantic typing of contexts *)
|
|
|
|
|
Implicit Types
|
|
|
|
|
(θ : gmap string expr).
|
|
|
|
|
|
|
|
|
|
Inductive sem_context_rel : typing_context → (gmap string expr) → Prop :=
|
|
|
|
|
| sem_context_rel_empty : sem_context_rel ∅ ∅
|
|
|
|
|
| sem_context_rel_insert Γ θ v x A :
|
|
|
|
|
𝒱 A v →
|
|
|
|
|
sem_context_rel Γ θ →
|
|
|
|
|
sem_context_rel (<[x := A]> Γ) (<[x := of_val v]> θ).
|
|
|
|
|
|
|
|
|
|
Notation 𝒢 := sem_context_rel.
|
|
|
|
|
|
|
|
|
|
Definition sem_typed Γ e A :=
|
|
|
|
|
closed (elements (dom Γ)) e ∧
|
|
|
|
|
∀ θ, 𝒢 Γ θ → ℰ A (subst_map θ e).
|
|
|
|
|
Notation "Γ ⊨ e : A" := (sem_typed Γ e A) (at level 74, e, A at next level).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(* We start by proving a couple of helper lemmas that will be useful later. *)
|
|
|
|
|
|
|
|
|
|
Lemma sem_expr_rel_of_val A v:
|
|
|
|
|
ℰ A v → 𝒱 A v.
|
|
|
|
|
Proof.
|
|
|
|
|
simp type_interp.
|
|
|
|
|
intros (v' & ->%big_step_val & Hv').
|
|
|
|
|
apply Hv'.
|
|
|
|
|
Qed.
|
|
|
|
|
Lemma val_inclusion A v:
|
|
|
|
|
𝒱 A v → ℰ A v.
|
|
|
|
|
Proof.
|
|
|
|
|
intros H. simp type_interp. eauto using big_step_of_val.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma val_rel_closed v A:
|
|
|
|
|
𝒱 A v → closed [] v.
|
|
|
|
|
Proof.
|
|
|
|
|
induction A in v |-*; simp type_interp.
|
|
|
|
|
- intros [z ->]. done.
|
|
|
|
|
- intros (x & e & -> & Hcl & _). done.
|
|
|
|
|
- intros (v1 & v2 & -> & Hv1 & Hv2).
|
|
|
|
|
unfold closed.
|
|
|
|
|
simpl.
|
|
|
|
|
apply andb_True.
|
|
|
|
|
split.
|
|
|
|
|
by apply (IHA1 _ Hv1).
|
|
|
|
|
by apply (IHA2 _ Hv2).
|
|
|
|
|
- intro H.
|
|
|
|
|
case H; intros (v' & -> & Hv').
|
|
|
|
|
+ exact (IHA1 _ Hv').
|
|
|
|
|
+ exact (IHA2 _ Hv').
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma sem_context_rel_closed Γ θ:
|
|
|
|
|
𝒢 Γ θ → subst_closed [] θ.
|
|
|
|
|
Proof.
|
|
|
|
|
induction 1; rewrite /subst_closed.
|
|
|
|
|
- naive_solver.
|
|
|
|
|
- intros y e. rewrite lookup_insert_Some.
|
|
|
|
|
intros [[-> <-]|[Hne Hlook]].
|
|
|
|
|
+ by eapply val_rel_closed.
|
|
|
|
|
+ eapply IHsem_context_rel; last done.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(* This is essentially an inversion lemma for 𝒢 *)
|
|
|
|
|
Lemma sem_context_rel_vals Γ θ x A :
|
|
|
|
|
𝒢 Γ θ →
|
|
|
|
|
Γ !! x = Some A →
|
|
|
|
|
∃ e v, θ !! x = Some e ∧ to_val e = Some v ∧ 𝒱 A v.
|
|
|
|
|
Proof.
|
|
|
|
|
induction 1 as [|Γ θ v y B Hvals Hctx IH].
|
|
|
|
|
- naive_solver.
|
|
|
|
|
- rewrite lookup_insert_Some. intros [[-> ->]|[Hne Hlook]].
|
|
|
|
|
+ do 2 eexists. split; first by rewrite lookup_insert.
|
|
|
|
|
split; first by eapply to_of_val. done.
|
|
|
|
|
+ eapply IH in Hlook as (e & w & Hlook & He & Hval).
|
|
|
|
|
do 2 eexists; split; first by rewrite lookup_insert_ne.
|
|
|
|
|
split; first done. done.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma sem_context_rel_dom Γ θ :
|
|
|
|
|
𝒢 Γ θ → dom Γ = dom θ.
|
|
|
|
|
Proof.
|
|
|
|
|
induction 1.
|
|
|
|
|
- by rewrite !dom_empty.
|
|
|
|
|
- rewrite !dom_insert. congruence.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(* *** Compatibility lemmas *)
|
|
|
|
|
Lemma compat_int Γ z : Γ ⊨ (LitInt z) : Int.
|
|
|
|
|
Proof.
|
|
|
|
|
split; first done.
|
|
|
|
|
intros θ _. simp type_interp.
|
|
|
|
|
exists #z. split; simpl.
|
|
|
|
|
- constructor.
|
|
|
|
|
- simp type_interp. eauto.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma compat_var Γ x A :
|
|
|
|
|
Γ !! x = Some A →
|
|
|
|
|
Γ ⊨ (Var x) : A.
|
|
|
|
|
Proof.
|
|
|
|
|
intros Hx. split.
|
|
|
|
|
{ eapply bool_decide_pack, elem_of_elements, elem_of_dom_2, Hx. }
|
|
|
|
|
intros θ Hctx; simpl.
|
|
|
|
|
eapply sem_context_rel_vals in Hx as (e & v & He & Heq & Hv); last done.
|
|
|
|
|
rewrite He. simp type_interp. exists v. split; last done.
|
|
|
|
|
rewrite -(of_to_val _ _ Heq).
|
|
|
|
|
by apply big_step_of_val.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma compat_app Γ e1 e2 A B :
|
|
|
|
|
Γ ⊨ e1 : (A → B) →
|
|
|
|
|
Γ ⊨ e2 : A →
|
|
|
|
|
Γ ⊨ (e1 e2) : B.
|
|
|
|
|
Proof.
|
|
|
|
|
intros [Hfuncl Hfun] [Hargcl Harg]. split.
|
|
|
|
|
{ unfold closed. simpl. eauto. }
|
|
|
|
|
intros θ Hctx; simpl.
|
|
|
|
|
specialize (Hfun _ Hctx). simp type_interp in Hfun. destruct Hfun as (v1 & Hbs1 & Hv1).
|
|
|
|
|
simp type_interp in Hv1. destruct Hv1 as (x & e & -> & Hcl & Hv1).
|
|
|
|
|
specialize (Harg _ Hctx). simp type_interp in Harg.
|
|
|
|
|
destruct Harg as (v2 & Hbs2 & Hv2).
|
|
|
|
|
|
|
|
|
|
apply Hv1 in Hv2.
|
|
|
|
|
simp type_interp in Hv2. destruct Hv2 as (v & Hbsv & Hv).
|
|
|
|
|
|
|
|
|
|
simp type_interp.
|
|
|
|
|
exists v. split; last done.
|
|
|
|
|
eauto.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(* Compatibility for [lam] unfortunately needs a very technical helper lemma. *)
|
|
|
|
|
Lemma lam_closed Γ θ (x : string) A e :
|
|
|
|
|
closed (elements (dom (<[x:=A]> Γ))) e →
|
|
|
|
|
𝒢 Γ θ →
|
|
|
|
|
closed [] (Lam x (subst_map (delete x θ) e)).
|
|
|
|
|
Proof.
|
|
|
|
|
intros Hcl Hctxt.
|
|
|
|
|
eapply subst_map_closed'_2.
|
|
|
|
|
- eapply is_closed_weaken; first done.
|
|
|
|
|
rewrite dom_delete dom_insert (sem_context_rel_dom Γ θ) //.
|
|
|
|
|
intros y. destruct (decide (x = y)); set_solver.
|
|
|
|
|
- eapply subst_closed_weaken, sem_context_rel_closed; last done.
|
|
|
|
|
+ set_solver.
|
|
|
|
|
+ apply map_delete_subseteq.
|
|
|
|
|
Qed.
|
|
|
|
|
Lemma compat_lam Γ x e A B :
|
|
|
|
|
(<[ x := A ]> Γ) ⊨ e : B →
|
|
|
|
|
Γ ⊨ (Lam (BNamed x) e) : (A → B).
|
|
|
|
|
Proof.
|
|
|
|
|
intros [Hbodycl Hbody]. split.
|
|
|
|
|
{ unfold closed in *. cbn in *. eapply is_closed_weaken; first eassumption.
|
|
|
|
|
set_solver. }
|
|
|
|
|
intros θ Hctxt. simpl. simp type_interp.
|
|
|
|
|
eexists.
|
|
|
|
|
split; first by eauto.
|
|
|
|
|
simp type_interp.
|
|
|
|
|
eexists x, _. split; first reflexivity.
|
|
|
|
|
split; first by eapply lam_closed.
|
|
|
|
|
intros v' Hv'.
|
|
|
|
|
specialize (Hbody (<[ x := of_val v']> θ)).
|
|
|
|
|
simpl. rewrite subst_subst_map; last by eapply sem_context_rel_closed.
|
|
|
|
|
apply Hbody.
|
|
|
|
|
apply sem_context_rel_insert; done.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma compat_lam_anon Γ e A B :
|
|
|
|
|
Γ ⊨ e : B →
|
|
|
|
|
Γ ⊨ (Lam BAnon e) : (A → B).
|
|
|
|
|
Proof.
|
|
|
|
|
intros [Hbodycl Hbody]. split; first done.
|
|
|
|
|
intros θ Hctxt. simpl. simp type_interp.
|
|
|
|
|
eexists.
|
|
|
|
|
split; first by eauto.
|
|
|
|
|
simp type_interp.
|
|
|
|
|
eexists _, _. split; first reflexivity.
|
|
|
|
|
split.
|
|
|
|
|
{ simpl. eapply subst_map_closed'_2; simpl.
|
|
|
|
|
- by erewrite <-sem_context_rel_dom.
|
|
|
|
|
- by eapply sem_context_rel_closed. }
|
|
|
|
|
naive_solver.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma compat_add Γ e1 e2 :
|
|
|
|
|
Γ ⊨ e1 : Int →
|
|
|
|
|
Γ ⊨ e2 : Int →
|
|
|
|
|
Γ ⊨ (e1 + e2) : Int.
|
|
|
|
|
Proof.
|
|
|
|
|
intros [Hcl1 He1] [Hcl2 He2]. split.
|
|
|
|
|
{ unfold closed in *. naive_solver. }
|
|
|
|
|
intros θ Hctx.
|
|
|
|
|
simp type_interp.
|
|
|
|
|
specialize (He1 _ Hctx). specialize (He2 _ Hctx).
|
|
|
|
|
simp type_interp in He1. simp type_interp in He2.
|
|
|
|
|
|
|
|
|
|
destruct He1 as (v1 & Hb1 & Hv1).
|
|
|
|
|
destruct He2 as (v2 & Hb2 & Hv2).
|
|
|
|
|
simp type_interp in Hv1, Hv2.
|
|
|
|
|
destruct Hv1 as (z1 & ->). destruct Hv2 as (z2 & ->).
|
|
|
|
|
|
|
|
|
|
exists #(z1 + z2). split.
|
|
|
|
|
- constructor; done.
|
|
|
|
|
- exists (z1 + z2)%Z. done.
|
|
|
|
|
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma compat_pair Γ e_lhs e_rhs A B:
|
|
|
|
|
Γ ⊨ e_lhs: A →
|
|
|
|
|
Γ ⊨ e_rhs: B →
|
|
|
|
|
Γ ⊨ (e_lhs, e_rhs): A × B.
|
|
|
|
|
Proof.
|
|
|
|
|
intros [Hcl_lhs He_lhs].
|
|
|
|
|
intros [Hcl_rhs He_rhs].
|
|
|
|
|
split.
|
|
|
|
|
(* The closedness can be handled by naive_solver *)
|
|
|
|
|
{
|
|
|
|
|
unfold closed.
|
|
|
|
|
naive_solver.
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(* Use the same θ and H_ctx everywhere: *)
|
|
|
|
|
intros θ H_ctx.
|
|
|
|
|
specialize (He_lhs _ H_ctx).
|
|
|
|
|
specialize (He_rhs _ H_ctx).
|
|
|
|
|
(* Apply the definition of E[A × B] and E[A], E[B] *)
|
|
|
|
|
simp type_interp in *.
|
|
|
|
|
destruct He_lhs as (v_lhs & Hbs_lhs & Hv_lhs).
|
|
|
|
|
destruct He_rhs as (v_rhs & Hbs_rhs & Hv_rhs).
|
|
|
|
|
|
|
|
|
|
(* We now just need to provide a value satisfying our requirements *)
|
|
|
|
|
exists (PairV v_lhs v_rhs).
|
|
|
|
|
split.
|
|
|
|
|
- (* Prove that our expression steps towards the value *)
|
|
|
|
|
simpl.
|
|
|
|
|
econstructor.
|
|
|
|
|
assumption.
|
|
|
|
|
assumption.
|
|
|
|
|
- (* Next prove that our value is a correct member of V[A × B] *)
|
|
|
|
|
simp type_interp. (* Can't just split here :> *)
|
|
|
|
|
eauto. (* Trivial from then on *)
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma compat_fst_snd {Γ e_pair A B}:
|
|
|
|
|
Γ ⊨ e_pair: A × B →
|
|
|
|
|
Γ ⊨ (Fst e_pair): A ∧ Γ ⊨ (Snd e_pair): B.
|
|
|
|
|
Proof.
|
|
|
|
|
intros [Hcl He].
|
|
|
|
|
split.
|
|
|
|
|
all: split; first (unfold closed; naive_solver).
|
|
|
|
|
all: intros θ H_ctx; specialize (He _ H_ctx).
|
|
|
|
|
all: simp type_interp in *; destruct He as (v & Hbs & Hv).
|
|
|
|
|
all: simp type_interp in Hv; destruct Hv as (v₁ & v₂ & -> & Hv₁ & Hv₂).
|
|
|
|
|
1: exists v₁.
|
|
|
|
|
2: exists v₂.
|
|
|
|
|
(* Solve the big_step *)
|
|
|
|
|
all: simpl; split; first (econstructor; eauto).
|
|
|
|
|
all: assumption.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma compat_inj {Γ e_inj} A B:
|
|
|
|
|
Γ ⊨ e_inj: A →
|
|
|
|
|
Γ ⊨ (InjL e_inj): A + B ∧ Γ ⊨ (InjR e_inj): B + A.
|
|
|
|
|
Proof.
|
|
|
|
|
intros [Hcl He].
|
|
|
|
|
split.
|
|
|
|
|
all: split; first (unfold closed; naive_solver).
|
|
|
|
|
all: intros θ H_ctx; specialize (He _ H_ctx).
|
|
|
|
|
all: simp type_interp in *; destruct He as (v & Hbs & Hv).
|
|
|
|
|
1: exists (InjLV v).
|
|
|
|
|
2: exists (InjRV v).
|
|
|
|
|
|
|
|
|
|
all: simpl; split; first (econstructor; eauto).
|
|
|
|
|
- simp type_interp; left; eauto.
|
|
|
|
|
- simp type_interp; right; eauto.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma compat_case {Γ e_inj e_lhs e_rhs A B C}:
|
|
|
|
|
Γ ⊨ e_inj: A + B →
|
|
|
|
|
Γ ⊨ e_lhs: (A → C) →
|
|
|
|
|
Γ ⊨ e_rhs: (B → C) →
|
|
|
|
|
Γ ⊨ (Case e_inj e_lhs e_rhs): C.
|
|
|
|
|
Proof.
|
|
|
|
|
intros [Hcl_inj He_inj] [Hcl_lhs He_lhs] [Hcl_rhs He_rhs].
|
|
|
|
|
split; first (unfold closed; naive_solver).
|
|
|
|
|
|
|
|
|
|
intros θ H_ctx;
|
|
|
|
|
specialize (He_inj _ H_ctx);
|
|
|
|
|
specialize (He_lhs _ H_ctx);
|
|
|
|
|
specialize (He_rhs _ H_ctx).
|
|
|
|
|
|
|
|
|
|
(* All the hypotheses! *)
|
|
|
|
|
simp type_interp in *;
|
|
|
|
|
destruct He_inj as (v_inj & Hbs_inj & Hv_inj);
|
|
|
|
|
destruct He_lhs as (v_lhs & Hbs_lhs & Hv_lhs);
|
|
|
|
|
destruct He_rhs as (v_rhs & Hbs_rhs & Hv_rhs).
|
|
|
|
|
simp type_interp in *;
|
|
|
|
|
destruct Hv_lhs as (x_lhs & fn_lhs & -> & Hcl_lhs2 & IHe_lhs);
|
|
|
|
|
destruct Hv_rhs as (x_rhs & fn_rhs & -> & Hcl_rhs2 & IHe_rhs).
|
|
|
|
|
|
|
|
|
|
case Hv_inj as [[v_lhs [-> Hv_lhs]] | [v_rhs [-> Hv_rhs]]].
|
|
|
|
|
1: specialize (IHe_lhs _ Hv_lhs);
|
|
|
|
|
simp type_interp in IHe_lhs;
|
|
|
|
|
destruct IHe_lhs as (v_res & Hbs_res & Hv_res).
|
|
|
|
|
2: specialize (IHe_rhs _ Hv_rhs);
|
|
|
|
|
simp type_interp in IHe_rhs;
|
|
|
|
|
destruct IHe_rhs as (v_res & Hbs_res & Hv_res).
|
|
|
|
|
|
|
|
|
|
all: exists v_res.
|
|
|
|
|
all: simpl; split; last assumption.
|
|
|
|
|
|
|
|
|
|
- eapply bs_case_l.
|
|
|
|
|
exact Hbs_inj.
|
|
|
|
|
econstructor; eauto.
|
|
|
|
|
apply big_step_of_val; reflexivity.
|
|
|
|
|
- eapply bs_case_r.
|
|
|
|
|
exact Hbs_inj.
|
|
|
|
|
econstructor; eauto.
|
|
|
|
|
apply big_step_of_val; reflexivity.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
Lemma sem_soundness Γ e A :
|
|
|
|
|
(Γ ⊢ e : A)%ty →
|
|
|
|
|
Γ ⊨ e : A.
|
|
|
|
|
Proof.
|
|
|
|
|
induction 1.
|
|
|
|
|
- by apply compat_var.
|
|
|
|
|
- by apply compat_lam.
|
|
|
|
|
- by apply compat_lam_anon.
|
|
|
|
|
- apply compat_int.
|
|
|
|
|
- by eapply compat_app.
|
|
|
|
|
- by apply compat_add.
|
|
|
|
|
- by apply compat_pair.
|
|
|
|
|
- (* "Cool theorem prover you got" — this comment was made by the Lean gang *)
|
|
|
|
|
exact (proj1 (compat_fst_snd IHsyn_typed)).
|
|
|
|
|
- exact (proj2 (compat_fst_snd IHsyn_typed)).
|
|
|
|
|
- exact (proj1 (compat_inj _ _ IHsyn_typed)).
|
|
|
|
|
- exact (proj2 (compat_inj _ _ IHsyn_typed)).
|
|
|
|
|
- by eapply compat_case.
|
|
|
|
|
Qed.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Lemma termination e A :
|
|
|
|
|
(∅ ⊢ e : A)%ty →
|
|
|
|
|
∃ v, big_step e v.
|
|
|
|
|
Proof.
|
|
|
|
|
intros [Hsemcl Hsem]%sem_soundness.
|
|
|
|
|
specialize (Hsem ∅).
|
|
|
|
|
simp type_interp in Hsem.
|
|
|
|
|
rewrite subst_map_empty in Hsem.
|
|
|
|
|
destruct Hsem as (v & Hbs & _); last eauto.
|
|
|
|
|
constructor.
|
|
|
|
|
Qed.
|