Require Import String.
Require Import List.
Require Import Arith.
Require Import Program.
Require Import EquivDec.
Require Import Morphisms.
Require Import BasicSystem.
Require Import DNNRCSystem.
Require Import tDNNRC.
Section tDNNRCSub.
Context {
m:
basic_model}.
Section typ.
Inductive dnnrc_type_sub {
A plug_type:
Set}
{
plug:
AlgPlug plug_type} {
tplug:
TAlgPlug} :
tdbindings -> @
dnnrc _ A plug_type ->
drtype ->
Prop :=
|
TDNNRCVar {τ}
tenv v :
forall (
a:
A),
lookup equiv_dec tenv v =
Some τ ->
dnnrc_type_sub tenv (
DNNRCVar a v) τ
|
TDNNRCConst {τ}
tenv c :
forall (
a:
A),
data_type (
normalize_data brand_relation_brands c) τ ->
dnnrc_type_sub tenv (
DNNRCConst a c) (
Tlocal τ)
|
TDNNRCBinop {τ₁ τ₂ τ}
tenv b e1 e2 :
forall (
a:
A),
binOp_type b τ₁ τ₂ τ ->
dnnrc_type_sub tenv e1 (
Tlocal τ₁) ->
dnnrc_type_sub tenv e2 (
Tlocal τ₂) ->
dnnrc_type_sub tenv (
DNNRCBinop a b e1 e2) (
Tlocal τ)
|
TDNNRCUnop {τ₁ τ}
tenv u e1 :
forall (
a:
A),
unaryOp_type u τ₁ τ ->
dnnrc_type_sub tenv e1 (
Tlocal τ₁) ->
dnnrc_type_sub tenv (
DNNRCUnop a u e1) (
Tlocal τ)
|
TDNNRCLet {τ₁ τ₂}
v tenv e1 e2 :
forall (
a:
A),
dnnrc_type_sub tenv e1 τ₁ ->
dnnrc_type_sub ((
v,τ₁)::
tenv)
e2 τ₂ ->
dnnrc_type_sub tenv (
DNNRCLet a v e1 e2) τ₂
|
TDNRCForLocal {τ₁ τ₂}
v tenv e1 e2 :
forall (
a:
A),
dnnrc_type_sub tenv e1 (
Tlocal (
Coll τ₁)) ->
dnnrc_type_sub ((
v,(
Tlocal τ₁))::
tenv)
e2 (
Tlocal τ₂) ->
dnnrc_type_sub tenv (
DNNRCFor a v e1 e2) (
Tlocal (
Coll τ₂))
|
TDNRCForDist {τ₁ τ₂}
v tenv e1 e2 :
forall (
a:
A),
dnnrc_type_sub tenv e1 (
Tdistr τ₁) ->
dnnrc_type_sub ((
v,(
Tlocal τ₁))::
tenv)
e2 (
Tlocal τ₂) ->
dnnrc_type_sub tenv (
DNNRCFor a v e1 e2) (
Tdistr τ₂)
|
TDNRCIf {τ}
tenv e1 e2 e3 :
forall (
a:
A),
dnnrc_type_sub tenv e1 (
Tlocal Bool) ->
dnnrc_type_sub tenv e2 τ ->
dnnrc_type_sub tenv e3 τ ->
dnnrc_type_sub tenv (
DNNRCIf a e1 e2 e3) τ
|
TDNNRCEither {τ τ
l τ
r}
tenv ed xl el xr er :
forall (
a:
A),
dnnrc_type_sub tenv ed (
Tlocal (
Either τ
l τ
r)) ->
dnnrc_type_sub ((
xl,(
Tlocal τ
l))::
tenv)
el τ ->
dnnrc_type_sub ((
xr,(
Tlocal τ
r))::
tenv)
er τ ->
dnnrc_type_sub tenv (
DNNRCEither a ed xl el xr er) τ
|
TDNNRCCollect {τ}
tenv e :
forall (
a:
A),
dnnrc_type_sub tenv e (
Tdistr τ) ->
dnnrc_type_sub tenv (
DNNRCCollect a e) (
Tlocal (
Coll τ))
|
TDNNRCDispatch {τ}
tenv e :
forall (
a:
A),
dnnrc_type_sub tenv e (
Tlocal (
Coll τ)) ->
dnnrc_type_sub tenv (
DNNRCDispatch a e) (
Tdistr τ)
|
TDNNRCAlg {τ
out}
tenv tbindings op nl :
forall (
a:
A),
Forall2 (
fun n τ =>
fst n =
fst τ
/\
dnnrc_type_sub tenv (
snd n) (
Tdistr (
snd τ)))
nl tbindings ->
plug_typing op tbindings (
Coll τ
out) ->
dnnrc_type_sub tenv (
DNNRCAlg a op nl) (
Tdistr τ
out)
|
TDNNRCSubsumption {τ
env τ
out} τ
env' τ
out'
e:
tdbindings_sub τ
env' τ
env ->
drtype_sub τ
out τ
out' ->
dnnrc_type_sub τ
env e τ
out ->
dnnrc_type_sub τ
env'
e τ
out'
.
Global Instance dnnrc_type_sub_proper {
A plug_type:
Set} {
plug:
AlgPlug plug_type} {
tplug:
TAlgPlug} :
Proper (
tdbindings_sub -->
eq ==>
drtype_sub ==>
impl) (
dnnrc_type_sub (
A:=
A)).
Proof.
Global Instance dbindings_type_proper :
Proper (
eq ==>
tdbindings_sub ==>
impl)
dbindings_type.
Proof.
unfold Proper,
respectful,
flip,
impl,
tdbindings_sub,
dbindings_type;
intros.
subst.
revert y y0 H0 H1.
induction x0;
intros x y0 F1 F2
;
invcs F1;
invcs F2;
trivial.
destruct a;
destruct y;
destruct x1;
intuition;
simpl in *;
subst.
rewrite H0 in H2.
auto.
Qed.
End typ.
Section lift.
Lemma dnnrc_type_to_dnnrc_type_sub {
A} (
plug_type:
Set) (
plug:
AlgPlug plug_type) {
tplug:
TAlgPlug} {τ} (
env:
dbindings) (
tenv:
tdbindings) (
e:@
dnnrc _ A plug_type) :
dnnrc_type tenv e τ ->
dnnrc_type_sub tenv e τ.
Proof.
Hint Constructors dnnrc_type_sub.
revert tenv τ.
induction e;
simpl;
intros tenv τ
dt;
invcs dt;
eauto.
-
econstructor;
try eassumption.
revert H5.
apply Forall2_incl.
rewrite Forall_forall in H.
intros ? ?
inn1 inn2 [
eqq1 eqq2].
auto.
Qed.
End lift.
Main lemma for the type correctness of DNNNRC
Theorem typed_dnnrc_yields_typed_data {
A} {
plug_type:
Set} (
plug:
AlgPlug plug_type) {
tplug:
TAlgPlug} {τ} (
env:
dbindings) (
tenv:
tdbindings) (
e:@
dnnrc _ A plug_type) :
dbindings_type env tenv ->
dnnrc_type_sub tenv e τ ->
(
exists x, (
dnnrc_eval brand_relation_brands env e) =
Some x /\ (
ddata_type x τ)).
Proof.
intros.
revert env H.
dependent induction H0;
simpl;
intros.
-
unfold dbindings_type in *.
dependent induction H0.
simpl in *;
congruence.
simpl in *.
destruct x;
simpl in *.
elim H0;
clear H0;
intros.
destruct y;
simpl in *.
rewrite H0 in *;
clear H0.
revert H.
elim (
equiv_dec v s0);
intros.
exists d.
inversion H.
rewrite H3 in *;
clear H3 H a.
split; [
reflexivity|
assumption].
specialize (
IHForall2 H);
clear H.
assumption.
-
exists (
Dlocal (
normalize_data brand_relation_brands c)).
intros.
split; [
reflexivity|
constructor;
assumption].
-
specialize (
IHdnnrc_type_sub1 env H0);
specialize (
IHdnnrc_type_sub2 env H0).
elim IHdnnrc_type_sub1;
intros;
clear IHdnnrc_type_sub1;
elim IHdnnrc_type_sub2;
intros;
clear IHdnnrc_type_sub2.
elim H1;
clear H1;
intros.
elim H2;
clear H2;
intros.
rewrite H1;
rewrite H2.
simpl.
inversion H3;
clear H3;
subst.
inversion H4;
clear H4;
subst.
elim (@
typed_binop_yields_typed_data _ _ _ _ _ _ _ _ τ₁ τ₂ τ
_ _ b H7 H6 H);
intros.
elim H3;
clear H3;
intros.
exists (
Dlocal x);
simpl.
split.
+
rewrite H3;
reflexivity.
+
constructor;
assumption.
-
specialize (
IHdnnrc_type_sub env H1).
elim IHdnnrc_type_sub;
intros;
clear IHdnnrc_type_sub.
elim H2;
clear H2;
intros.
rewrite H2;
clear H2.
inversion H3;
clear H3;
intros;
subst.
elim (@
typed_unop_yields_typed_data _ _ _ _ _ _ _ _ τ₁ τ
_ u H5 H);
intros.
elim H2;
clear H2;
intros.
exists (
Dlocal x);
simpl.
split.
+
rewrite H2;
reflexivity.
+
constructor;
assumption.
-
destruct (
IHdnnrc_type_sub1 _ H)
as [?[
re1 ?]].
destruct (
IHdnnrc_type_sub2 ((
v,
x)::
env))
as [?[
re2 ?]].
+
apply Forall2_cons;
intuition.
+
unfold var in *.
rewrite re1.
assert ((@
dnnrc_eval (@
basic_model_runtime m)
A plug_type
(@
brand_relation_brands
(@
brand_model_relation (@
basic_model_foreign_type m)
(@
basic_model_brand_model m)))
plug
(@
cons
(
prod DNNRCBase.var (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m))))
(@
pair DNNRCBase.var (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
v x)
env)
e2) = (@
dnnrc_eval (@
basic_model_runtime m)
A plug_type
(@
brand_relation_brands
(@
brand_model_relation (@
basic_model_foreign_type m)
(@
basic_model_brand_model m)))
plug
(@
cons (
prod string (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m))))
(@
pair string (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
v x)
env)
e2))
by reflexivity.
rewrite <-
H2 in re2;
clear H2.
rewrite re2.
eauto.
-
specialize (
IHdnnrc_type_sub1 env H).
elim IHdnnrc_type_sub1;
intros;
clear IHdnnrc_type_sub1.
elim H0;
clear H0;
intros.
rewrite H0;
clear H0;
simpl.
inversion H1;
clear H1;
subst.
dependent induction H3.
induction dl;
simpl in *.
+
exists (
Dlocal (
dcoll [])).
split; [
reflexivity|].
constructor;
apply dtcoll;
apply Forall_nil.
+
rewrite Forall_forall in *.
simpl in H0.
assert (
forall x :
data,
In x dl ->
data_type x r)
by (
intros;
apply (
H0 x0);
right;
assumption).
specialize (
IHdl H1);
clear H1.
elim IHdl;
intros;
clear IHdl.
elim H1;
clear H1;
intros.
unfold lift in H1.
unfold var in *.
assert (
exists x1,
rmap
(
fun d1 :
data =>
olift checkLocal
(
dnnrc_eval brand_relation_brands ((
v,
Dlocal d1) ::
env)
e2))
dl =
Some x1 /\ (
Dlocal (
dcoll x1)) =
x0).
revert H1.
assert (@
rmap (@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(
fun d1 : @
data (@
foreign_runtime_data (@
basic_model_runtime m)) =>
@
olift (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
checkLocal (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
dnnrc_eval (@
basic_model_runtime m)
A plug_type
(@
brand_relation_brands
(@
brand_model_relation (@
basic_model_foreign_type m)
(@
basic_model_brand_model m)))
plug
(@
cons
(
prod DNNRCBase.var
(@
ddata (@
foreign_runtime_data (@
basic_model_runtime m))))
(@
pair DNNRCBase.var
(@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
v
(@
Dlocal (@
foreign_runtime_data (@
basic_model_runtime m))
d1))
env)
e2))
dl = (@
rmap (@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(
fun d1 : @
data (@
foreign_runtime_data (@
basic_model_runtime m)) =>
@
olift (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
checkLocal (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
dnnrc_eval (@
basic_model_runtime m)
A plug_type
(@
brand_relation_brands
(@
brand_model_relation (@
basic_model_foreign_type m)
(@
basic_model_brand_model m)))
plug
(@
cons
(
prod string (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m))))
(@
pair string (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
v
(@
Dlocal (@
foreign_runtime_data (@
basic_model_runtime m))
d1))
env)
e2))
dl))
by reflexivity.
rewrite H1;
clear H1.
elim (
rmap
(
fun d1 :
data =>
olift checkLocal
(
dnnrc_eval brand_relation_brands ((
v,
Dlocal d1) ::
env)
e2))
dl);
intros.
inversion H1;
simpl in *.
subst;
clear H1;
exists a1;
split;
congruence.
congruence.
elim H3;
clear H3;
intros.
elim H3;
clear H3;
intros.
assert ((@
rmap (@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(
fun d1 : @
data (@
foreign_runtime_data (@
basic_model_runtime m)) =>
@
olift (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
checkLocal (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
dnnrc_eval (@
basic_model_runtime m)
A plug_type
(@
brand_relation_brands
(@
brand_model_relation (@
basic_model_foreign_type m)
(@
basic_model_brand_model m)))
plug
(@
cons
(
prod string (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m))))
(@
pair string (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
v
(@
Dlocal (@
foreign_runtime_data (@
basic_model_runtime m))
d1))
env)
e2))
dl) = (@
rmap (@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(
fun d1 : @
data (@
foreign_runtime_data (@
basic_model_runtime m)) =>
@
olift (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
data (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
checkLocal (@
foreign_runtime_data (@
basic_model_runtime m)))
(@
dnnrc_eval (@
basic_model_runtime m)
A plug_type
(@
brand_relation_brands
(@
brand_model_relation (@
basic_model_foreign_type m)
(@
basic_model_brand_model m)))
plug
(@
cons
(
prod DNNRCBase.var
(@
ddata (@
foreign_runtime_data (@
basic_model_runtime m))))
(@
pair DNNRCBase.var
(@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
v
(@
Dlocal (@
foreign_runtime_data (@
basic_model_runtime m))
d1))
env)
e2))
dl))
by reflexivity.
rewrite <-
H5;
clear H5.
rewrite H3.
rewrite <-
H4 in *;
clear H1 H3 H4;
simpl.
specialize (
IHdnnrc_type_sub2 ((
v,
Dlocal a0)::
env)).
assert (
dbindings_type ((
v,
Dlocal a0) ::
env) ((
v,
Tlocal τ₁) ::
tenv)).
unfold dbindings_type.
apply Forall2_cons;
try assumption.
simpl;
split;
try reflexivity.
assert (
r = τ₁)
by (
apply rtype_fequal;
assumption).
rewrite H1 in *;
clear H1 x.
constructor.
apply (
H0 a0);
left;
reflexivity.
specialize (
IHdnnrc_type_sub2 H1);
clear H1.
elim IHdnnrc_type_sub2;
clear IHdnnrc_type_sub2;
intros.
elim H1;
clear H1;
intros.
assert ((@
dnnrc_eval (@
basic_model_runtime m)
A plug_type
(@
brand_relation_brands
(@
brand_model_relation (@
basic_model_foreign_type m)
(@
basic_model_brand_model m)))
plug
(@
cons (
prod string (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m))))
(@
pair string (@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
v
(@
Dlocal (@
foreign_runtime_data (@
basic_model_runtime m))
a0))
env)
e2) =
(@
dnnrc_eval (@
basic_model_runtime m)
A plug_type
(@
brand_relation_brands
(@
brand_model_relation (@
basic_model_foreign_type m)
(@
basic_model_brand_model m)))
plug
(@
cons
(
prod DNNRCBase.var
(@
ddata (@
foreign_runtime_data (@
basic_model_runtime m))))
(@
pair DNNRCBase.var
(@
ddata (@
foreign_runtime_data (@
basic_model_runtime m)))
v
(@
Dlocal (@
foreign_runtime_data (@
basic_model_runtime m))
a0))
env)
e2))
by reflexivity.
rewrite <-
H4;
clear H4.
rewrite H1;
simpl.
inversion H3;
clear H3;
subst.
exists (
Dlocal (
dcoll (
d::
x1)));
split;
try reflexivity.
constructor;
apply dtcoll.
rewrite Forall_forall;
simpl;
intros.
elim H3;
clear H3;
intros.
rewrite H3 in *;
assumption.
inversion H2;
clear H2;
subst.
dependent induction H7.
rewrite Forall_forall in *.
assert (
r0 = τ₂)
by (
apply rtype_fequal;
assumption).
subst.
apply (
H2 x2);
assumption.
-
admit.
-
specialize (
IHdnnrc_type_sub1 env H);
specialize (
IHdnnrc_type_sub2 env H);
specialize (
IHdnnrc_type_sub3 env H).
elim IHdnnrc_type_sub1;
intros;
clear IHdnnrc_type_sub1;
elim IHdnnrc_type_sub2;
intros;
clear IHdnnrc_type_sub2;
elim IHdnnrc_type_sub3;
intros;
clear IHdnnrc_type_sub3.
elim H0;
clear H0;
intros.
elim H1;
clear H1;
intros.
elim H2;
clear H2;
intros.
rewrite H0.
simpl.
inversion H3;
clear H3;
subst.
dependent induction H8.
destruct b.
+
rewrite H1.
exists x0;
split; [
reflexivity|
assumption].
+
rewrite H2.
exists x1;
split; [
reflexivity|
assumption].
-
destruct (
IHdnnrc_type_sub1 _ H)
as [
dd [
evald typd]].
inversion typd;
clear typd;
subst.
apply data_type_Either_inv in H2.
rewrite evald.
simpl.
destruct H2 as [[
ddl[?
typd]]|[
ddr[?
typd]]];
subst.
+
destruct (
IHdnnrc_type_sub2 ((
xl,
Dlocal ddl)::
env));
unfold dbindings_type in *;
auto.
apply Forall2_cons;
auto;
split; [
auto|
constructor;
auto].
exists x;
auto.
+
destruct (
IHdnnrc_type_sub3 ((
xr,
Dlocal ddr)::
env));
unfold dbindings_type in *;
auto.
apply Forall2_cons;
auto;
split; [
auto|
constructor;
auto].
exists x;
auto.
-
elim (
IHdnnrc_type_sub env H);
intros.
elim H1;
clear H1;
intros.
rewrite H1;
simpl.
inversion H2;
clear H2;
subst.
exists (
Dlocal (
dcoll dl)).
simpl.
split; [
reflexivity|].
constructor.
constructor.
assumption.
-
elim (
IHdnnrc_type_sub env H);
intros.
elim H1;
clear H1;
intros.
rewrite H1;
simpl.
inversion H2;
clear H2;
subst;
simpl.
dependent induction H5.
exists (
Ddistr dl).
simpl.
split; [
reflexivity|].
constructor.
assert (
r = τ)
by (
apply rtype_fequal;
assumption).
subst;
assumption.
-
admit.
We will need a special inductive principle because of the list of expressions in TDNRAlg *) -
rewrite H in H2.
destruct (
IHdnnrc_type_sub _ H2)
as [
dd [
dd_eval dd_typ]].
rewrite H0 in dd_typ.
eauto.
Admitted.
End tDNNRCSub.