Mcltt.Core.Semantic.NbE
From Mcltt Require Import LibTactics.
From Mcltt.Core Require Import Base.
From Mcltt.Core.Semantic Require Export Domain Evaluation Readback.
From Mcltt.Core.Syntactic Require Export System.
Import Domain_Notations.
Generalizable All Variables.
Inductive initial_env : ctx -> env -> Prop :=
| initial_env_nil : initial_env nil empty_env
| initial_env_cons :
`( initial_env Γ ρ ->
{{ ⟦ A ⟧ ρ ↘ a }} ->
initial_env (A :: Γ) d{{{ ρ ↦ ⇑! a (length Γ) }}}).
#[export]
Hint Constructors initial_env : mcltt.
Lemma functional_initial_env : forall Γ ρ,
initial_env Γ ρ ->
forall ρ',
initial_env Γ ρ' ->
ρ = ρ'.
Proof.
induction 1; intros ? Hother; inversion_clear Hother; eauto.
erewrite IHinitial_env in *; try eassumption;
functional_eval_rewrite_clear;
eauto.
Qed.
#[export]
Hint Resolve functional_initial_env : mcltt.
From Mcltt.Core Require Import Base.
From Mcltt.Core.Semantic Require Export Domain Evaluation Readback.
From Mcltt.Core.Syntactic Require Export System.
Import Domain_Notations.
Generalizable All Variables.
Inductive initial_env : ctx -> env -> Prop :=
| initial_env_nil : initial_env nil empty_env
| initial_env_cons :
`( initial_env Γ ρ ->
{{ ⟦ A ⟧ ρ ↘ a }} ->
initial_env (A :: Γ) d{{{ ρ ↦ ⇑! a (length Γ) }}}).
#[export]
Hint Constructors initial_env : mcltt.
Lemma functional_initial_env : forall Γ ρ,
initial_env Γ ρ ->
forall ρ',
initial_env Γ ρ' ->
ρ = ρ'.
Proof.
induction 1; intros ? Hother; inversion_clear Hother; eauto.
erewrite IHinitial_env in *; try eassumption;
functional_eval_rewrite_clear;
eauto.
Qed.
#[export]
Hint Resolve functional_initial_env : mcltt.
In the following spec, we do not care (for now)
whether a is the evaluation result of A or not.
If we want to specify that as well, we need a generalized
version of drop_env that can drop x elements.
Lemma initial_env_spec : forall x Γ ρ A,
initial_env Γ ρ ->
{{ #x : A ∈ Γ }} ->
exists a, ρ x = d{{{ ⇑! a (length Γ - x - 1) }}}.
Proof.
induction x; intros * Hinit Hlookup;
dependent destruction Hlookup; dependent destruction Hinit; simpl; mauto 3.
eexists; repeat f_equal; lia.
Qed.
#[export]
Hint Resolve initial_env_spec : mcltt.
Ltac functional_initial_env_rewrite_clear1 :=
let tactic_error o1 o2 := fail 3 "functional_initial_env equality between" o1 "and" o2 "cannot be solved by mauto" in
match goal with
| H1 : initial_env ?G ?ρ, H2 : initial_env ?G ?ρ' |- _ =>
clean replace ρ' with ρ by first [solve [mauto 2] | tactic_error ρ' ρ]; clear H2
end.
Ltac functional_initial_env_rewrite_clear := repeat functional_initial_env_rewrite_clear1.
Inductive nbe : ctx -> exp -> typ -> nf -> Prop :=
| nbe_run :
`( initial_env Γ ρ ->
{{ ⟦ A ⟧ ρ ↘ a }} ->
{{ ⟦ M ⟧ ρ ↘ m }} ->
{{ Rnf ⇓ a m in (length Γ) ↘ w }} ->
nbe Γ M A w ).
#[export]
Hint Constructors nbe : mcltt.
Lemma functional_nbe : forall Γ M A w w',
nbe Γ M A w ->
nbe Γ M A w' ->
w = w'.
Proof.
intros.
inversion_clear H; inversion_clear H0;
functional_initial_env_rewrite_clear;
functional_eval_rewrite_clear;
functional_read_rewrite_clear;
reflexivity.
Qed.
#[export]
Hint Resolve functional_nbe : mcltt.
Lemma nbe_cumu : forall {Γ A i W},
nbe Γ A {{{ Type@i }}} W ->
nbe Γ A {{{ Type@(S i) }}} W.
Proof.
inversion_clear 1.
simplify_evals.
inversion_clear_by_head read_nf.
mauto.
Qed.
Lemma lift_nbe_ge : forall {Γ A i j W},
i <= j ->
nbe Γ A {{{ Type@i }}} W ->
nbe Γ A {{{ Type@j }}} W.
Proof.
induction 1; mauto using nbe_cumu.
Qed.
Lemma lift_nbe_max_left : forall {Γ A i i' W},
nbe Γ A {{{ Type@i }}} W ->
nbe Γ A {{{ Type@(max i i') }}} W.
Proof.
intros.
assert (i <= max i i') by lia.
mauto using lift_nbe_ge.
Qed.
Lemma lift_nbe_max_right : forall {Γ A i i' W},
nbe Γ A {{{ Type@i' }}} W ->
nbe Γ A {{{ Type@(max i i') }}} W.
Proof.
intros.
assert (i' <= max i i') by lia.
mauto using lift_nbe_ge.
Qed.
#[export]
Hint Resolve lift_nbe_max_left lift_nbe_max_right : mcltt.
Lemma functional_nbe_of_typ : forall Γ A i j W W',
nbe Γ A {{{ Type@i }}} W ->
nbe Γ A {{{ Type@j }}} W' ->
W = W'.
Proof.
mauto.
Qed.
#[export]
Hint Resolve functional_nbe_of_typ : mcltt.
Inductive nbe_ty : ctx -> typ -> nf -> Prop :=
| nbe_ty_run :
`( initial_env Γ ρ ->
{{ ⟦ M ⟧ ρ ↘ m }} ->
{{ Rtyp m in (length Γ) ↘ W }} ->
nbe_ty Γ M W ).
#[export]
Hint Constructors nbe_ty : mcltt.
Lemma functional_nbe_ty : forall Γ M w w',
nbe_ty Γ M w ->
nbe_ty Γ M w' ->
w = w'.
Proof.
intros.
inversion_clear H; inversion_clear H0;
functional_initial_env_rewrite_clear;
functional_eval_rewrite_clear;
functional_read_rewrite_clear;
reflexivity.
Qed.
Lemma nbe_type_to_nbe_ty : forall Γ M i w,
nbe Γ M {{{ Type@i }}} w ->
nbe_ty Γ M w.
Proof.
intros. progressive_inversion.
mauto.
Qed.
#[export]
Hint Resolve functional_nbe_ty nbe_type_to_nbe_ty : mcltt.
Ltac functional_nbe_rewrite_clear1 :=
let tactic_error o1 o2 := fail 3 "functional_nbe equality between" o1 "and" o2 "cannot be solved by mauto" in
match goal with
| H1 : nbe ?G ?M ?A ?W, H2 : nbe ?G ?M ?A ?W' |- _ =>
clean replace W' with W by first [solve [mauto 2] | tactic_error W' W]; clear H2
| H1 : nbe ?G ?A {{{ Type@?i }}} ?W, H2 : nbe ?G ?A {{{ Type@?j }}} ?W' |- _ =>
clean replace W' with W by first [solve [mauto 2] | tactic_error W' W]
| H1 : nbe_ty ?G ?M ?W, H2 : nbe_ty ?G ?M ?W' |- _ =>
clean replace W' with W by first [solve [mauto 2] | tactic_error W' W]; clear H2
end.
Ltac functional_nbe_rewrite_clear := repeat functional_nbe_rewrite_clear1.
initial_env Γ ρ ->
{{ #x : A ∈ Γ }} ->
exists a, ρ x = d{{{ ⇑! a (length Γ - x - 1) }}}.
Proof.
induction x; intros * Hinit Hlookup;
dependent destruction Hlookup; dependent destruction Hinit; simpl; mauto 3.
eexists; repeat f_equal; lia.
Qed.
#[export]
Hint Resolve initial_env_spec : mcltt.
Ltac functional_initial_env_rewrite_clear1 :=
let tactic_error o1 o2 := fail 3 "functional_initial_env equality between" o1 "and" o2 "cannot be solved by mauto" in
match goal with
| H1 : initial_env ?G ?ρ, H2 : initial_env ?G ?ρ' |- _ =>
clean replace ρ' with ρ by first [solve [mauto 2] | tactic_error ρ' ρ]; clear H2
end.
Ltac functional_initial_env_rewrite_clear := repeat functional_initial_env_rewrite_clear1.
Inductive nbe : ctx -> exp -> typ -> nf -> Prop :=
| nbe_run :
`( initial_env Γ ρ ->
{{ ⟦ A ⟧ ρ ↘ a }} ->
{{ ⟦ M ⟧ ρ ↘ m }} ->
{{ Rnf ⇓ a m in (length Γ) ↘ w }} ->
nbe Γ M A w ).
#[export]
Hint Constructors nbe : mcltt.
Lemma functional_nbe : forall Γ M A w w',
nbe Γ M A w ->
nbe Γ M A w' ->
w = w'.
Proof.
intros.
inversion_clear H; inversion_clear H0;
functional_initial_env_rewrite_clear;
functional_eval_rewrite_clear;
functional_read_rewrite_clear;
reflexivity.
Qed.
#[export]
Hint Resolve functional_nbe : mcltt.
Lemma nbe_cumu : forall {Γ A i W},
nbe Γ A {{{ Type@i }}} W ->
nbe Γ A {{{ Type@(S i) }}} W.
Proof.
inversion_clear 1.
simplify_evals.
inversion_clear_by_head read_nf.
mauto.
Qed.
Lemma lift_nbe_ge : forall {Γ A i j W},
i <= j ->
nbe Γ A {{{ Type@i }}} W ->
nbe Γ A {{{ Type@j }}} W.
Proof.
induction 1; mauto using nbe_cumu.
Qed.
Lemma lift_nbe_max_left : forall {Γ A i i' W},
nbe Γ A {{{ Type@i }}} W ->
nbe Γ A {{{ Type@(max i i') }}} W.
Proof.
intros.
assert (i <= max i i') by lia.
mauto using lift_nbe_ge.
Qed.
Lemma lift_nbe_max_right : forall {Γ A i i' W},
nbe Γ A {{{ Type@i' }}} W ->
nbe Γ A {{{ Type@(max i i') }}} W.
Proof.
intros.
assert (i' <= max i i') by lia.
mauto using lift_nbe_ge.
Qed.
#[export]
Hint Resolve lift_nbe_max_left lift_nbe_max_right : mcltt.
Lemma functional_nbe_of_typ : forall Γ A i j W W',
nbe Γ A {{{ Type@i }}} W ->
nbe Γ A {{{ Type@j }}} W' ->
W = W'.
Proof.
mauto.
Qed.
#[export]
Hint Resolve functional_nbe_of_typ : mcltt.
Inductive nbe_ty : ctx -> typ -> nf -> Prop :=
| nbe_ty_run :
`( initial_env Γ ρ ->
{{ ⟦ M ⟧ ρ ↘ m }} ->
{{ Rtyp m in (length Γ) ↘ W }} ->
nbe_ty Γ M W ).
#[export]
Hint Constructors nbe_ty : mcltt.
Lemma functional_nbe_ty : forall Γ M w w',
nbe_ty Γ M w ->
nbe_ty Γ M w' ->
w = w'.
Proof.
intros.
inversion_clear H; inversion_clear H0;
functional_initial_env_rewrite_clear;
functional_eval_rewrite_clear;
functional_read_rewrite_clear;
reflexivity.
Qed.
Lemma nbe_type_to_nbe_ty : forall Γ M i w,
nbe Γ M {{{ Type@i }}} w ->
nbe_ty Γ M w.
Proof.
intros. progressive_inversion.
mauto.
Qed.
#[export]
Hint Resolve functional_nbe_ty nbe_type_to_nbe_ty : mcltt.
Ltac functional_nbe_rewrite_clear1 :=
let tactic_error o1 o2 := fail 3 "functional_nbe equality between" o1 "and" o2 "cannot be solved by mauto" in
match goal with
| H1 : nbe ?G ?M ?A ?W, H2 : nbe ?G ?M ?A ?W' |- _ =>
clean replace W' with W by first [solve [mauto 2] | tactic_error W' W]; clear H2
| H1 : nbe ?G ?A {{{ Type@?i }}} ?W, H2 : nbe ?G ?A {{{ Type@?j }}} ?W' |- _ =>
clean replace W' with W by first [solve [mauto 2] | tactic_error W' W]
| H1 : nbe_ty ?G ?M ?W, H2 : nbe_ty ?G ?M ?W' |- _ =>
clean replace W' with W by first [solve [mauto 2] | tactic_error W' W]; clear H2
end.
Ltac functional_nbe_rewrite_clear := repeat functional_nbe_rewrite_clear1.