Section ROptimEnv.
Require Import List String.
Require Import ListSet.
Require Import Utils BasicRuntime.
Require Import NRARuntime NRAOptim.
Require Import cNRAEnv cNRAEnvIgnore cNRAEnvEq.
Local Open Scope nra_scope.
Local Open Scope nraenv_core_scope.
Context {
fruntime:
foreign_runtime}.
Hint Resolve dnrec_sort_content.
Lemma pull_nra_opt (
p1 p2:
nraenv_core) :
(
nra_of_nraenv_core p1) ≡ₐ (
nra_of_nraenv_core p2) ->
p1 ≡ₑ
p2.
Proof.
Lemma envand_comm (
p1 p2:
nraenv_core) :
p2 ∧
p1 ≡ₑ
p1 ∧
p2.
Proof.
Lemma envunion_assoc (
p1 p2 p3:
nraenv_core):
(
p1 ⋃
p2) ⋃
p3 ≡ₑ
p1 ⋃ (
p2 ⋃
p3).
Proof.
Lemma select_union_distr (
q q₁
q₂:
nraenv_core) :
σ⟨
q ⟩(
q₁ ⋃
q₂) ≡ₑ σ⟨
q ⟩(
q₁) ⋃ σ⟨
q ⟩(
q₂).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_.
simpl.
generalize (
h ⊢ₑ
q₁ @ₑ
x ⊣
c;
env)
as d1.
generalize (
h ⊢ₑ
q₂ @ₑ
x ⊣
c;
env)
as d2.
intros.
destruct d1;
destruct d2;
try (
autorewrite with alg;
reflexivity);
simpl.
destruct d;
try reflexivity.
destruct d0;
simpl;
try (
destruct (
lift_filter
(
fun x' :
data =>
match h ⊢ₑ
q @ₑ
x' ⊣
c;
env with
|
Some (
dbool b) =>
Some b
|
_ =>
None
end)
l);
simpl;
reflexivity).
induction l;
simpl.
destruct (
lift_filter
(
fun x' :
data =>
match h ⊢ₑ
q @ₑ
x' ⊣
c;
env with
|
Some (
dbool b) =>
Some b
|
_ =>
None
end)
l0);
reflexivity.
generalize(
h ⊢ₑ
q @ₑ
a ⊣
c;
env);
intros.
unfold bunion.
rewrite lift_app_filter.
destruct o;
try reflexivity.
destruct d;
try reflexivity.
revert IHl.
generalize ((
lift_filter
(
fun x' :
data =>
match h ⊢ₑ
q @ₑ
x' ⊣
c;
env with
|
Some (
dbool b0) =>
Some b0
|
_ =>
None
end)
l)).
generalize (
lift_filter
(
fun x' :
data =>
match h ⊢ₑ
q @ₑ
x' ⊣
c;
env with
|
Some (
dbool b0) =>
Some b0
|
_ =>
None
end)
l0).
intros.
destruct o0;
try reflexivity.
simpl.
destruct o;
try reflexivity.
+
destruct b;
autorewrite with alg;
reflexivity.
+
autorewrite with alg.
reflexivity.
Qed.
Lemma envmap_singleton (
p1 p2:
nraenv_core) :
χ⟨
p1 ⟩( ‵{|
p2 |} ) ≡ₑ ‵{|
p1 ◯
p2 |}.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
intros.
destruct o;
try reflexivity;
simpl.
generalize (
h ⊢ₑ
p1 @ₑ
d ⊣
c;
env);
intros;
simpl.
destruct o;
reflexivity.
Qed.
Lemma envmap_map_compose (
p1 p2 p3:
nraenv_core) :
χ⟨
p1 ⟩( χ⟨
p2 ⟩(
p3 ) ) ≡ₑ χ⟨
p1 ◯
p2 ⟩(
p3 ).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p3 @ₑ
x ⊣
c;
env);
intros.
destruct o;
try reflexivity;
simpl.
destruct d;
try reflexivity;
simpl.
unfold olift,
lift;
simpl.
induction l;
try reflexivity;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
a ⊣
c;
env);
intros.
destruct o;
try reflexivity;
simpl.
revert IHl;
generalize (
rmap (
nraenv_core_eval h c p2 env)
l);
intros.
destruct o;
try reflexivity;
simpl.
destruct (
h ⊢ₑ
p1 @ₑ
d ⊣
c;
env);
try reflexivity;
simpl.
revert IHl;
generalize (
rmap
(
fun x0 :
data =>
match h ⊢ₑ
p2 @ₑ
x0 ⊣
c;
env with
|
Some x'0 =>
h ⊢ₑ
p1 @ₑ
x'0 ⊣
c;
env
|
None =>
None
end)
l);
intros.
destruct o;
try reflexivity;
simpl in *.
destruct (
rmap (
nraenv_core_eval h c p1 env)
l0).
inversion IHl;
reflexivity.
congruence.
destruct (
rmap (
nraenv_core_eval h c p1 env)
l0).
congruence.
reflexivity.
revert IHl;
generalize (
rmap
(
fun x0 :
data =>
match h ⊢ₑ
p2 @ₑ
x0 ⊣
c;
env with
|
Some x'0 =>
h ⊢ₑ
p1 @ₑ
x'0 ⊣
c;
env
|
None =>
None
end)
l);
intros.
destruct o;
try congruence.
destruct (
h ⊢ₑ
p1 @ₑ
d ⊣
c;
env);
reflexivity.
Qed.
Lemma app_over_rec s p1 p2:
‵[| (
s,
p1) |] ◯
p2 ≡ₑ ‵[| (
s,
p1 ◯
p2) |].
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma envflatten_coll_flatten p:
♯
flatten(‵{| ♯
flatten(
p ) |}) ≡ₑ ♯
flatten(
p ).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
clear x p;
intros.
destruct o;
try reflexivity;
simpl.
unfold olift;
simpl.
destruct d;
try reflexivity;
simpl.
induction l;
try reflexivity;
simpl.
unfold lift,
rflatten in *;
simpl in *.
destruct a;
try reflexivity.
revert IHl;
generalize (
oflat_map
(
fun x :
data =>
match x with
|
dcoll y =>
Some y
|
_ =>
None
end)
l);
intros.
destruct o;
try reflexivity;
simpl.
rewrite app_nil_r.
reflexivity.
Qed.
Lemma envflatten_coll_coll p:
♯
flatten(‵{| ‵{|
p |} |}) ≡ₑ ‵{|
p |}.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
clear x p;
intros.
destruct o;
reflexivity.
Qed.
Lemma envflatten_nil :
♯
flatten(‵{||}) ≡ₑ ‵{||}.
Proof.
Lemma envflatten_coll_map p1 p2 :
♯
flatten(‵{| χ⟨
p1 ⟩(
p2 ) |}) ≡ₑ χ⟨
p1 ⟩(
p2 ).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
clear x p2;
intros.
destruct o;
try reflexivity;
simpl.
destruct d;
try reflexivity;
simpl.
induction l;
try reflexivity;
simpl.
unfold olift in *;
simpl in *.
generalize (
h ⊢ₑ
p1 @ₑ
a ⊣
c;
env);
clear a;
intros.
destruct o;
try reflexivity;
simpl.
unfold lift in *;
simpl in *.
revert IHl;
generalize (
rmap (
nraenv_core_eval h c p1 env)
l);
intros.
destruct o;
try reflexivity;
try congruence.
unfold lift_oncoll in *;
simpl in *.
rewrite app_nil_r.
rewrite app_nil_r in IHl.
inversion IHl;
reflexivity.
Qed.
Lemma flatten_flatten_map_either_nil p₁
p₂
p₃ :
♯
flatten( ♯
flatten(χ⟨
ANEither p₁ ‵{||} ◯
p₂⟩(
p₃))) ≡ₑ
♯
flatten( χ⟨
ANEither( ♯
flatten(
p₁)) ‵{||} ◯
p₂⟩(
p₃)).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
destruct (
h ⊢ₑ
p₃ @ₑ
x ⊣
c;
env);
simpl;
trivial.
unfold olift.
destruct d;
simpl;
trivial.
induction l;
simpl;
trivial.
unfold lift in *.
destruct (
rmap
(
fun x0 :
data =>
match h ⊢ₑ
p₂ @ₑ
x0 ⊣
c;
env with
|
Some (
dleft dl) =>
h ⊢ₑ
p₁ @ₑ
dl ⊣
c;
env
|
Some (
dright _) =>
Some (
dcoll nil)
|
Some _ =>
None
|
None =>
None
end)
l);
simpl in *;
destruct (
rmap
(
fun x0 :
data =>
match h ⊢ₑ
p₂ @ₑ
x0 ⊣
c;
env with
|
Some (
dleft dl) =>
match h ⊢ₑ
p₁ @ₑ
dl ⊣
c;
env with
|
Some x'0 =>
lift_oncoll
(
fun l1 :
list data =>
match rflatten l1 with
|
Some a' =>
Some (
dcoll a')
|
None =>
None
end)
x'0
|
None =>
None
end
|
Some (
dright _) =>
Some (
dcoll nil)
|
Some _ =>
None
|
None =>
None
end)
l);
simpl in * .
-
destruct (
h ⊢ₑ
p₂ @ₑ
a ⊣
c;
env);
simpl;
trivial.
case_eq (
rflatten l0);
[
intros ?
eqq0 |
intros eqq0];
rewrite eqq0 in *;
(
case_eq (
rflatten l1);
[
intros ?
eqq1 |
intros eqq1];
rewrite eqq1 in *;
simpl in IHl);
try discriminate.
+
case_eq (
rflatten l2);
[
intros ?
eqq2 |
intros eqq2];
try rewrite eqq2 in *;
try discriminate.
inversion IHl;
clear IHl;
subst.
destruct d;
simpl;
trivial.
*
destruct (
h ⊢ₑ
p₁ @ₑ
d ⊣
c;
env);
simpl;
trivial.
destruct d0;
simpl;
trivial.
rewrite (
rflatten_cons _ _ _ eqq0).
simpl.
{
case_eq (
rflatten l4);
[
intros ?
eqq4 |
intros eqq4];
simpl.
-
rewrite (
rflatten_cons _ _ _ eqq1).
rewrite (
rflatten_app _ _ _ _ eqq4 eqq2).
trivial.
-
rewrite (
rflatten_app_none1 _ _ eqq4).
trivial.
}
*
rewrite (
rflatten_cons _ _ _ eqq0).
rewrite (
rflatten_cons _ _ _ eqq1).
simpl.
rewrite eqq2.
trivial.
+
case_eq (
rflatten l2);
[
intros ?
eqq2 |
intros eqq2];
try rewrite eqq2 in *;
try discriminate.
destruct d;
simpl;
trivial.
*
destruct (
h ⊢ₑ
p₁ @ₑ
d ⊣
c;
env);
simpl;
trivial.
destruct d0;
simpl;
trivial.
rewrite (
rflatten_cons _ _ _ eqq0).
simpl.
rewrite (
rflatten_app_none2 _ _ eqq2).
destruct (
rflatten l3);
simpl;
trivial.
rewrite (
rflatten_cons_none _ _ eqq1).
trivial.
*
rewrite (
rflatten_cons _ _ _ eqq0).
simpl.
rewrite (
rflatten_cons_none _ _ eqq1).
rewrite eqq2.
trivial.
+
destruct d;
simpl;
trivial.
*
destruct (
h ⊢ₑ
p₁ @ₑ
d ⊣
c;
env);
simpl;
trivial.
rewrite (
rflatten_cons_none _ _ eqq0).
destruct d0;
simpl;
trivial.
destruct (
rflatten l2);
simpl;
trivial.
rewrite (
rflatten_cons_none _ _ eqq1).
trivial.
*
rewrite (
rflatten_cons_none _ _ eqq0).
rewrite (
rflatten_cons_none _ _ eqq1).
trivial.
-
destruct (
h ⊢ₑ
p₂ @ₑ
a ⊣
c;
env);
simpl;
trivial.
destruct d;
simpl;
trivial.
+
destruct (
h ⊢ₑ
p₁ @ₑ
d ⊣
c;
env);
simpl;
trivial.
destruct d0;
simpl;
trivial.
case_eq (
rflatten l0);
[
intros ?
eqq0 |
intros eqq0];
rewrite eqq0 in *;
simpl in *.
*
case_eq (
rflatten l2);
[
intros ?
eqq2 |
intros eqq2];
rewrite eqq2 in *;
try discriminate.
rewrite (
rflatten_cons _ _ _ eqq0);
simpl.
rewrite (
rflatten_app_none2 _ _ eqq2).
destruct (
rflatten l1);
trivial.
*
rewrite (
rflatten_cons_none _ _ eqq0).
destruct (
rflatten l1);
trivial.
+
case_eq (
rflatten l0);
[
intros ?
eqq0 |
intros eqq0];
rewrite eqq0 in *;
simpl in *.
*
case_eq (
rflatten l1);
[
intros ?
eqq1 |
intros eqq1];
rewrite eqq1 in *;
try discriminate.
rewrite (
rflatten_cons _ _ _ eqq0);
simpl.
rewrite eqq1.
trivial.
*
rewrite (
rflatten_cons_none _ _ eqq0).
trivial.
-
case_eq (
rflatten l0);
[
intros ?
eqq0 |
intros eqq0];
rewrite eqq0 in *;
simpl in *;
try discriminate.
destruct (
h ⊢ₑ
p₂ @ₑ
a ⊣
c;
env);
simpl;
trivial.
destruct d;
simpl;
trivial.
+
destruct (
h ⊢ₑ
p₁ @ₑ
d ⊣
c;
env);
simpl;
trivial.
destruct d0;
simpl;
trivial.
destruct (
rflatten l1);
simpl;
trivial.
rewrite (
rflatten_cons_none _ _ eqq0).
trivial.
+
rewrite (
rflatten_cons_none _ _ eqq0).
trivial.
-
destruct (
h ⊢ₑ
p₂ @ₑ
a ⊣
c;
env);
simpl;
trivial.
destruct d;
simpl;
trivial.
destruct (
h ⊢ₑ
p₁ @ₑ
d ⊣
c;
env);
simpl;
trivial.
destruct d0;
simpl;
trivial.
destruct (
rflatten l0);
simpl;
trivial.
Qed.
Lemma envflatten_coll_mergeconcat p1 p2:
♯
flatten( ‵{|
p1 ⊗
p2 |} ) ≡ₑ
p1 ⊗
p2.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env);
clear p1;
intros.
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
clear x p2;
intros.
destruct o;
destruct o0;
try reflexivity;
simpl.
destruct d;
destruct d0;
try reflexivity;
simpl.
destruct (
merge_bindings l l0);
reflexivity.
Qed.
Lemma rmap_to_map l :
rmap (
fun x :
data =>
Some (
dcoll (
x ::
nil)))
l =
Some (
map (
fun x :
data => (
dcoll (
x ::
nil)))
l).
Proof.
induction l; [reflexivity|simpl; rewrite IHl; reflexivity].
Qed.
Lemma double_flatten_map_coll p1 p2 :
♯
flatten(χ⟨ χ⟨ ‵{|
ID |} ⟩( ♯
flatten(
p1 ) ) ⟩(
p2 ))
≡ₑ χ⟨ ‵{|
ID |} ⟩(♯
flatten(χ⟨ ♯
flatten(
p1 ) ⟩(
p2 ))).
Proof.
Lemma envflatten_map_coll p1 p2 :
♯
flatten(χ⟨ ‵{|
p1 |} ⟩(
p2 )) ≡ₑ χ⟨
p1 ⟩(
p2 ).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
clear x p2;
intros.
destruct o;
try reflexivity.
destruct d;
try reflexivity;
simpl.
induction l;
try reflexivity;
simpl.
generalize (
h ⊢ₑ
p1 @ₑ
a ⊣
c;
env);
clear a;
intros;
simpl.
destruct o;
try reflexivity;
simpl.
unfold olift in *.
revert IHl.
generalize (
rmap
(
fun x :
data =>
match h ⊢ₑ
p1 @ₑ
x ⊣
c;
env with
|
Some x' =>
Some (
dcoll (
x' ::
nil))
|
None =>
None
end)
l);
generalize (
rmap (
nraenv_core_eval h c p1 env)
l);
intros.
unfold lift in *;
simpl.
destruct o;
destruct o0;
simpl;
try reflexivity;
try congruence.
-
simpl in *.
unfold rflatten in *;
simpl in *.
revert IHl.
generalize ((
oflat_map
(
fun x :
data =>
match x with
|
dcoll y =>
Some y
|
_ =>
None
end)
l1));
intros;
simpl in *.
destruct o;
try congruence.
inversion IHl;
clear IHl H0;
reflexivity.
-
simpl in *.
unfold rflatten in *;
simpl.
revert IHl.
generalize ((
oflat_map
(
fun x :
data =>
match x with
|
dcoll y =>
Some y
|
_ =>
None
end)
l0));
intros;
simpl in *.
destruct o;
try congruence;
reflexivity.
Qed.
Lemma select_over_nil p₁ :
σ⟨
p₁⟩(
ANConst (
dcoll nil)) ≡ₑ
ANConst (
dcoll nil).
Proof.
red; intros br env dn_env d dn_d.
simpl; trivial.
Qed.
Lemma map_over_nil p₁ :
χ⟨
p₁⟩(
ANConst (
dcoll nil)) ≡ₑ
ANConst (
dcoll nil).
Proof.
red; intros br env dn_env d dn_d.
simpl; trivial.
Qed.
Lemma map_over_flatten p₁
p₂ :
χ⟨
p₁⟩(♯
flatten(
p₂)) ≡ₑ (♯
flatten(χ⟨χ⟨
p₁⟩(
ID)⟩(
p₂))).
Proof.
red;
intros br c dn_c env dn_env d dn_d.
simpl.
destruct (
br ⊢ₑ
p₂ @ₑ
d ⊣
c;
env);
simpl;
trivial.
destruct d0;
simpl;
trivial.
clear d dn_d.
induction l;
simpl;
trivial.
destruct a;
simpl;
trivial.
case_eq (
rflatten l); [
intros ?
eqq1 |
intros eqq1];
rewrite eqq1 in IHl;
simpl in *;
[
rewrite (
rflatten_cons _ _ _ eqq1) |
rewrite (
rflatten_cons_none _ _ eqq1)]
; (
case_eq (
rmap
(
fun x :
data =>
lift_oncoll
(
fun c1 :
list data =>
lift dcoll (
rmap (
nraenv_core_eval br c p₁
env)
c1))
x)
l); [
intros ?
eqq2 |
intros eqq2];
rewrite eqq2 in IHl;
simpl in * ).
-
apply lift_injective in IHl; [ |
inversion 1;
trivial].
rewrite rmap_over_app.
rewrite IHl.
destruct (
rmap (
nraenv_core_eval br c p₁
env)
l0);
simpl;
trivial.
-
apply none_lift in IHl.
rewrite rmap_over_app.
rewrite IHl;
simpl.
destruct (
rmap (
nraenv_core_eval br c p₁
env)
l0);
simpl;
trivial.
-
clear IHl.
cut False; [
intuition | ].
revert eqq1 l1 eqq2.
induction l;
simpl in *;
try discriminate.
destruct a;
simpl in *;
try discriminate.
intros.
unfold rflatten in *.
simpl in *.
apply none_lift in eqq1.
specialize (
IHl eqq1);
clear eqq1.
match_destr_in eqq2.
apply some_lift in eqq2.
destruct eqq2 as [?
eqq2 ?];
subst.
apply (
IHl _ eqq2).
-
match_destr.
Qed.
Lemma select_over_flatten p₁
p₂ :
σ⟨
p₁⟩(♯
flatten(
p₂)) ≡ₑ (♯
flatten(χ⟨σ⟨
p₁⟩(
ID)⟩(
p₂))).
Proof.
red;
intros br c dn_c env dn_env d dn_d.
simpl.
destruct (
br ⊢ₑ
p₂ @ₑ
d ⊣
c;
env);
simpl;
trivial.
destruct d0;
simpl;
trivial.
clear d dn_d.
induction l;
simpl;
trivial.
simpl.
destruct a;
simpl;
trivial.
case_eq (
rflatten l); [
intros ?
eqq1 |
intros eqq1];
rewrite eqq1 in IHl;
simpl in *;
[
rewrite (
rflatten_cons _ _ _ eqq1) |
rewrite (
rflatten_cons_none _ _ eqq1)];
(
case_eq (
rmap
(
fun x :
data =>
lift_oncoll
(
fun c1 :
list data =>
lift dcoll
(
lift_filter
(
fun x' :
data =>
match br ⊢ₑ
p₁ @ₑ
x' ⊣
c;
env with
|
Some (
dbool b) =>
Some b
|
Some _ =>
None
|
None =>
None
end)
c1))
x)
l); [
intros ?
eqq2 |
intros eqq2];
rewrite eqq2 in IHl;
simpl in * ).
-
apply lift_injective in IHl; [ |
inversion 1;
trivial].
rewrite lift_app_filter.
rewrite IHl.
destruct ( (
lift_filter
(
fun x' :
data =>
match br ⊢ₑ
p₁ @ₑ
x' ⊣
c;
env with
|
Some (
dbool b) =>
Some b
|
Some _ =>
None
|
None =>
None
end)
l0));
simpl;
trivial.
-
apply none_lift in IHl.
rewrite lift_app_filter.
rewrite IHl;
simpl.
destruct (
lift_filter
(
fun x' :
data =>
match br ⊢ₑ
p₁ @ₑ
x' ⊣
c;
env with
|
Some (
dbool b) =>
Some b
|
Some _ =>
None
|
None =>
None
end)
l0);
simpl;
trivial.
-
clear IHl.
cut False; [
intuition | ].
revert eqq1 l1 eqq2.
induction l;
simpl in *;
try discriminate.
destruct a;
simpl in *;
try discriminate.
intros.
unfold rflatten in *.
simpl in *.
apply none_lift in eqq1.
specialize (
IHl eqq1);
clear eqq1.
match_destr_in eqq2.
apply some_lift in eqq2.
destruct eqq2 as [?
eqq2 ?];
subst.
apply (
IHl _ eqq2).
-
match_destr.
Qed.
Lemma select_over_either p₁
p₂
p₃ :
σ⟨
p₁⟩(
ANEither p₂
p₃) ≡ₑ
ANEither (σ⟨
p₁⟩(
p₂)) (σ⟨
p₁⟩(
p₃)).
Proof.
Now has a (better) typed variant for arbitrary p1/p2, see TOptimEnv
Lemma envdot_from_duplicate_r s1 s2 p1 :
(‵[| (
s1,
p1) |] ⊕ ‵[| (
s2,
p1) |])·
s2 ≡ₑ
p1.
Proof.
Lemma envdot_from_duplicate_l s1 s2 p1 :
(‵[| (
s1,
p1) |] ⊕ ‵[| (
s2,
p1) |])·
s1 ≡ₑ
p1.
Proof.
Lemma envmap_over_either p₁
p₂
p₃ :
χ⟨
p₁⟩(
ANEither p₂
p₃) ≡ₑ
ANEither (χ⟨
p₁⟩(
p₂)) (χ⟨
p₁⟩(
p₃)).
Proof.
Lemma envmap_over_either_app p₁
p₂
p₃
p₄:
χ⟨
p₁⟩(
ANEither p₂
p₃ ◯
p₄) ≡ₑ
ANEither (χ⟨
p₁⟩(
p₂)) (χ⟨
p₁⟩(
p₃)) ◯
p₄.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
unfold olift.
destruct (
h ⊢ₑ
p₄ @ₑ
x ⊣
c;
env);
simpl;
trivial.
destruct d;
simpl;
trivial.
Qed.
Lemma envmap_into_id p :
χ⟨
ID ⟩(‵{|
p |}) ≡ₑ ‵{|
p |}.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
clear x p;
intros.
destruct o;
reflexivity.
Qed.
Lemma envmap_into_id_flatten p :
χ⟨
ID ⟩( ♯
flatten(
p) ) ≡ₑ ♯
flatten(
p).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
clear x p;
intros.
destruct o;
try reflexivity;
simpl.
unfold lift_oncoll;
simpl.
destruct d;
try reflexivity;
simpl.
unfold olift,
lift;
simpl.
destruct (
rflatten l);
try reflexivity;
clear l;
simpl.
induction l0;
try reflexivity;
simpl.
unfold lift;
simpl.
revert IHl0;
destruct (
rmap (
fun x:
data =>
Some x)
l0);
congruence.
Qed.
Lemma product_singletons s1 s2 p1 p2:
‵{|‵[| (
s1,
p1) |] |} × ‵{| ‵[| (
s2,
p2) |] |} ≡ₑ
‵{|‵[| (
s1,
p1) |] ⊕ ‵[| (
s2,
p2) |] |}.
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env);
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
intros.
destruct o;
destruct o0;
reflexivity.
Qed.
Lemma app_over_id p:
p ◯
ID ≡ₑ
p.
Proof.
Lemma appenv_over_env p:
ENV ◯ₑ
p ≡ₑ
p.
Proof.
Lemma app_over_id_l p:
ID ◯
p ≡ₑ
p.
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma app_over_app p1 p2 p3:
(
p1 ◯
p2) ◯
p3 ≡ₑ
p1 ◯ (
p2 ◯
p3).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p3 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma app_over_unop u p1 p2:
(
ANUnop u p1) ◯
p2 ≡ₑ (
ANUnop u (
p1 ◯
p2)).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma appenv_over_unop u p1 p2:
(
ANUnop u p1) ◯ₑ
p2 ≡ₑ (
ANUnop u (
p1 ◯ₑ
p2)).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma unop_over_either u p₁
p₂ :
ANUnop u (
ANEither p₁
p₂) ≡ₑ
ANEither (
ANUnop u p₁)(
ANUnop u p₂).
Proof.
Lemma unop_over_either_app u p₁
p₂
p₃ :
ANUnop u (
ANEither p₁
p₂ ◯
p₃) ≡ₑ
ANEither (
ANUnop u p₁)(
ANUnop u p₂) ◯
p₃.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
unfold olift.
destruct (
h ⊢ₑ
p₃ @ₑ
x ⊣
c;
env);
simpl;
trivial.
destruct d;
simpl;
trivial.
Qed.
Lemma app_over_merge p1 p2:
(
ANEnv ⊗
p1) ◯
p2 ≡ₑ
ANEnv ⊗ (
p1 ◯
p2).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma app_over_binop_l b d p1 p2:
(
ANBinop b p2 (
ANConst d) ◯
p1)
≡ₑ (
ANBinop b (
p2 ◯
p1) (
ANConst d)).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma app_concat_over_binop b p1 p2 p3 p4:
(
ANBinop b p1 p2 ◯ (
p3 ⊕
p4) )
≡ₑ (
ANBinop b (
p1 ◯ (
p3 ⊕
p4)) (
p2 ◯ (
p3 ⊕
p4))).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
destruct (
h ⊢ₑ
p3 @ₑ
x ⊣
c;
env);
try reflexivity;
simpl.
destruct (
h ⊢ₑ
p4 @ₑ
x ⊣
c;
env);
try reflexivity;
simpl.
destruct d;
try reflexivity;
simpl.
destruct d0;
reflexivity.
Qed.
Lemma app_over_binop_env b p1 p2 s:
(
ANBinop b p1 p2 ◯ (
ANUnop (
ADot s)
ANEnv))
≡ₑ (
ANBinop b (
p1 ◯ (
ANUnop (
ADot s)
ANEnv)) (
p2 ◯ (
ANUnop (
ADot s)
ANEnv))).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
destruct env;
try reflexivity;
simpl.
destruct (
edot l s);
reflexivity.
Qed.
Lemma app_over_select p0 p1 p2:
σ⟨
p1 ⟩(
p2 ) ◯
p0 ≡ₑ σ⟨
p1 ⟩(
p2 ◯
p0 ).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p0 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma app_over_map p0 p1 p2:
χ⟨
p1 ⟩(
p2 ) ◯
p0 ≡ₑ χ⟨
p1 ⟩(
p2 ◯
p0 ).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p0 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma app_over_mapconcat p0 p1 p2:
⋈ᵈ⟨
p1 ⟩(
p2 ) ◯
p0 ≡ₑ ⋈ᵈ⟨
p1 ⟩(
p2 ◯
p0 ).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p0 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma app_over_product p0 p1 p2:
(
p1 ×
p2) ◯
p0 ≡ₑ (
p1 ◯
p0) × (
p2 ◯
p0).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p0 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma appenv_over_map p0 p1 p2:
nraenv_core_ignores_id p0 ->
χ⟨
p1 ⟩(
p2 ) ◯ₑ
p0 ≡ₑ χ⟨
p1 ◯ₑ
p0 ⟩(
p2 ◯ₑ
p0 ).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros ? ? ?
_ ?
_ ?
_;
simpl.
case_eq (
h ⊢ₑ
p0 @ₑ
x ⊣
c;
env);
intros;
try reflexivity;
simpl.
destruct (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
d);
try reflexivity;
simpl.
destruct d0;
try reflexivity;
simpl.
induction l;
try reflexivity;
simpl.
rewrite (
nraenv_core_ignores_id_swap p0 H h c env a x).
rewrite H0;
simpl.
destruct (
h ⊢ₑ
p1 @ₑ
a ⊣
c;
d);
try reflexivity;
simpl.
f_equal;
unfold lift in *;
simpl in *.
destruct (
rmap (
nraenv_core_eval h c p1 d)
l);
destruct (
rmap
(
fun x0 :
data =>
olift (
fun env' :
data =>
h ⊢ₑ
p1 @ₑ
x0 ⊣
c;
env') (
h ⊢ₑ
p0 @ₑ
x0 ⊣
c;
env))
l);
congruence.
Qed.
Lemma appenv_over_select p0 p1 p2:
nraenv_core_ignores_id p0 ->
σ⟨
p1 ⟩(
p2 ) ◯ₑ
p0 ≡ₑ σ⟨
p1 ◯ₑ
p0 ⟩(
p2 ◯ₑ
p0 ).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros ? ? ?
_ ?
_ ?
_;
simpl.
case_eq (
h ⊢ₑ
p0 @ₑ
x ⊣
c;
env);
intros;
try reflexivity;
simpl.
destruct (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
d);
try reflexivity;
simpl.
destruct d0;
try reflexivity;
simpl.
induction l;
try reflexivity;
simpl.
rewrite (
nraenv_core_ignores_id_swap p0 H h c env a x).
rewrite H0;
simpl.
destruct (
h ⊢ₑ
p1 @ₑ
a ⊣
c;
d);
try reflexivity;
simpl.
destruct d0;
try reflexivity.
destruct b;
try reflexivity.
f_equal;
unfold lift in *;
simpl in *.
destruct (
lift_filter
(
fun x' :
data =>
match h ⊢ₑ
p1 @ₑ
x' ⊣
c;
d with
|
Some (
dbool b) =>
Some b
|
_ =>
None
end)
l);
destruct (
lift_filter
(
fun x' :
data =>
match
olift (
fun env' :
data =>
h ⊢ₑ
p1 @ₑ
x' ⊣
c;
env') (
h ⊢ₑ
p0 @ₑ
x' ⊣
c;
env)
with
|
Some (
dbool b) =>
Some b
|
_ =>
None
end)
l);
simpl in *;
try congruence.
f_equal;
unfold lift in *;
simpl in *.
destruct (
lift_filter
(
fun x' :
data =>
match h ⊢ₑ
p1 @ₑ
x' ⊣
c;
d with
|
Some (
dbool b) =>
Some b
|
_ =>
None
end)
l);
destruct (
lift_filter
(
fun x' :
data =>
match
olift (
fun env' :
data =>
h ⊢ₑ
p1 @ₑ
x' ⊣
c;
env') (
h ⊢ₑ
p0 @ₑ
x' ⊣
c;
env)
with
|
Some (
dbool b) =>
Some b
|
_ =>
None
end)
l);
simpl in *;
try congruence.
Qed.
Lemma appenv_over_mapenv p:
ANAppEnv (
ANMapEnv (
ANUnop AColl ANEnv)) (
ANUnop AFlatten p) ≡ₑ (
ANMap (
ANUnop AColl ANID) (
ANUnop AFlatten p)).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma appenv_over_mapenv_coll p:
ANAppEnv (
ANMapEnv (
ANUnop AColl (
ANUnop AColl ANEnv))) (
ANUnop AFlatten p) ≡ₑ (
ANMap (
ANUnop AColl (
ANUnop AColl ANID)) (
ANUnop AFlatten p)).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros;
simpl.
generalize (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma appenv_over_mapenv_merge s:
ANAppEnv (
ANMapEnv (
ANUnop AColl ((
ENV) ·
s))) (
ENV ⊗
ID)
≡ₑ
ANMap (
ANUnop AColl ((
ID) ·
s)) (
ENV ⊗
ID).
Proof.
Lemma appenv_over_env_merge_l p1 p2:
nraenv_core_ignores_env p1 ->
ANAppEnv (
ENV ⊗
p1)
p2 ≡ₑ
p2 ⊗
p1.
Proof.
Lemma appenv_over_mapenv_merge2 s:
ANAppEnv (
ANMapEnv ((
ENV) ·
s)) (
ENV ⊗
ID)
≡ₑ
ANMap ((
ID) ·
s) (
ENV ⊗
ID).
Proof.
Lemma env_appenv p:
(
ENV) ◯ₑ
p ≡ₑ
p.
Proof.
Lemma envmap_singleton_rec s1 s2 :
χ⟨‵[| (
s1,
ID) |] ⟩( ‵{|(
ID) ·
s2 |}) ≡ₑ ‵{|‵[| (
s1, (
ID) ·
s2) |] |}.
Proof.
Lemma envmap_dot_singleton a p :
χ⟨
ID·
a ⟩( ‵{|
p |} ) ≡ₑ ‵{|
p·
a |}.
Proof.
Lemma envunnest_singleton s1 s2 s3 p1 p2 :
s1 <>
s2 /\
s2 <>
s3 /\
s3 <>
s1 ->
χ⟨ ¬π[
s1](
ID) ⟩(
⋈ᵈ⟨ χ⟨‵[| (
s2,
ID) |] ⟩((
ID)·
s1) ⟩( ‵{|‵[| (
s3,
p1) |] ⊕ ‵[| (
s1,‵{|
p2 |}) |]|} )
)
≡ₑ ‵{|‵[| (
s3,
p1) |] ⊕ ‵[| (
s2,
p2) |]|}.
Proof.
Lemma binop_over_rec_pair b p1 p2 a1 a2:
a1 <>
a2 ->
(
ANBinop b ((
ID) ·
a1) ((
ID) ·
a2))
◯ (‵[| (
a1,
p1) |] ⊕ ‵[| (
a2,
p2) |])
≡ₑ (
ANBinop b p1 p2).
Proof.
Lemma concat_id_left p1 p2 s1 s2 d:
(‵[| (
s1,
p1) |] ⊕ ‵[| (
s2,
ANConst d) |])
◯
p2
≡ₑ (‵[| (
s1,
p1 ◯
p2) |] ⊕ ‵[| (
s2,
ANConst d) |]).
Proof.
unfold nra_eq,
nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma tostring_dstring s:
(
ANUnop AToString (
ANConst (
dstring s))) ≡ₑ (
ANConst (
dstring s)).
Proof.
Lemma tostring_tostring p:
(
ANUnop AToString (
ANUnop AToString p)) ≡ₑ (
ANUnop AToString p).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
destruct (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
reflexivity.
Qed.
Lemma app_over_env_dot s:
(
ENV ◯ (
ENV) ·
s) ·
s ≡ₑ (
ENV) ·
s.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
destruct env;
try reflexivity;
simpl.
case_eq (
RRelation.edot l s);
intros;
try reflexivity;
assumption.
Qed.
Lemma app_over_appenv p1 p2 p3:
nraenv_core_ignores_id p3 ->
((
p3 ◯ₑ
p2) ◯
p1) ≡ₑ
p3 ◯ₑ (
p2 ◯
p1).
Proof.
unfold nraenv_core_eq;
intros ? ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env);
intros.
destruct o;
try reflexivity;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
d ⊣
c;
env);
intros.
destruct o;
try reflexivity;
simpl.
apply nraenv_core_ignores_id_swap;
assumption.
Qed.
Lemma appenv_over_app_ie p1 p2 p3:
nraenv_core_ignores_env p3 ->
((
p3 ◯
p2) ◯ₑ
p1) ≡ₑ
p3 ◯ (
p2 ◯ₑ
p1).
Proof.
unfold nraenv_core_eq;
intros ? ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env);
intros.
destruct o;
try reflexivity;
simpl.
destruct (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
d);
simpl;
trivial.
apply nraenv_core_ignores_env_swap;
assumption.
Qed.
Lemma app_over_appenv_over_mapenv p1 p2:
(((
ANMapEnv (‵{|
ENV|})) ◯ₑ
p1) ◯
p2) ≡ₑ
(((
ANMapEnv (‵{|
ENV|})) ◯ₑ (
p1 ◯
p2) )).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
generalize (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
intros.
destruct o;
reflexivity.
Qed.
Lemma map_full_over_select_id p0 p1 p2:
χ⟨
p0 ⟩(σ⟨
p1 ⟩(‵{|
p2 |})) ≡ₑ χ⟨
p0 ◯
p2 ⟩(σ⟨
p1 ◯
p2 ⟩(‵{|
ID |})).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
case_eq (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
intros;
try reflexivity;
simpl.
destruct (
h ⊢ₑ
p1 @ₑ
d ⊣
c;
env);
try reflexivity;
simpl.
destruct d0;
try reflexivity;
simpl.
case_eq b;
intros;
try reflexivity;
simpl.
rewrite H;
simpl.
reflexivity.
Qed.
Lemma compose_selects_in_mapenv p1 p2 :
(♯
flatten(
ANMapEnv (χ⟨
ENV⟩(σ⟨
p1⟩( ‵{|
ID |}))))) ◯ₑ (χ⟨
ENV⟩(σ⟨
p2⟩( ‵{|
ID |})))
≡ₑ (χ⟨
ENV⟩(σ⟨
p1⟩(σ⟨
p2⟩( ‵{|
ID |})))).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
autorewrite with alg.
destruct (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
try reflexivity.
destruct d;
try reflexivity.
destruct b;
try reflexivity.
autorewrite with alg;
simpl.
destruct (
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env);
try reflexivity.
destruct d;
try reflexivity.
destruct b;
reflexivity.
Qed.
Lemma flatten_through_appenv p1 p2 :
♯
flatten(
p1 ◯ₑ
p2) ≡ₑ ♯
flatten(
p1) ◯ₑ
p2.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
destruct (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
reflexivity.
Qed.
Lemma appenv_through_either q₁
q₂
q₃:
nraenv_core_ignores_id q₃ ->
ANEither q₁
q₂ ◯ₑ
q₃ ≡ₑ
ANEither (
q₁ ◯ₑ
q₃) (
q₂ ◯ₑ
q₃).
Proof.
intros.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
unfold olift.
generalize (
nraenv_core_ignores_id_swap q₃
H h c env x);
intros eqq.
destruct (
h ⊢ₑ
q₃ @ₑ
x ⊣
c;
env);
simpl in * ;
destruct x;
simpl;
trivial;
specialize (
eqq x);
rewrite <-
eqq;
trivial.
Qed.
Lemma flatten_mapenv_coll p1:
♯
flatten(
ANMapEnv (‵{|
p1 |})) ≡ₑ
ANMapEnv p1.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
destruct env;
try reflexivity;
simpl.
autorewrite with alg.
induction l;
try reflexivity;
simpl in *.
destruct (
h ⊢ₑ
p1 @ₑ
x ⊣
c;
a);
try reflexivity;
simpl.
apply f_equal.
revert IHl.
destruct ((
rmap (
fun env' :
data =>
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env')
l));
destruct ((
rmap
(
fun env' :
data =>
olift (
fun d1 :
data =>
Some (
dcoll (
d1 ::
nil)))
(
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env'))
l));
intros;
simpl in *;
try congruence.
rewrite (
rflatten_cons (
d::
nil)
l1 l0).
auto.
destruct (
rflatten l1);
simpl in *;
congruence.
unfold lift in *.
case_eq (
rflatten l0);
intros;
simpl in *;
try (
rewrite H in *;
congruence).
unfold rflatten in *;
simpl.
rewrite H.
reflexivity.
Qed.
Lemma flip_env1 p :
χ⟨
ENV⟩(σ⟨
p ⟩(‵{|
ID|})) ◯ₑ
ID ≡ₑ (σ⟨
p ⟩(‵{|
ID|})) ◯ₑ
ID.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
destruct (
h ⊢ₑ
p @ₑ
x ⊣
c;
x);
try reflexivity;
simpl.
destruct d;
try reflexivity;
simpl.
destruct b;
reflexivity.
Qed.
Lemma flip_env2 p :
(σ⟨
p ⟩(‵{|
ID|}) ◯ₑ
ID) ≡ₑ σ⟨
p ◯ₑ
ID ⟩(‵{|
ID|}).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
destruct (
h ⊢ₑ
p @ₑ
x ⊣
c;
x);
reflexivity.
Qed.
Lemma flip_env3 b p1 p2 :
(
ANBinop b p1 p2) ◯ₑ
ID ≡ₑ (
ANBinop b (
p1 ◯ₑ
ID) (
p2 ◯ₑ
ID)).
Proof.
Lemma flip_env4 p1 p2 s :
(
ANUnop (
ADot s)
p1) ◯ₑ
p2 ≡ₑ (
ANUnop (
ADot s) (
p1 ◯ₑ
p2)).
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
destruct (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
reflexivity.
Qed.
Lemma flip_env5 p1 p2:
♯
flatten(χ⟨σ⟨
p1⟩(‵{|
ID|})⟩(
p2)) ≡ₑ σ⟨
p1⟩(
p2).
Proof.
Lemma flip_env7 p1 p2:
nraenv_core_ignores_id p1 ->
(
ANMapEnv (‵{|
p1 |})) ◯ₑ
p2 ≡ₑ χ⟨‵{|
p1 ◯ₑ
ID |}⟩(
p2).
Proof.
unfold nraenv_core_eq;
intros ? ? ?
_ ?
_ ?
_;
simpl.
destruct (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
try reflexivity;
simpl.
destruct d;
try reflexivity;
simpl.
induction l;
try reflexivity;
simpl.
rewrite (
nraenv_core_ignores_id_swap p1 H h c a x a).
destruct (
h ⊢ₑ
p1 @ₑ
a ⊣
c;
a);
try reflexivity;
simpl.
destruct ((
rmap
(
fun env' :
data =>
olift (
fun d1 :
data =>
Some (
dcoll (
d1 ::
nil)))
(
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env'))
l));
destruct ((
rmap
(
fun x0 :
data =>
olift (
fun d1 :
data =>
Some (
dcoll (
d1 ::
nil))) (
h ⊢ₑ
p1 @ₑ
x0 ⊣
c;
x0))
l));
simpl in *;
congruence.
Qed.
Lemma merge_concat_to_concat s1 s2 p1 p2:
s1 <>
s2 ->
‵[| (
s1,
p1)|] ⊗ ‵[| (
s2,
p2)|] ≡ₑ ‵{|‵[| (
s1,
p1)|] ⊕ ‵[| (
s2,
p2)|]|}.
Proof.
intros.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
destruct (
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env);
try reflexivity;
simpl.
destruct (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env);
try reflexivity;
simpl.
unfold merge_bindings.
simpl.
unfold compatible_with;
simpl.
destruct (
EquivDec.equiv_dec s1 s2);
try congruence.
simpl.
reflexivity.
Qed.
Lemma dot_over_rec s p :
(‵[| (
s,
p)|]) ·
s ≡ₑ
p.
Proof.
unfold nraenv_core_eq;
intros ? ?
_ ?
_ ?
_;
simpl.
destruct (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
try reflexivity;
simpl.
unfold edot;
simpl.
destruct (
string_eqdec s s);
congruence.
Qed.
Lemma either_app_over_dleft p₁
p₂
d :
(
ANEither p₁
p₂) ◯ (
ANConst (
dleft d)) ≡ₑ
p₁ ◯ (
ANConst d).
Proof.
red; simpl; intros; reflexivity.
Qed.
Lemma either_app_over_dright p₁
p₂
d :
(
ANEither p₁
p₂) ◯ (
ANConst (
dright d)) ≡ₑ
p₂ ◯ (
ANConst d).
Proof.
red; simpl; intros; reflexivity.
Qed.
Lemma either_app_over_aleft p₁
p₂
p :
(
ANEither p₁
p₂) ◯ (
ANUnop ALeft p) ≡ₑ
p₁ ◯
p.
Proof.
red;
simpl;
intros.
unfold olift.
destruct (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
trivial.
Qed.
Lemma either_app_over_aright p₁
p₂
p :
(
ANEither p₁
p₂) ◯ (
ANUnop ARight p) ≡ₑ
p₂ ◯
p.
Proof.
red;
simpl;
intros.
unfold olift.
destruct (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
trivial.
Qed.
optimizations for record projection
Lemma rproject_over_concat sl p1 p2 :
π[
sl](
p1 ⊕
p2)
≡ₑ π[
sl](
p1) ⊕ π[
sl](
p2).
Proof.
red;
simpl;
intros.
destruct (
h ⊢ₑ
p1 @ₑ
x ⊣
c;
env);
destruct (
h ⊢ₑ
p2 @ₑ
x ⊣
c;
env).
-
destruct d;
destruct d0;
simpl;
trivial.
rewrite rproject_rec_sort_commute,
rproject_app.
trivial.
-
destruct x;
destruct d;
simpl;
trivial.
-
destruct x;
destruct d;
simpl;
trivial.
-
destruct x;
simpl;
trivial.
Qed.
Lemma rproject_over_const sl l :
π[
sl](
ANConst (
drec l)) ≡ₑ
ANConst (
drec (
RRelation.rproject l sl)).
Proof.
Lemma rproject_over_rec_in sl s p :
In s sl ->
π[
sl](‵[| (
s,
p) |]) ≡ₑ ‵[| (
s,
p) |].
Proof.
red;
simpl;
intros.
destruct (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
simpl;
trivial.
destruct (
in_dec string_dec s sl);
intuition.
Qed.
Lemma rproject_over_rec_nin sl s p :
~
In s sl ->
π[
sl](‵[| (
s,
p) |]) ≡ₑ ‵[||] ◯
p .
Proof.
red;
simpl;
intros.
destruct (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
simpl;
trivial.
destruct (
in_dec string_dec s sl);
intuition.
Qed.
Lemma rproject_over_rproject sl1 sl2 p :
π[
sl1](π[
sl2](
p)) ≡ₑ π[
set_inter string_dec sl2 sl1](
p).
Proof.
red;
simpl;
intros.
destruct (
h ⊢ₑ
p @ₑ
x ⊣
c;
env);
simpl;
trivial.
destruct d;
simpl;
trivial.
rewrite rproject_rproject.
trivial.
Qed.
Lemma rproject_over_either sl p1 p2 :
π[
sl](
ANEither p1 p2) ≡ₑ
ANEither (π[
sl](
p1)) (π[
sl](
p2)).
Proof.
red; simpl; intros.
destruct x; simpl; trivial.
Qed.
Lemma map_over_map_split p₁
p₂
p₃ :
χ⟨χ⟨
p₁ ⟩(
p₂) ⟩(
p₃) ≡ₑ χ⟨χ⟨
p₁ ⟩(
ID) ⟩(χ⟨
p₂⟩(
p₃)).
Proof.
Definition nodupA :
nraenv_core ->
Prop :=
nraenv_core_always_ensures
(
fun d =>
match d with
|
dcoll dl =>
NoDup dl
|
_ =>
False
end).
Lemma dup_elim (
q:
nraenv_core) :
nodupA q ->
ANUnop ADistinct q ≡ₑ
q.
Proof.
intros nd.
red;
intros.
simpl.
case_eq (
h ⊢ₑ
q @ₑ
x ⊣
c;
env);
simpl;
trivial;
intros.
specialize (
nd h c dn_c env dn_env x dn_x d H).
simpl in nd.
match_destr_in nd;
try tauto.
rewrite rondcoll_dcoll.
rewrite NoDup_bdistinct;
trivial.
Qed.
Some optimizations are best seen through outlining -- the
opposite of inlining. This allows sharing of common sub-expressions.
To enable this, we first define the "last" part of a computation.
returns: (last part of the computation, rest of it)
Fixpoint nraenv_core_split_last (
e:
nraenv_core) : (
nraenv_core*
nraenv_core)
:=
match e with
|
ANID => (
ANID,
ANID)
|
ANConst c => (
ANID,
ANConst c)
|
ANBinop b e1 e2 => (
ANBinop b e1 e2,
ANID)
|
ANUnop u e1 =>
match nraenv_core_split_last e1 with
| (
ANID,
r) => (
ANUnop u r,
ANID)
| (
e1last,
e1rest) => (
e1last,
ANUnop u e1rest)
end
|
ANMap e1 e2 =>
match nraenv_core_split_last e2 with
| (
ANID,
r) => (
ANMap e1 e2,
ANID)
| (
e2last,
e2rest) => (
e2last,
ANMap e1 e2rest)
end
|
ANMapConcat e1 e2 =>
match nraenv_core_split_last e2 with
| (
ANID,
r) => (
ANMapConcat e1 e2,
ANID)
| (
e2last,
e2rest) => (
e2last,
ANMapConcat e1 e2rest)
end
|
ANProduct e1 e2 => (
ANProduct e1 e2,
ANID)
|
ANSelect e1 e2 =>
match nraenv_core_split_last e2 with
| (
ANID,
r) => (
ANSelect e1 e2,
ANID)
| (
e2last,
e2rest) => (
e2last,
ANSelect e1 e2rest)
end
|
ANDefault e1 e2 => (
ANDefault e1 e2,
ANID)
|
ANEither l r => (
ANEither l r,
ANID)
|
ANEitherConcat l r =>
(
ANEitherConcat l r,
ANID)
|
ANApp e1 e2 =>
match nraenv_core_split_last e2 with
| (
ANID,
r) => (
e1,
r)
| (
e2last,
e2rest) => (
e2last,
ANApp e1 e2rest)
end
|
ANGetConstant s => (
ANID,
ANGetConstant s)
|
ANEnv => (
ANID,
ANEnv)
|
ANAppEnv e1 e2 => (
ANAppEnv e1 e2,
ANID)
|
ANMapEnv e => (
ANMapEnv e,
ANID)
end.
End ROptimEnv.
Hint Rewrite @
envflatten_map_coll :
nraenv_core_optim.
Hint Rewrite @
envmap_into_id :
nraenv_core_optim.
Hint Rewrite @
envmap_into_id_flatten :
nraenv_core_optim.
Hint Rewrite @
envmap_map_compose :
nraenv_core_optim.
Hint Rewrite @
envmap_singleton :
nraenv_core_optim.
Hint Rewrite @
envflatten_coll_mergeconcat :
nraenv_core_optim.
Hint Rewrite @
envflatten_coll_map :
nraenv_core_optim.
Hint Rewrite @
envflatten_coll_flatten :
nraenv_core_optim.
Hint Rewrite @
envflatten_coll_coll :
nraenv_core_optim.
Hint Rewrite @
app_over_id :
nraenv_core_optim.
Hint Rewrite @
app_over_id_l :
nraenv_core_optim.
Hint Rewrite @
app_over_app :
nraenv_core_optim.
Hint Rewrite @
app_over_map :
nraenv_core_optim.
Hint Rewrite @
app_over_select :
nraenv_core_optim.
Hint Rewrite @
app_over_unop :
nraenv_core_optim.
Hint Rewrite @
app_over_binop_l :
nraenv_core_optim.
Hint Rewrite @
app_over_merge :
nraenv_core_optim.
Hint Rewrite @
app_over_rec :
nraenv_core_optim.
Hint Rewrite @
binop_over_rec_pair :
nraenv_core_optim.
Hint Rewrite @
concat_id_left :
nraenv_core_optim.
Hint Rewrite @
app_over_env_dot :
nraenv_core_optim.
Hint Rewrite @
app_over_appenv_over_mapenv :
nraenv_core_optim.
Hint Rewrite @
product_singletons :
nraenv_core_optim.
Hint Rewrite @
double_flatten_map_coll :
nraenv_core_optim.
Hint Rewrite @
tostring_dstring :
nraenv_core_optim.
Hint Rewrite @
tostring_tostring :
nraenv_core_optim.
Hint Rewrite @
env_appenv :
nraenv_core_optim.
Hint Rewrite @
appenv_over_mapenv :
nraenv_core_optim.
Hint Rewrite @
appenv_over_mapenv_coll :
nraenv_core_optim.
Hint Rewrite @
appenv_over_mapenv_merge :
nraenv_core_optim.
Hint Rewrite @
appenv_over_mapenv_merge2 :
nraenv_core_optim.
Hint Rewrite @
compose_selects_in_mapenv :
nraenv_core_optim.
Hint Rewrite @
flatten_through_appenv :
nraenv_core_optim.
Hint Rewrite @
flatten_mapenv_coll :
nraenv_core_optim.
Hint Rewrite @
either_app_over_dleft :
nraenv_core_optim.
Hint Rewrite @
either_app_over_dright :
nraenv_core_optim.
Hint Rewrite @
either_app_over_aleft :
nraenv_core_optim.
Hint Rewrite @
either_app_over_aright :
nraenv_core_optim.
Hint Rewrite @
rproject_over_concat :
nraenv_core_optim.
Hint Rewrite @
rproject_over_rec_in :
nraenv_core_optim.
Hint Rewrite @
rproject_over_rec_nin :
nraenv_core_optim.
Hint Rewrite @
rproject_over_rproject :
nraenv_core_optim.
Hint Rewrite @
rproject_over_either :
nraenv_core_optim.