Require Import Equivalence.
Require Import Morphisms.
Require Import Setoid.
Require Import EquivDec.
Require Import Program.
Require Import List.
Require Import String.
Require Import Utils.
Require Import DataSystem.
Require Import cNRAEnv.
Require Import cNRAEnvEq.
Require Import TcNRAEnv.
Section TcNRAEnvEq.
Local Open Scope nraenv_core_scope.
Definition typed_nraenv_core {
m:
basic_model} τ
c τ
env τ
in τ
out := {
op:
nraenv_core|
op ▷ τ
in >=> τ
out ⊣ τ
c;τ
env}.
Definition tnraenv_core_eq {
m:
basic_model} {τ
c τ
env τ
in τ
out} (
op1 op2:
typed_nraenv_core τ
c τ
env τ
in τ
out) :
Prop :=
forall (
x:
data)
c (
env:
data)
(
dt_x:
x ▹ τ
in)
(
dt_c:
bindings_type c τ
c)
(
dt_env:
env ▹ τ
env),
brand_relation_brands ⊢ₑ (
proj1_sig op1) @ₑ
x ⊣
c;
env
=
brand_relation_brands ⊢ₑ (
proj1_sig op2) @ₑ
x ⊣
c;
env.
Global Instance tnraenv_core_equiv {
m:
basic_model} {τ
c} {τ
env τ
in τ
out:
rtype} :
Equivalence (@
tnraenv_core_eq m τ
c τ
env τ
in τ
out).
Proof.
Notation "
t1 ⇝ₑ
t2 ⊣ τ
c ;
tenv" := (
typed_nraenv_core τ
c tenv t1 t2) (
at level 80).
Notation "
X ≡τₑ
Y" := (
tnraenv_core_eq X Y) (
at level 80).
Local Hint Resolve data_type_normalized :
qcert.
Local Hint Resolve bindings_type_Forall_normalized :
qcert.
Lemma nraenv_core_eq_impl_tnraenv_core_eq {
m:
basic_model} {τ
c τ
env τ
in τ
out} (
op1 op2: τ
in ⇝ₑ τ
out ⊣ τ
c;τ
env) :
`
op1 ≡ₑ `
op2 ->
op1 ≡τₑ
op2.
Proof.
Lemma nraenv_core_eq_pf_irrel {
m:
basic_model} {
op} {τ
in τ
out τ
c τ
env} (
pf1 pf2:
op ▷ τ
in >=> τ
out ⊣ τ
c;τ
env) :
tnraenv_core_eq (
exist _ op pf1) (
exist _ op pf2).
Proof.
red; intros; simpl.
reflexivity.
Qed.
Context {
m:
basic_model}.
Definition tnraenv_core_rewrites_to (
op1 op2:
nraenv_core) :
Prop :=
forall τ
c (τ
env τ
in τ
out:
rtype),
op1 ▷ τ
in >=> τ
out ⊣ τ
c;τ
env ->
(
op2 ▷ τ
in >=> τ
out ⊣ τ
c;τ
env)
/\ (
forall (
x:
data)
c
env
(
dt_x:
x ▹ τ
in)
(
dt_c:
bindings_type c τ
c)
(
dt_env:
env ▹ τ
env),
brand_relation_brands ⊢ₑ
op1 @ₑ
x ⊣
c;
env
=
brand_relation_brands ⊢ₑ
op2 @ₑ
x ⊣
c;
env).
Notation "
op1 ⇒
op2" := (@
tnraenv_core_rewrites_to op1 op2) (
at level 80).
Lemma rewrites_typed_with_untyped (
op1 op2:
nraenv_core) :
op1 ≡ₑ
op2 ->
(
forall {τ
c} {τ
env τ
in τ
out:
rtype},
op1 ▷ τ
in >=> τ
out ⊣ τ
c;τ
env ->
op2 ▷ τ
in >=> τ
out ⊣ τ
c;τ
env)
->
op1 ⇒
op2.
Proof.
Lemma talg_rewrites_eq_is_typed_eq {τ
c} {τ
env τ
in τ
out:
rtype} (
op1 op2:
typed_nraenv_core τ
c τ
env τ
in τ
out):
(`
op1 ⇒ `
op2) -> @
tnraenv_core_eq m τ
c τ
env τ
in τ
out op1 op2.
Proof.
unfold tnraenv_core_rewrites_to,
tnraenv_core_eq;
intros.
dependent induction op1.
dependent induction op2;
simpl in *.
elim (
H τ
c τ
env τ
in τ
out);
clear H;
intros.
apply (
H0 x1 c env dt_x dt_c dt_env).
assumption.
Qed.
Global Instance tnraenv_core_rewrites_to_pre :
PreOrder tnraenv_core_rewrites_to.
Proof.
constructor;
red;
intros.
-
unfold tnraenv_core_rewrites_to;
intros.
split;
try assumption;
intros.
reflexivity.
-
unfold tnraenv_core_rewrites_to in *;
intros.
specialize (
H τ
c τ
env τ
in τ
out H1).
elim H;
clear H;
intros.
specialize (
H0 τ
c τ
env τ
in τ
out H).
elim H0;
clear H0;
intros.
split;
try assumption;
intros.
rewrite (
H2 x0 c env);
try assumption.
rewrite (
H3 x0 c env);
try assumption.
reflexivity.
Qed.
Global Instance anid_tproper:
Proper tnraenv_core_rewrites_to cNRAEnvID.
Proof.
Global Instance anconst_tproper:
Proper (
eq ==>
tnraenv_core_rewrites_to)
cNRAEnvConst.
Proof.
Global Instance anbinop_tproper:
Proper (
eq ==>
tnraenv_core_rewrites_to
==>
tnraenv_core_rewrites_to
==>
tnraenv_core_rewrites_to)
cNRAEnvBinop.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
rewrite H in *;
clear H.
nraenv_core_inferer.
specialize (
H0 τ
c τ
env τ
in τ₁
H9);
elim H0;
clear H0 H9;
intros.
specialize (
H1 τ
c τ
env τ
in τ₂
H10);
elim H1;
clear H1 H10;
intros.
econstructor;
qeauto;
intros.
rewrite (
H0 x2 c env dt_x dt_c dt_env);
rewrite (
H2 x2 c env dt_x dt_c dt_env);
reflexivity.
Qed.
Global Instance anunop_tproper :
Proper (
eq ==>
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvUnop.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
nraenv_core_inferer.
specialize (
H0 τ
c τ
env τ
in τ
H8);
elim H0;
clear H0 H8;
intros.
econstructor;
qeauto.
intros.
rewrite (
H0 x c env dt_x dt_c dt_env);
reflexivity.
Qed.
Global Instance anmap_tproper :
Proper (
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvMap.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
nraenv_core_inferer.
specialize (
H0 τ
c τ
env τ
in (
Coll τ₁)
H8);
elim H0;
clear H0 H8;
intros.
specialize (
H τ
c τ
env τ₁ τ₂
H4);
elim H;
clear H H4;
intros.
econstructor;
qeauto;
intros.
rewrite (
H1 x1 c env dt_x dt_c dt_env).
input_well_typed.
dtype_inverter.
inversion τ
out.
rtype_equalizer.
subst.
clear eout τ
out.
induction dout;
try reflexivity;
simpl in *.
f_equal.
inversion H5;
clear H5;
subst.
rewrite (
H2 a c env H6 dt_c dt_env).
input_well_typed.
unfold lift in *.
specialize (
IHdout H7).
destruct (
lift_map (
nraenv_core_eval brand_relation_brands c x env)
dout);
destruct (
lift_map (
nraenv_core_eval brand_relation_brands c y env)
dout);
congruence.
Qed.
Global Instance anmapconcat_tproper :
Proper (
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvMapProduct.
Proof.
Global Instance anproduct_tproper :
Proper (
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvProduct.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
nraenv_core_inferer.
specialize (
H0 τ
c τ
env τ
in (
Coll (
Rec Closed τ₂
pf2))
H5);
elim H0;
clear H0 H5;
intros.
specialize (
H τ
c τ
env τ
in (
Coll (
Rec Closed τ₁
pf1))
H4);
elim H;
clear H H4;
intros.
econstructor;
qeauto;
intros.
rewrite (
H1 x1 c env dt_x dt_c dt_env).
rewrite (
H2 x1 c env dt_x dt_c dt_env).
reflexivity.
Qed.
Global Instance anselect_tproper :
Proper (
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvSelect.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
nraenv_core_inferer.
specialize (
H0 τ
c τ
env τ
in (
Coll τ)
H8);
elim H0;
clear H0 H8;
intros.
specialize (
H τ
c τ
env τ
Bool H4);
elim H;
clear H H4;
intros.
econstructor;
qeauto;
intros.
rewrite (
H1 x1 c env dt_x dt_c dt_env).
input_well_typed.
dtype_inverter.
apply f_equal.
apply lift_filter_eq;
auto;
simpl;
intros.
dtype_enrich.
rewrite (
H2 a c env H4 dt_c dt_env).
reflexivity.
Qed.
Global Instance andefault_tproper :
Proper (
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvDefault.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
nraenv_core_inferer.
specialize (
H0 τ
c τ
env τ
in (
Coll τ)
H8);
elim H0;
clear H0 H8;
intros.
specialize (
H τ
c τ
env τ
in (
Coll τ)
H4);
elim H;
clear H H4;
intros.
econstructor;
qeauto;
intros.
rewrite (
H2 x1 c env dt_x dt_c dt_env).
rewrite (
H1 x1 c env dt_x dt_c dt_env).
reflexivity.
Qed.
Global Instance aneither_tproper :
Proper (
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvEither.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
inversion H1;
subst.
specialize (
H0 _ _ _ _ H8);
elim H0;
clear H0 H8;
intros.
specialize (
H _ _ _ _ H4);
elim H;
intros.
econstructor;
qeauto;
intros.
simpl.
inversion dt_x;
rtype_equalizer.
-
subst;
eauto.
-
subst;
eauto.
Qed.
Global Instance aneitherconcat_tproper :
Proper (
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvEitherConcat.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
inversion H1;
clear H1;
subst.
specialize (
H0 _ _ _ _ H5);
elim H0;
clear H0 H5;
intros.
specialize (
H _ _ _ _ H4);
elim H;
clear H H4;
intros.
econstructor;
qeauto;
intros.
simpl.
rewrite H1,
H2;
trivial.
Qed.
Global Instance anapp_tproper :
Proper (
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvApp.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
nraenv_core_inferer.
specialize (
H0 τ
c τ
env τ
in τ1
H4);
elim H0;
clear H0 H4;
intros.
specialize (
H τ
c τ
env τ1 τ
out H8);
elim H;
clear H H8;
intros.
econstructor;
qeauto;
intros.
rewrite (
H1 x1 c env dt_x dt_c dt_env).
input_well_typed.
rewrite (
H2 dout c env τ
out0 dt_c dt_env).
auto.
Qed.
Global Instance anenv_tproper:
Proper tnraenv_core_rewrites_to cNRAEnvEnv.
Proof.
Global Instance anappenv_tproper :
Proper (
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvAppEnv.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
nraenv_core_inferer.
specialize (
H0 τ
c τ
env τ
in τ
env'
H4);
elim H0;
clear H0 H4;
intros.
specialize (
H τ
c τ
env' τ
in τ
out H8);
elim H;
clear H H8;
intros.
econstructor;
qeauto;
intros.
rewrite (
H1 x1 c env dt_x dt_c dt_env).
input_well_typed.
rewrite (
H2 x1 c dout dt_x dt_c τ
out0).
auto.
Qed.
Global Instance anmapenv_tproper :
Proper (
tnraenv_core_rewrites_to ==>
tnraenv_core_rewrites_to)
cNRAEnvMapEnv.
Proof.
unfold Proper,
respectful,
tnraenv_core_rewrites_to;
intros.
nraenv_core_inferer.
specialize (
H τ
c τ
env0 τ
in τ₂
H2);
elim H;
clear H H2;
intros.
econstructor;
qeauto;
intros.
dtype_inverter.
f_equal.
apply lift_map_ext;
intros.
rewrite (
H0 x0 c x1 dt_x dt_c).
reflexivity.
inversion dt_env.
rtype_equalizer.
subst.
rewrite Forall_forall in *;
auto.
Qed.
End TcNRAEnvEq.
Notation "
op1 ⇒
op2" := (
tnraenv_core_rewrites_to op1 op2) (
at level 80) :
nraenv_core_scope.
Notation "
h ⊧
t1 ⇝
t2 ⊣
c ;
tenv" := (@
typed_nraenv_core h c tenv t1 t2) (
at level 80) :
nraenv_core_scope.
Notation "
X ≡τ
Y" := (
tnraenv_core_eq X Y) (
at level 80) :
nraenv_core_scope.
Notation "
X ≡τ'
Y" := (
tnraenv_core_eq (
exist _ _ X) (
exist _ _ Y)) (
at level 80) :
nraenv_core_scope.