Section TcNRAEnv.
Require Import String.
Require Import List.
Require Import Compare_dec.
Require Import Program.
Require Import Utils BasicSystem.
Require Import cNRAEnv cNRAEnvEq.
Local Open Scope nraenv_core_scope.
Typing for NRA
Section typ.
Context {
m:
basic_model}.
Context (τ
constants:
tbindings).
Inductive nraenv_core_type :
nraenv_core ->
rtype ->
rtype ->
rtype ->
Prop :=
|
ANTID {τ
env τ} :
nraenv_core_type ANID τ
env τ τ
|
ANTConst {τ
env τ
in τ
out}
c :
data_type (
normalize_data brand_relation_brands c) τ
out ->
nraenv_core_type (
ANConst c) τ
env τ
in τ
out
|
ANTBinop {τ
env τ
in τ₁ τ₂ τ
out}
b op1 op2 :
binOp_type b τ₁ τ₂ τ
out ->
nraenv_core_type op1 τ
env τ
in τ₁ ->
nraenv_core_type op2 τ
env τ
in τ₂ ->
nraenv_core_type (
ANBinop b op1 op2) τ
env τ
in τ
out
|
ANTUnop {τ
env τ
in τ τ
out}
u op :
unaryOp_type u τ τ
out ->
nraenv_core_type op τ
env τ
in τ ->
nraenv_core_type (
ANUnop u op) τ
env τ
in τ
out
|
ANTMap {τ
env τ
in τ₁ τ₂}
op1 op2 :
nraenv_core_type op1 τ
env τ₁ τ₂ ->
nraenv_core_type op2 τ
env τ
in (
Coll τ₁) ->
nraenv_core_type (
ANMap op1 op2) τ
env τ
in (
Coll τ₂)
|
ANTMapConcat {τ
env τ
in τ₁ τ₂ τ₃}
op1 op2 pf1 pf2 pf3 :
nraenv_core_type op1 τ
env (
Rec Closed τ₁
pf1) (
Coll (
Rec Closed τ₂
pf2)) ->
nraenv_core_type op2 τ
env τ
in (
Coll (
Rec Closed τ₁
pf1)) ->
rec_concat_sort τ₁ τ₂ = τ₃ ->
nraenv_core_type (
ANMapConcat op1 op2) τ
env τ
in (
Coll (
Rec Closed τ₃
pf3))
|
ANTProduct {τ
env τ
in τ₁ τ₂ τ₃}
op1 op2 pf1 pf2 pf3 :
nraenv_core_type op1 τ
env τ
in (
Coll (
Rec Closed τ₁
pf1)) ->
nraenv_core_type op2 τ
env τ
in (
Coll (
Rec Closed τ₂
pf2)) ->
rec_concat_sort τ₁ τ₂ = τ₃ ->
nraenv_core_type (
ANProduct op1 op2) τ
env τ
in (
Coll (
Rec Closed τ₃
pf3))
|
ANTSelect {τ
env τ
in τ}
op1 op2 :
nraenv_core_type op1 τ
env τ
Bool ->
nraenv_core_type op2 τ
env τ
in (
Coll τ) ->
nraenv_core_type (
ANSelect op1 op2) τ
env τ
in (
Coll τ)
|
ANTDefault {τ
env τ
in τ}
op1 op2 :
nraenv_core_type op1 τ
env τ
in (
Coll τ) ->
nraenv_core_type op2 τ
env τ
in (
Coll τ) ->
nraenv_core_type (
ANDefault op1 op2) τ
env τ
in (
Coll τ)
|
ANTEither {τ
env τ
l τ
r τ
out}
opl opr :
nraenv_core_type opl τ
env τ
l τ
out ->
nraenv_core_type opr τ
env τ
r τ
out ->
nraenv_core_type (
ANEither opl opr) τ
env (
Either τ
l τ
r) τ
out
|
ANTEitherConcat {τ
env τ
in rll pfl rlr pfr rlo pfo lo ro}
op1 op2 pflo pfro :
nraenv_core_type op1 τ
env τ
in (
Either (
Rec Closed rll pfl) (
Rec Closed rlr pfr)) ->
nraenv_core_type op2 τ
env τ
in (
Rec Closed rlo pfo) ->
rec_concat_sort rll rlo =
lo ->
rec_concat_sort rlr rlo =
ro ->
nraenv_core_type (
ANEitherConcat op1 op2) τ
env τ
in (
Either (
Rec Closed lo pflo) (
Rec Closed ro pfro))
|
ANTApp {τ
env τ
in τ1 τ2}
op2 op1 :
nraenv_core_type op1 τ
env τ
in τ1 ->
nraenv_core_type op2 τ
env τ1 τ2 ->
nraenv_core_type (
ANApp op2 op1) τ
env τ
in τ2
|
ANTGetConstant {τ
env τ
in τ
out}
s :
tdot τ
constants s =
Some τ
out ->
nraenv_core_type (
ANGetConstant s) τ
env τ
in τ
out
|
ANTEnv {τ
env τ
in} :
nraenv_core_type ANEnv τ
env τ
in τ
env
|
ANTAppEnv {τ
env τ
env' τ
in τ2}
op2 op1 :
nraenv_core_type op1 τ
env τ
in τ
env' ->
nraenv_core_type op2 τ
env' τ
in τ2 ->
nraenv_core_type (
ANAppEnv op2 op1) τ
env τ
in τ2
|
ANTMapEnv {τ
env τ
in τ₂}
op1 :
nraenv_core_type op1 τ
env τ
in τ₂ ->
nraenv_core_type (
ANMapEnv op1) (
Coll τ
env) τ
in (
Coll τ₂).
End typ.
Notation "
Op ▷
A >=>
B ⊣
C ;
E" := (
nraenv_core_type C Op E A B) (
at level 70).
Type lemmas for individual algebraic expressions
Context {
m:
basic_model}.
Lemma rmap_typed {τ
c} {τ
env τ₁ τ₂ :
rtype}
c (
op1 :
nraenv_core) (
env:
data) (
dl :
list data) :
(
bindings_type c τ
c) ->
(
env ▹ τ
env) ->
(
Forall (
fun d :
data =>
data_type d τ₁)
dl) ->
(
op1 ▷ τ₁ >=> τ₂ ⊣ τ
c; τ
env) ->
(
forall d :
data,
data_type d τ₁ ->
exists x :
data,
brand_relation_brands ⊢ₑ
op1 @ₑ
d ⊣
c;
env =
Some x /\
x ▹ τ₂) ->
exists x :
list data, (
rmap (
nraenv_core_eval brand_relation_brands c op1 env)
dl =
Some x) /\
data_type (
dcoll x) (
Coll τ₂).
Proof.
intros dt_c;
intros.
induction dl;
simpl;
intros.
-
exists (@
nil data);
split; [
reflexivity|
apply dtcoll;
apply Forall_nil].
-
inversion H0;
clear H0.
elim (
H2 a);
intros;
try assumption.
elim H0;
intros;
clear H0.
rewrite H7;
clear H7.
specialize (
IHdl H6);
clear H6.
elim IHdl;
intros;
clear IHdl.
elim H0;
intros;
clear H0.
dependent induction H7.
rewrite H6.
exists (
x0 ::
x1).
split;
try reflexivity.
apply dtcoll.
apply Forall_cons;
try assumption.
assert (
r = τ₂)
by (
apply rtype_fequal;
assumption).
rewrite <-
H3;
assumption.
Qed.
Lemma rmap_env_typed {τ
c} {τ
env τ₁ τ₂ :
rtype}
c (
op1 :
nraenv_core) (
x0:
data) (
dl :
list data) :
bindings_type c τ
c ->
(
x0 ▹ τ₁) ->
(
Forall (
fun d :
data =>
data_type d τ
env)
dl) ->
(
op1 ▷ τ₁ >=> τ₂ ⊣ τ
c;τ
env) ->
(
forall env :
data,
data_type env τ
env ->
forall d :
data,
data_type d τ₁ ->
exists x :
data,
brand_relation_brands ⊢ₑ
op1 @ₑ
d ⊣
c;
env =
Some x /\
data_type x τ₂) ->
exists x :
list data, (
rmap (
fun env' => (
nraenv_core_eval brand_relation_brands c op1 env'
x0))
dl =
Some x) /\
data_type (
dcoll x) (
Coll τ₂).
Proof.
intros dt_c.
induction dl;
simpl;
intros.
-
exists (@
nil data);
split; [
reflexivity|
apply dtcoll;
apply Forall_nil].
-
inversion H0;
clear H0 H4 l H3 x.
elim (
H2 a H5 x0);
intros;
try assumption.
elim H0;
intros;
clear H0.
rewrite H3;
clear H3;
simpl in *.
specialize (
IHdl H H6);
clear H6.
elim IHdl;
intros;
clear IHdl;
trivial.
elim H0;
intros;
clear H0.
dependent induction H6.
rewrite H3;
clear H3;
simpl.
exists (
x2 ::
x1).
split;
try reflexivity.
apply dtcoll.
apply Forall_cons;
try assumption.
assert (
r = τ₂)
by (
apply rtype_fequal;
assumption).
rewrite <-
H3;
assumption.
eauto.
Qed.
Lemma recover_rec k d r τ
pf:
data_type d r ->
`
r =
Rec₀
k
(
map
(
fun x :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x, ` (
snd x))) τ) ->
data_type d (
Rec k τ
pf).
Proof.
intros.
assert (
Rec k τ
pf =
r).
unfold Rec.
apply rtype_fequal.
rewrite H0.
reflexivity.
rewrite H1;
assumption.
Qed.
Lemma recover_rec_forall k l r τ
pf:
Forall (
fun d :
data =>
data_type d r)
l ->
`
r =
Rec₀
k
(
map
(
fun x :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x, ` (
snd x))) τ) ->
Forall (
fun d :
data =>
data_type d (
Rec k τ
pf))
l.
Proof.
Lemma omap_concat_typed_env
(τ
env:
rtype) (τ₁ τ₂ τ₃:
list (
string *
rtype)) (
env:
data) (
dl2:
list data)
(
x :
list (
string *
data))
pf1 pf2 pf3:
(
data_type env τ
env) ->
(
forall x :
data,
In x dl2 ->
data_type x (
Rec Closed τ₂
pf2)) ->
rec_concat_sort τ₁ τ₂ = τ₃ ->
data_type (
drec x) (
Rec Closed τ₁
pf1) ->
(
exists y :
list data,
rmap (
fun x1 :
data =>
orecconcat (
drec x)
x1)
dl2
=
Some y /\
data_type (
dcoll y) (
Coll (
Rec Closed τ₃
pf3))).
Proof.
Lemma rproduct_typed_env {τ
env:
rtype} {τ₁ τ₂ τ₃:
list (
string *
rtype)} (
env:
data) (
dl dl0:
list data)
pf1 pf2 pf3:
data_type env τ
env ->
Forall (
fun d :
data =>
data_type d (
Rec Closed τ₂
pf2))
dl0 ->
Forall (
fun d :
data =>
data_type d (
Rec Closed τ₁
pf1))
dl ->
rec_concat_sort τ₁ τ₂ = τ₃ ->
exists x :
list data, (
rproduct dl dl0 =
Some x) /\
data_type (
dcoll x) (
Coll (
Rec Closed τ₃
pf3)).
Proof.
Lemma data_type_concat l1 l2 τ:
data_type (
dcoll l1) (
Coll τ) ->
data_type (
dcoll l2) (
Coll τ) ->
data_type (
dcoll (
l1 ++
l2)) (
Coll τ).
Proof.
intros.
dependent induction H.
dependent induction H0.
apply dtcoll.
apply Forall_app;
rewrite Forall_forall in *;
assert (
r = τ)
by (
apply rtype_fequal;
assumption);
assert (
r0 = τ)
by (
apply rtype_fequal;
assumption);
rewrite H1 in H;
rewrite H2 in H0;
assumption.
Qed.
Lemma rmap_concat_typed_env {τ
c} {τ
env:
rtype} {τ₁ τ₂ τ₃ :
list (
string *
rtype)} (
op1 :
nraenv_core)
c (
env:
data) (
dl:
list data)
pf1 pf2 pf3:
bindings_type c τ
c ->
env ▹ τ
env ->
rec_concat_sort τ₁ τ₂ = τ₃ ->
Forall (
fun d :
data =>
data_type d (
Rec Closed τ₁
pf1))
dl ->
(
op1 ▷
Rec Closed τ₁
pf1 >=>
Coll (
Rec Closed τ₂
pf2) ⊣ τ
c;τ
env) ->
(
forall d :
data,
data_type d (
Rec Closed τ₁
pf1) ->
exists x :
data,
brand_relation_brands ⊢ₑ
op1 @ₑ
d ⊣
c;
env =
Some x /\
data_type x (
Coll (
Rec Closed τ₂
pf2))) ->
exists x :
list data, (
rmap_concat (
nraenv_core_eval brand_relation_brands c op1 env)
dl =
Some x) /\
data_type (
dcoll x) (
Coll (
Rec Closed τ₃
pf3)).
Proof.
Lemma rmap_concat_typed2_env {τ
c} {τ
env:
rtype} {τ₁ τ₂ τ₃ :
list (
string *
rtype)} τ
in c (
op1 :
nraenv_core) (
env:
data)
y (
dl:
list data)
pf1 pf2 pf3:
bindings_type c τ
c ->
env▹ τ
env ->
rec_concat_sort τ₁ τ₂ = τ₃ ->
Forall (
fun d :
data =>
data_type d (
Rec Closed τ₁
pf1))
dl ->
(
op1 ▷ τ
in >=>
Coll (
Rec Closed τ₂
pf2) ⊣ τ
c;τ
env) ->
(
forall d :
data,
data_type d (
Rec Closed τ₁
pf1) ->
exists x :
data,
brand_relation_brands ⊢ₑ
op1 @ₑ
y ⊣
c;
env =
Some x /\
data_type x (
Coll (
Rec Closed τ₂
pf2))) ->
exists x :
list data, (
rmap_concat (
fun z =>
brand_relation_brands ⊢ₑ
op1@ₑ
y ⊣
c;
env)
dl =
Some x) /\
data_type (
dcoll x) (
Coll (
Rec Closed τ₃
pf3)).
Proof.
Main typing soundness theorem for NRAEnv
Theorem typed_nraenv_core_yields_typed_data {τ
c} {τ
env τ
in τ
out}
c (
env:
data) (
d:
data) (
op:
nraenv_core):
bindings_type c τ
c ->
(
env ▹ τ
env) -> (
d ▹ τ
in) -> (
op ▷ τ
in >=> τ
out ⊣ τ
c;τ
env) ->
(
exists x, (
brand_relation_brands ⊢ₑ
op @ₑ
d ⊣
c;
env =
Some x /\ (
x ▹ τ
out))).
Proof.
intros dt_c Henv.
intros.
revert env Henv d H.
dependent induction H0;
simpl;
intros.
ANTID *) -
exists d;
split; [
reflexivity|
assumption].
ANTConst *) -
exists (
RDataNorm.normalize_data brand_relation_brands c0);
split;
try reflexivity.
assumption.
ANTBinop *) -
elim (
IHnraenv_core_type1 env Henv d H0);
elim (
IHnraenv_core_type2 env Henv d H0);
intros.
elim H1;
elim H2;
intros;
clear H1 H2.
rewrite H3;
simpl.
rewrite H5;
simpl.
apply (
typed_binop_yields_typed_data x0 x b H4 H6);
assumption.
ANTUnop *) -
elim (
IHnraenv_core_type env Henv d H1);
intros.
elim H2;
intros;
clear H2.
rewrite H3.
apply (
typed_unop_yields_typed_data x u H4);
assumption.
ANTMap *) -
elim (
IHnraenv_core_type2 env Henv d H);
intros;
clear H IHnraenv_core_type2.
elim H0;
intros;
clear H0.
rewrite H;
clear H.
invcs H1.
rtype_equalizer.
subst.
assert (
EE :
exists x :
list data, (
rmap (
nraenv_core_eval brand_relation_brands c op1 env)
dl =
Some x)
/\
data_type (
dcoll x) (
Coll τ₂)).
+
apply (@
rmap_typed τ
c τ
env τ₁ τ₂
c op1 env dl dt_c Henv);
trivial.
apply IHnraenv_core_type1;
trivial.
+
destruct EE as [? [
eqq dt]].
simpl.
rewrite eqq;
simpl.
eexists;
split;
try reflexivity.
trivial.
ANTMapConcat *) -
elim (
IHnraenv_core_type2 env Henv d H0);
intros;
clear IHnraenv_core_type2 H0.
elim H1;
intros;
clear H1.
rewrite H0;
clear H0.
invcs H2.
assert (
EE :
exists x :
list data, (
rmap_concat (
nraenv_core_eval brand_relation_brands c op1 env)
dl =
Some x) /\
data_type (
dcoll x) (
Coll (
Rec Closed (
rec_concat_sort τ₁ τ₂)
pf3))).
+
apply (
rmap_concat_typed_env op1 c env dl pf1 pf2 pf3 dt_c Henv);
try assumption;
try reflexivity.
apply recover_rec_forall with (
r:=
r);
assumption.
apply IHnraenv_core_type1;
assumption.
+
destruct EE as [? [
eqq typ]].
simpl;
rewrite eqq;
simpl.
eexists;
split;
try reflexivity.
trivial.
ANTProduct *) -
elim (
IHnraenv_core_type1 env Henv d H0);
intros;
clear IHnraenv_core_type1.
elim H1;
intros;
clear H1.
rewrite H2;
clear H2;
invcs H3.
assert (
EE :
exists x :
list data, (
rmap_concat (
fun _ :
data =>
brand_relation_brands ⊢ₑ
op2 @ₑ
d ⊣
c;
env)
dl =
Some x) /\
data_type (
dcoll x) (
Coll (
Rec Closed (
rec_concat_sort τ₁ τ₂)
pf3))).
+
apply (@
rmap_concat_typed2_env τ
c τ
env τ₁ τ₂ (
rec_concat_sort τ₁ τ₂) τ
in c op2 env d dl pf1 pf2 pf3);
try assumption;
try reflexivity.
apply recover_rec_forall with (
r:=
r);
assumption.
destruct (
IHnraenv_core_type2 env Henv d H0)
as [? [
eqq dt]].
rewrite eqq.
intros.
eexists;
split;
try reflexivity.
trivial.
+
destruct EE as [? [
eqq typ]].
simpl;
rewrite eqq;
simpl.
eexists;
split;
try reflexivity.
trivial.
ANTSelect *) -
elim (
IHnraenv_core_type2 env Henv d H);
intros;
clear IHnraenv_core_type2.
elim H0;
intros;
clear H0.
rewrite H1;
clear H1 H0_0.
invcs H2.
rtype_equalizer.
subst.
assert (
exists c2,
(
lift_filter
(
fun x' :
data =>
match brand_relation_brands ⊢ₑ
op1 @ₑ
x' ⊣
c;
env with
|
Some (
dbool b) =>
Some b
|
_ =>
None
end)
dl) =
Some c2 /\
Forall (
fun d :
data =>
data_type d τ)
c2).
+
induction dl.
*
exists (@
nil data).
split.
reflexivity.
apply Forall_nil.
*
rewrite Forall_forall in *;
intros.
assert (
forall x :
data,
In x dl ->
data_type x τ)
by intuition.
assert (
data_type a τ)
by (
simpl in *;
intuition).
destruct (
IHnraenv_core_type1 env Henv a H1)
as [? [
eqq dt]].
simpl;
rewrite eqq;
simpl.
dtype_inverter.
destruct (
IHdl H0)
as [? [
eqq1 dt1]].
rewrite eqq1;
simpl.
assert (
data_type a τ)
by (
simpl in *;
intuition).
destruct x0;
simpl;
eexists;
split;
try reflexivity;
trivial.
constructor;
trivial.
+
destruct H0 as [? [
eqq dt]].
simpl;
rewrite eqq;
simpl.
eexists;
split;
try reflexivity;
trivial.
constructor;
trivial.
ANTDefault *) -
elim (
IHnraenv_core_type1 env Henv d H);
elim (
IHnraenv_core_type2 env Henv d H);
intros.
elim H0;
elim H1;
intros;
clear H0 H1 H.
rewrite H2.
rewrite H4.
clear H2 H4.
simpl.
invcs H3;
invcs H5;
rtype_equalizer.
subst.
destruct dl.
+
eexists;
split;
try reflexivity;
trivial.
constructor;
trivial.
+
eexists;
split;
try reflexivity;
trivial.
constructor;
trivial.
ANTEither *) -
destruct (
data_type_Either_inv H)
as [[
dd[?
ddtyp]]|[
dd[?
ddtyp]]];
subst;
eauto.
ANTEitherConcat *) -
destruct (
IHnraenv_core_type2 env Henv d H1)
as [? [??]].
rewrite H2.
destruct (
IHnraenv_core_type1 env Henv d H1)
as [? [??]].
rewrite H4.
destruct (
data_type_Rec_inv H3);
subst.
destruct (
data_type_Either_inv H5)
as [[
dd[?
ddtyp]]|[
dd[?
ddtyp]]];
subst;
eauto;
destruct (
data_type_Rec_inv ddtyp);
subst;
(
eexists;
split;[
reflexivity| ];
econstructor;
eapply dtrec_rec_concat_sort;
eauto).
ANTApp *) -
elim (
IHnraenv_core_type1 env Henv d H);
intros.
elim H0;
intros;
clear H0 H.
rewrite H1;
simpl.
elim (
IHnraenv_core_type2 env Henv x H2);
intros.
elim H;
intros;
clear H.
rewrite H0;
simpl.
exists x0;
split;[
reflexivity|
assumption].
ANTGetConstant *) -
unfold tdot in *.
unfold edot in *.
destruct (
Forall2_lookupr_some _ _ _ _ dt_c H)
as [? [
eqq1 eqq2]].
rewrite eqq1.
eauto.
ANTEnv *) -
exists env;
split; [
reflexivity|
assumption].
ANTAppEnv *) -
elim (
IHnraenv_core_type1 env Henv d H);
intros.
elim H0;
intros;
clear H0.
rewrite H1;
simpl.
elim (
IHnraenv_core_type2 x H2 d H);
intros.
elim H0;
intros;
clear H0.
rewrite H3;
simpl.
exists x0;
split;[
reflexivity|
assumption].
ANTMapEnv *) -
intros.
invcs Henv;
rtype_equalizer.
subst;
simpl.
assert (
exists x :
list data, (
rmap (
fun env' :
data => (
nraenv_core_eval brand_relation_brands c op1 env'
d))
dl =
Some x) /\
data_type (
dcoll x) (
Coll τ₂)).
*
apply (@
rmap_env_typed τ
c τ
env τ
in τ₂);
try assumption.
*
destruct H1 as [? [
eqq dt]].
rewrite eqq;
simpl.
eexists;
split;
try reflexivity;
trivial.
Qed.
Corrolaries of the main type soudness theorem
Definition typed_nraenv_core_total {τ
c} {τ
env τ
in τ
out} (
op:
nraenv_core) (
HOpT:
op ▷ τ
in >=> τ
out ⊣ τ
c;τ
env)
c (
env:
data) (
d:
data)
(
dt_c:
bindings_type c τ
c) :
(
env ▹ τ
env) ->
(
d ▹ τ
in) ->
{
x:
data |
x ▹ τ
out }.
Proof.
Definition tnraenv_core_eval {τ
c} {τ
env τ
in τ
out} (
op:
nraenv_core) (
HOpT:
op ▷ τ
in >=> τ
out ⊣ τ
c;τ
env)
c (
env:
data) (
d:
data)
(
dt_c:
bindings_type c τ
c) :
(
env ▹ τ
env) -> (
d ▹ τ
in) ->
data.
Proof.
Require Import NRASystem.
Auxiliary lemmas specific to some of the NRA expressions used in
the translation
Definition nra_context_type tbind tpid :
rtype :=
Rec Closed (("
PBIND"%
string,
tbind) :: ("
PDATA"%
string,
tpid) ::
nil) (
eq_refl _).
Lemma ATdot {
p s τ
c τ
in τ
pf τ
out}:
p ▷ τ
in >=>
Rec Closed τ
pf ⊣ τ
c ->
tdot τ
s =
Some τ
out ->
AUnop (
ADot s)
p ▷ τ
in >=> τ
out ⊣ τ
c.
Proof.
intros.
repeat econstructor; eauto.
Qed.
Lemma ATdot_inv {
p s τ
c τ
in τ
out}:
AUnop (
ADot s)
p ▷ τ
in >=> τ
out ⊣ τ
c ->
exists τ
pf k,
p ▷ τ
in >=>
Rec k τ
pf ⊣ τ
c /\
tdot τ
s =
Some τ
out.
Proof.
inversion 1; subst.
inversion H2; subst.
repeat econstructor; eauto.
Qed.
Lemma ATnra_data τ
c τ τ
in :
nra_data ▷
nra_context_type τ τ
in >=> τ
in ⊣ τ
c.
Proof.
eapply ATdot.
-
econstructor.
-
reflexivity.
Qed.
Lemma ATnra_data_inv'
k τ
c τ τ
in pf τ
out:
nra_data ▷
Rec k [("
PBIND"%
string, τ); ("
PDATA"%
string, τ
in)]
pf >=> τ
out ⊣ τ
c ->
τ
in = τ
out.
Proof.
unfold nra_data.
intros H.
inversion H;
clear H;
subst.
inversion H2;
clear H2;
subst.
inversion H5;
clear H5;
subst.
destruct τ';
inversion H3;
clear H3;
subst.
destruct τ';
inversion H4;
clear H4;
subst.
destruct τ';
inversion H6;
clear H6;
subst.
rtype_equalizer.
subst.
destruct p;
destruct p0;
simpl in *;
subst.
inversion H0;
trivial.
Qed.
Lemma ATnra_data_inv τ
c τ τ
in τ
out:
nra_data ▷
nra_context_type τ τ
in >=> τ
out ⊣ τ
c ->
τ
in = τ
out.
Proof.
Hint Constructors nra_type unaryOp_type binOp_type.
Hint Resolve ATdot ATnra_data.
Lemma ATunnest_two (
s1 s2:
string) (
op:
NRA.nra) τ
c τ
in τ₁
pf1 τ
s τ
rem pf2 :
op ▷ τ
in >=> (
Coll (
Rec Closed τ₁
pf1)) ⊣ τ
c ->
tdot τ₁
s1 =
Some (
Coll τ
s) ->
τ
rem = (
rremove (
rec_concat_sort τ₁ ((
s2,τ
s)::
nil))
s1) ->
NRAExt.unnest_two s1 s2 op ▷
τ
in >=>
Coll (
Rec Closed τ
rem pf2) ⊣ τ
c.
Proof.
intros;
subst.
econstructor;
eauto.
Grab Existential Variables.
eauto.
unfold rec_concat_sort.
eauto.
Qed.
Ltac nra_inverter :=
match goal with
| [
H:
Coll _ =
Coll _ |-
_] =>
inversion H;
clear H
| [
H: `?τ₁ =
Coll₀ (`?τ₂) |-
_] =>
rewrite (
Coll_right_inv τ₁ τ₂)
in H;
subst
| [
H:
Coll₀ (`?τ₂) = `?τ₁ |-
_] =>
symmetry in H
| [
H:@
nra_type _ _ AID _ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
AMap _ _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
AMapConcat _ _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
AEither _ _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
AEitherConcat _ _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
ARecEither _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
ADefault _ _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
AApp _ _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
AProduct _ _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
ASelect _ _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
AUnop _ _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
ABinop _ _ _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
AConst _)
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:@
nra_type _ _ (
nra_data)
_ _ |-
_ ] =>
apply ATnra_data_inv'
in H
| [
H:@
nra_type _ _ (
nra_data) (
nra_context_type _ _)
_ |-
_ ] =>
apply ATnra_data_inv in H
| [
H: (
_,
_) = (
_,
_) |-
_ ] =>
inversion H;
clear H
| [
H:
map (
fun x2 :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x2, ` (
snd x2))) ?
x0 = [] |-
_] =>
apply (
map_rtype_nil x0)
in H;
simpl in H;
subst
| [
H: (
map
(
fun x :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x,
proj1_sig (
snd x)))
_)
=
(
map
(
fun x' :
string * {τ₀' :
rtype₀ |
wf_rtype₀ τ₀' =
true} =>
(
fst x',
proj1_sig (
snd x')))
_) |-
_ ] =>
apply map_rtype_fequal in H;
trivial
| [
H:
Rec _ _ _ =
Rec _ _ _ |-
_ ] =>
generalize (
Rec_inv H);
clear H;
intro H;
try subst
| [
H:
context [(
_::
nil) =
map
(
fun x :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x,
proj1_sig (
snd x)))
_] |-
_] =>
symmetry in H
| [
H:
context [
map
(
fun x :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x,
proj1_sig (
snd x)))
_ = (
_::
_) ] |-
_] =>
apply map_eq_cons in H;
destruct H as [? [? [? [??]]]]
| [
H:
Coll₀
_ =
Coll₀
_ |-
_ ] =>
inversion H;
clear H
| [
H:
Rec₀
_ _ =
Rec₀
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:
nraenv_core_type _ _ (
snd ?
x)
_ |-
_] =>
destruct x;
simpl in *;
subst
| [
H:
unaryOp_type AColl _ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type AFlatten _ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type (
ARec _)
_ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type (
ADot _)
_ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type (
ARecRemove _)
_ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type ARight _ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type ALeft _ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
binOp_type AConcat _ _ _ |-
_ ] =>
inversion H;
clear H
| [
H:
binOp_type AAnd _ _ _ |-
_ ] =>
inversion H;
clear H
| [
H:
binOp_type AMergeConcat _ _ _ |-
_ ] =>
inversion H;
clear H
end;
try rtype_equalizer;
try assumption;
try subst;
simpl in *;
try nra_inverter.
Lemma ATunnest_two_inv (
s1 s2:
string) (
op:
NRA.nra) τ
c τ
in rec :
unnest_two s1 s2 op ▷
τ
in >=>
Coll rec ⊣ τ
c ->
exists τ₁
pf1 τ
s τ
rem pf2,
op ▷ τ
in >=> (
Coll (
Rec Closed τ₁
pf1)) ⊣ τ
c /\
tdot τ₁
s1 =
Some (
Coll τ
s) /\
rec = (
Rec Closed τ
rem pf2) /\
τ
rem = (
rremove (
rec_concat_sort τ₁ ((
s2,τ
s)::
nil))
s1).
Proof.
unfold unnest_two.
intros H.
nra_inverter.
destruct x;
simpl in *.
repeat eexists;
intuition;
eauto.
Qed.
Lemma ATRecEither s τ
c τ
l τ
r pf1 pf2:
nra_type τ
c (
ARecEither s) (
Either τ
l τ
r)
(
Either
(
Rec Closed ((
s,τ
l)::
nil)
pf1)
(
Rec Closed ((
s,τ
r)::
nil)
pf2)).
Proof.
econstructor; eauto.
Qed.
Theorem typed_nraenv_core_to_typed_nra {τ
c} {τ
env τ
in τ
out} (
op:
nraenv_core):
(
nraenv_core_type τ
c op τ
env τ
in τ
out) -> (
nra_type τ
c (
nra_of_nraenv_core op) (
nra_context_type τ
env τ
in) τ
out).
Proof.
intros.
dependent induction H;
simpl;
intros.
ANID *) -
eauto.
ANConst *) -
eauto.
ANBinop *) -
eauto.
ANUnop *) -
eauto.
ANMap *) -
apply (@
ATMap m τ
c (
nra_context_type τ
env τ
in) (
nra_context_type τ
env τ₁) τ₂);
try assumption.
eapply ATunnest_two.
eapply (
ATUnop).
eauto.
unfold nra_wrap_a1,
nra_double.
eapply ATBinop.
eauto.
eapply (
ATUnop).
eauto.
eapply ATUnop;
eauto.
eapply ATDot.
unfold tdot,
edot;
simpl.
auto.
eapply (
ATUnop).
eauto.
eauto.
unfold tdot,
edot;
auto.
reflexivity.
reflexivity.
ANMapConcat *) -
apply (@
ATMap m τ
c (
nra_context_type τ
env τ
in) (
Rec Closed (("
PBIND"%
string, τ
env) :: ("
PDATA"%
string, (
Rec Closed τ₁
pf1)) :: ("
PDATA2"%
string, (
Rec Closed τ₂
pf2)) ::
nil) (
eq_refl _))).
econstructor;
eauto.
econstructor;
eauto.
econstructor;
eauto.
reflexivity.
econstructor;
eauto.
econstructor;
eauto.
reflexivity.
apply (@
ATMapConcat m τ
c (
nra_context_type τ
env τ
in)
[("
PBIND"%
string, τ
env); ("
PDATA"%
string,
Rec Closed τ₁
pf1)]
[("
PDATA2"%
string, (
Rec Closed τ₂
pf2))]
[("
PBIND"%
string, τ
env); ("
PDATA"%
string,
Rec Closed τ₁
pf1); ("
PDATA2"%
string,
Rec Closed τ₂
pf2)]
(
AMap (
AUnop (
ARec "
PDATA2")
AID) (
nra_of_nraenv_core op1))
(
unnest_two "
a1" "
PDATA" (
AUnop AColl (
nra_wrap_a1 (
nra_of_nraenv_core op2))))
eq_refl eq_refl
);
try reflexivity.
eauto.
unfold nra_wrap_a1.
apply (
ATunnest_two "
a1" "
PDATA" (
AUnop AColl (
nra_double "
PBIND" "
a1"
nra_bind (
nra_of_nraenv_core op2))) τ
c (
nra_context_type τ
env τ
in) [("
PBIND"%
string, τ
env); ("
a1"%
string,
Coll (
Rec Closed τ₁
pf1))]
eq_refl (
Rec Closed τ₁
pf1));
try reflexivity.
apply (@
ATUnop m τ
c (
nra_context_type τ
env τ
in) (
Rec Closed [("
PBIND"%
string, τ
env); ("
a1"%
string,
Coll (
Rec Closed τ₁
pf1))]
eq_refl)).
econstructor;
eauto.
unfold nra_double,
nra_bind.
apply (@
ATBinop m τ
c (
nra_context_type τ
env τ
in) (
Rec Closed [("
PBIND"%
string, τ
env)]
eq_refl) (
Rec Closed [("
a1"%
string,
Coll (
Rec Closed τ₁
pf1))]
eq_refl));
try eauto.
econstructor;
eauto.
econstructor;
eauto.
econstructor;
eauto.
ANProduct *) -
eauto.
ANSelect *) -
econstructor;
eauto.
econstructor;
eauto.
eapply ATunnest_two.
+
econstructor;
eauto.
unfold nra_wrap_a1,
nra_double.
eapply ATBinop.
*
econstructor;
reflexivity.
*
econstructor;
eauto.
econstructor;
eauto.
econstructor;
eauto.
reflexivity.
*
econstructor;
eauto.
+
reflexivity.
+
unfold rremove;
reflexivity.
ANDefault *) -
eauto.
ANTEither *) -
econstructor.
+
econstructor;
try reflexivity.
* {
econstructor.
-
econstructor;
eauto.
econstructor;
eauto.
reflexivity.
-
econstructor;
eauto.
}
* {
econstructor;
eauto.
-
econstructor;
eauto.
econstructor;
eauto.
econstructor;
eauto.
}
+
econstructor;
eauto.
ANEitherConcat *) -
eauto.
ANApp *) -
apply (@
ATApp m τ
c (
nra_context_type τ
env τ
in) (
nra_context_type τ
env τ1) τ2).
+
unfold nra_context,
nra_bind,
nra_context_type,
nra_double;
simpl.
unfold nra_wrap.
apply (@
ATBinop m τ
c (
Rec Closed [("
PBIND"%
string, τ
env); ("
PDATA"%
string, τ
in)]
eq_refl) (
Rec Closed (("
PBIND"%
string, τ
env)::
nil) (
eq_refl _)) (
Rec Closed (("
PDATA"%
string, τ1)::
nil) (
eq_refl _))).
econstructor;
eauto.
econstructor;
eauto.
econstructor;
eauto.
econstructor;
eauto.
econstructor;
eauto.
+
trivial.
ANGetConstant *) -
unfold nra_bind,
nra_context_type.
econstructor;
eauto.
ANEnv *) -
unfold nra_bind,
nra_context_type.
eauto.
ANAppEnv *) -
apply (@
ATApp m τ
c (
nra_context_type τ
env τ
in) (
nra_context_type τ
env' τ
in) τ2).
+
unfold nra_context,
nra_bind,
nra_context_type,
nra_double;
simpl.
apply (@
ATBinop m τ
c (
Rec Closed [("
PBIND"%
string, τ
env); ("
PDATA"%
string, τ
in)]
eq_refl) (
Rec Closed (("
PBIND"%
string, τ
env')::
nil) (
eq_refl _)) (
Rec Closed (("
PDATA"%
string, τ
in)::
nil) (
eq_refl _))).
econstructor;
eauto.
do 3 (
econstructor;
eauto).
do 3 (
econstructor;
eauto).
+
trivial.
ANMapEnv *) -
econstructor;
eauto.
eapply ATunnest_two.
+
econstructor;
eauto.
unfold nra_wrap_bind_a1,
nra_double.
eapply ATBinop;
eauto.
*
do 3 (
econstructor;
eauto).
reflexivity.
+
reflexivity.
+
simpl;
trivial.
Grab Existential Variables.
eauto.
eauto.
eauto.
eauto.
eauto.
eauto.
eauto.
eauto.
eauto.
eauto.
eauto.
eauto.
Qed.
Lemma fold_nra_context_type (
env d: {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true})
pf :
Rec Closed [("
PBIND"%
string,
env); ("
PDATA"%
string,
d)]
pf
=
nra_context_type env d.
Proof.
Ltac defst l
:=
match l with
| @
nil (
string*
rtype₀) =>
constr:(@
nil (
string*
rtype))
|
cons (?
x,
proj1_sig ?
y) ?
l' =>
let l'' :=
defst l'
in
constr:(
cons (
x,
y)
l'')
end.
Ltac rec_proj_simpler
:=
repeat
match goal with
| [
H:
Rec₀ ?
k ?
l =
proj1_sig ?τ |-
_ ] =>
symmetry in H
| [
H:
proj1_sig ?τ =
Rec₀ ?
k ?
l |-
_ ] =>
let ll :=
defst l in
let HH:=
fresh "
eqq"
in
generalize (@
Rec₀
_eq_proj1_Rec _ _ τ
k ll);
intros HH;
simpl in HH;
specialize (
HH H);
clear H;
destruct HH;
try subst τ
end.
Require Import Eqdep_dec.
Require Import Bool.
Lemma UIP_bool {
a b:
bool} (
pf1 pf2:
a =
b) :
pf1 =
pf2.
Proof.
Ltac nra_inverter_ext
:=
simpl in *;
match goal with
| [
H:@
nra_type _ _ (
unnest_two _ _ _)
_ (
Coll _) |-
_ ] =>
apply ATunnest_two_inv in H;
destruct H as [? [? [? [? [? [? [?[??]]]]]]]]
| [
H:
prod _ _ |-
_ ] =>
destruct H;
simpl in *;
try subst
| [
H:
context [
Rec Closed [("
PBIND"%
string, ?
env); ("
PDATA"%
string, ?
d)] ?
pf ] |-
_ ] =>
unfold rtype in H;
rewrite (
fold_nra_context_type env d pf)
in H
| [
H:
Rec₀ ?
k ?
l =
proj1_sig ?τ |-
_ ] =>
symmetry in H
| [
H:
proj1_sig ?τ =
Rec₀ ?
k ?
l |-
_ ] =>
let ll :=
defst l in
let HH:=
fresh "
eqq"
in
generalize (@
Rec₀
_eq_proj1_Rec _ _ τ
k ll);
intros HH;
simpl in HH;
specialize (
HH H);
clear H;
destruct HH;
try subst τ
| [
H:
proj1_sig _ =
Rec₀
Closed
(
map
(
fun x :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x, ` (
snd x)))
_) |-
_ ]
=>
let Hpf :=
fresh "
spf"
in
apply Rec₀
_eq_proj1_Rec in H;
destruct H as [?
Hpf]
| [
H1:@
eq bool ?
a ?
b,
H2:@
eq bool ?
a ?
b |-
_] =>
destruct (
UIP_bool H1 H2)
end.
Ltac nra_inverter2 :=
repeat (
try unfold nra_wrap,
nra_wrap_a1,
nra_wrap_bind_a1,
nra_context,
nra_double,
nra_bind,
nra_wrap in *; (
nra_inverter_ext ||
nra_inverter);
try subst).
Ltac tdot_inverter :=
repeat
match goal with
| [
H:
tdot _ _ =
Some _ |-
_ ] =>
let HH:=
fresh "
eqq"
in
inversion H as [
HH];
match type of HH with
| ?
x1 = ?
x2 =>
try (
subst x2 ||
subst x1);
clear H
|
_ =>
fail 1
end
end.
Lemma typed_nraenv_core_to_typed_nra_inv' {
k τ
c τ
env τ
in τ
out pf} (
op:
nraenv_core):
nra_type τ
c (
nra_of_nraenv_core op) (
Rec k [("
PBIND"%
string, τ
env); ("
PDATA"%
string, τ
in)]
pf) τ
out ->
nraenv_core_type τ
c op τ
env τ
in τ
out.
Proof.
Hint Constructors nraenv_core_type.
revert k τ
env τ
in τ
out pf.
induction op;
simpl;
intros.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
inversion H;
clear H;
subst.
econstructor;
trivial.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
-
nra_inverter2;
try tdot_inverter;
eauto.
Qed.
Theorem typed_nraenv_core_to_typed_nra_inv {τ
c} {τ
env τ
in τ
out} (
op:
nraenv_core):
nra_type τ
c (
nra_of_nraenv_core op) (
nra_context_type τ
env τ
in) τ
out ->
nraenv_core_type τ
c op τ
env τ
in τ
out.
Proof.
Lemma typed_nraenv_core_const_sort_f {τ
c op τ
env τ
in τ
out} :
nraenv_core_type (
rec_sort τ
c)
op τ
env τ
in τ
out ->
nraenv_core_type τ
c op τ
env τ
in τ
out.
Proof.
Lemma typed_nraenv_core_const_sort_b {τ
c op τ
env τ
in τ
out} :
nraenv_core_type τ
c op τ
env τ
in τ
out ->
nraenv_core_type (
rec_sort τ
c)
op τ
env τ
in τ
out.
Proof.
Lemma typed_nraenv_core_const_sort τ
c op τ
env τ
in τ
out :
nraenv_core_type (
rec_sort τ
c)
op τ
env τ
in τ
out <->
nraenv_core_type τ
c op τ
env τ
in τ
out.
Proof.
End TcNRAEnv.
Notation "
Op ▷
A >=>
B ⊣
C ;
E" := (
nraenv_core_type C Op E A B) (
at level 70).
Notation "
Op @▷
d ⊣
C ;
e" := (
tnraenv_core_eval C Op e d) (
at level 70).
Hint Constructors nraenv_core_type.
Hint Constructors unaryOp_type.
Hint Constructors binOp_type.
Ltac nraenv_core_inverter :=
match goal with
| [
H:
Coll _ =
Coll _ |-
_] =>
inversion H;
clear H
| [
H: `?τ₁ =
Coll₀ (`?τ₂) |-
_] =>
rewrite (
Coll_right_inv τ₁ τ₂)
in H;
subst
| [
H:
Coll₀ (`?τ₂) = `?τ₁ |-
_] =>
symmetry in H
| [
H:
ANID ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANEnv ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANMap _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANMapConcat _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANMapEnv _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANDefault _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANApp _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANAppEnv _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANEither _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANEitherConcat _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANProduct _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANSelect _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANUnop _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANBinop _ _ _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H:
ANConst _ ▷
_ >=>
_ ⊣
_ ;
_ |-
_ ] =>
inversion H;
clear H
| [
H: (
_,
_) = (
_,
_) |-
_ ] =>
inversion H;
clear H
| [
H:
map (
fun x2 :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x2, ` (
snd x2))) ?
x0 = [] |-
_] =>
apply (
map_rtype_nil x0)
in H;
simpl in H;
subst
| [
H: (
map
(
fun x :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x,
proj1_sig (
snd x)))
_)
=
(
map
(
fun x' :
string * {τ₀' :
rtype₀ |
wf_rtype₀ τ₀' =
true} =>
(
fst x',
proj1_sig (
snd x')))
_) |-
_ ] =>
apply map_rtype_fequal in H;
trivial
| [
H:
Rec _ _ _ =
Rec _ _ _ |-
_ ] =>
generalize (
Rec_inv H);
clear H;
intro H;
try subst
| [
H:
context [(
_::
nil) =
map
(
fun x :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x,
proj1_sig (
snd x)))
_] |-
_] =>
symmetry in H
| [
H:
context [
map
(
fun x :
string * {τ₀ :
rtype₀ |
wf_rtype₀ τ₀ =
true} =>
(
fst x,
proj1_sig (
snd x)))
_ = (
_::
nil) ] |-
_] =>
apply map_eq_cons in H;
destruct H as [? [? [? [??]]]]
| [
H:
Coll₀
_ =
Coll₀
_ |-
_ ] =>
inversion H;
clear H
| [
H:
Rec₀
_ _ =
Rec₀
_ _ |-
_ ] =>
inversion H;
clear H
| [
H:
_ ▷
_ >=>
snd ?
x ⊣
_ ;
_ |-
_] =>
destruct x;
simpl in *;
subst
| [
H:
unaryOp_type AColl _ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type AFlatten _ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type (
ARec _)
_ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type (
ADot _)
_ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type (
ARecProject _)
_ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type (
ARecRemove _)
_ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type ALeft _ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
unaryOp_type ARight _ _ |-
_ ] =>
inversion H;
clear H;
subst
| [
H:
binOp_type AConcat _ _ _ |-
_ ] =>
inversion H;
clear H
| [
H:
binOp_type AAnd _ _ _ |-
_ ] =>
inversion H;
clear H
| [
H:
binOp_type AMergeConcat _ _ _ |-
_ ] =>
inversion H;
clear H
end;
try rtype_equalizer;
try assumption;
try subst;
simpl in *;
try nraenv_core_inverter.
Ltac nraenv_core_inferer :=
try nraenv_core_inverter;
subst;
try eauto.
Ltac input_well_typed :=
repeat progress
match goal with
| [
HO:?
op ▷ ?τ
in >=> ?τ
out ⊣ ?τ
c ; ?τ
env,
HI:?
x ▹ ?τ
in,
HC:
bindings_type ?
c ?τ
c,
HE:?
env ▹ ?τ
env
|-
context [(
nraenv_core_eval ?
h ?
c ?
op ?
env ?
x)]] =>
let xout :=
fresh "
dout"
in
let xtype :=
fresh "τ
out"
in
let xeval :=
fresh "
eout"
in
destruct (
typed_nraenv_core_yields_typed_data c _ _ op HC HE HI HO)
as [
xout [
xeval xtype]];
rewrite xeval in *;
simpl
end.