NNRS is a variant of the named nested relational calculus
(NNRC) that is meant to be more imperative in feel. It is used
as an intermediate language between NNRC and more imperative /
statement oriented backends
Require Import String.
Require Import List.
Require Import Arith.
Require Import EquivDec.
Require Import Morphisms.
Require Import Arith.
Require Import Max.
Require Import Bool.
Require Import Peano_dec.
Require Import EquivDec.
Require Import Decidable.
Require Import Utils.
Require Import DataRuntime.
Require Import NNRS.
Require Import NNRSVars.
Section NNRSEval.
Context {
fruntime:
foreign_runtime}.
Context (
h:
brand_relation_t).
Local Open Scope nnrs.
Local Open Scope string.
Evaluation Semantics
Section Evaluation.
Evaluation takes a NNRS expression and an environment. It
returns an optional value. When None is returned, it
denotes an error. An error is always propagated.
Fixpoint nnrs_expr_eval
(σ
c:
bindings) (σ:
pd_bindings) (
e:
nnrs_expr)
:
option data
:=
match e with
|
NNRSGetConstant v =>
edot σ
c v
|
NNRSVar v =>
olift id (
lookup equiv_dec σ
v)
|
NNRSConst d =>
Some (
normalize_data h d)
|
NNRSBinop bop e₁
e₂ =>
olift2 (
fun d₁
d₂ =>
binary_op_eval h bop d₁
d₂)
(
nnrs_expr_eval σ
c σ
e₁)
(
nnrs_expr_eval σ
c σ
e₂)
|
NNRSUnop uop e =>
olift (
fun d =>
unary_op_eval h uop d)
(
nnrs_expr_eval σ
c σ
e)
|
NNRSGroupBy g sl e =>
match nnrs_expr_eval σ
c σ
e with
|
Some (
dcoll dl) =>
lift dcoll (
group_by_nested_eval_table g sl dl)
|
_ =>
None
end
end.
Fixpoint nnrs_stmt_eval
(σ
c:
bindings) (σ:
pd_bindings) (ψ
c:
mc_bindings) (ψ
d:
md_bindings)
(
s:
nnrs_stmt) :
option (
pd_bindings*
mc_bindings*
md_bindings)
:=
match s with
|
NNRSSeq s₁
s₂ =>
match nnrs_stmt_eval σ
c σ ψ
c ψ
d s₁
with
|
Some (σ₁, ψ
c₁, ψ
d₁) =>
nnrs_stmt_eval σ
c σ₁ ψ
c₁ ψ
d₁
s₂
|
None =>
None
end
|
NNRSLet v e s₀ =>
match nnrs_expr_eval σ
c σ
e with
|
Some d =>
match nnrs_stmt_eval σ
c ((
v,
Some d)::σ) ψ
c ψ
d s₀
with
|
Some (
_::σ₁, ψ
c₁, ψ
d₁) =>
Some (σ₁, ψ
c₁,ψ
d₁)
|
_ =>
None
end
|
None =>
None
end
|
NNRSLetMut v s₁
s₂ =>
match nnrs_stmt_eval σ
c σ ψ
c ((
v,
None)::ψ
d)
s₁
with
|
Some (σ₁, ψ
c₁, (
_,
d)::ψ
d₁) =>
match nnrs_stmt_eval σ
c ((
v,
d)::σ₁) ψ
c₁ ψ
d₁
s₂
with
|
Some (
_::σ₂, ψ
c₂, ψ
d₂) =>
Some (σ₂, ψ
c₂,ψ
d₂)
|
_ =>
None
end
|
_ =>
None
end
|
NNRSLetMutColl v s₁
s₂ =>
match nnrs_stmt_eval σ
c σ ((
v,
nil)::ψ
c) ψ
d s₁
with
|
Some (σ₁, ((
_,
dl)::ψ
c₁), ψ
d₁) =>
match nnrs_stmt_eval σ
c ((
v,
Some (
dcoll dl))::σ₁) ψ
c₁ ψ
d₁
s₂
with
|
Some ((
_::σ₂), ψ
c₂, ψ
d₂) =>
Some (σ₂,ψ
c₂,ψ
d₂)
|
_ =>
None
end
|
_ =>
None
end
|
NNRSAssign v e =>
match nnrs_expr_eval σ
c σ
e,
lookup string_dec ψ
d v with
|
Some d,
Some _ =>
Some (σ, ψ
c,
update_first string_dec ψ
d v (
Some d))
|
_,
_ =>
None
end
|
NNRSPush v e =>
match nnrs_expr_eval σ
c σ
e,
lookup string_dec ψ
c v with
|
Some d,
Some dl =>
Some (σ,
update_first string_dec ψ
c v (
dl++
d::
nil)%
list, ψ
d)
|
_,
_ =>
None
end
|
NNRSFor v e s₀ =>
match nnrs_expr_eval σ
c σ
e with
|
Some (
dcoll c1) =>
let fix for_fun (
dl:
list data) σ₁ ψ
c₁ ψ
d₁ :=
match dl with
|
nil =>
Some (σ₁, ψ
c₁, ψ
d₁)
|
d::
dl' =>
match nnrs_stmt_eval σ
c ((
v,
Some d)::σ₁) ψ
c₁ ψ
d₁
s₀
with
|
Some (
_::σ₂, ψ
c₂, ψ
d₂) =>
for_fun dl' σ₂ ψ
c₂ ψ
d₂
|
_ =>
None
end
end in
for_fun c1 σ ψ
c ψ
d
|
_ =>
None
end
|
NNRSIf e s₁
s₂ =>
match nnrs_expr_eval σ
c σ
e with
|
Some (
dbool true) =>
nnrs_stmt_eval σ
c σ ψ
c ψ
d s₁
|
Some (
dbool false) =>
nnrs_stmt_eval σ
c σ ψ
c ψ
d s₂
|
_ =>
None
end
|
NNRSEither e x₁
s₁
x₂
s₂ =>
match nnrs_expr_eval σ
c σ
e with
|
Some (
dleft d) =>
match nnrs_stmt_eval σ
c ((
x₁,
Some d)::σ) ψ
c ψ
d s₁
with
|
Some (
_::σ₂, ψ
c₂, ψ
d₂) =>
Some (σ₂, ψ
c₂, ψ
d₂)
|
_ =>
None
end
|
Some (
dright d) =>
match nnrs_stmt_eval σ
c ((
x₂,
Some d)::σ) ψ
c ψ
d s₂
with
|
Some (
_::σ₂, ψ
c₂, ψ
d₂) =>
Some (σ₂, ψ
c₂, ψ
d₂)
|
_ =>
None
end
|
_ =>
None
end
end.
Definition nnrs_eval σ
c (
q:
nnrs) :
option (
option data) :=
let (
s,
ret) :=
q in
match nnrs_stmt_eval σ
c nil nil ((
ret,
None)::
nil)
s with
|
Some (
_,
_, (
_,
o)::
_) =>
Some o
|
_ =>
None
end.
Definition nnrs_eval_top σ
c (
q:
nnrs) :=
olift id (
nnrs_eval (
rec_sort σ
c)
q).
End Evaluation.
Section Core.
Program Definition nnrs_core_eval σ
c (
q:
nnrs_core)
:=
nnrs_eval σ
c q.
Program Definition nnrs_core_eval_top σ
c (
q:
nnrs_core)
:=
olift id (
nnrs_core_eval (
rec_sort σ
c)
q).
End Core.
Section props.
Ltac destr H :=
let eqq :=
fresh "
eqq"
in
first [
match goal with
[
H:
_ *
_ |-
_ ] =>
destruct H
end |
(
match_case_in H;
[
intros [???]
eqq |
intros eqq];
rewrite eqq in H;
try discriminate)
| (
match_case_in H;
[
intros [??]
eqq |
intros eqq];
rewrite eqq in H;
try discriminate)
| (
match_case_in H;
[
intros ??
eqq |
intros eqq];
rewrite eqq in H;
try discriminate)
| (
match_case_in H;
[
intros ?
eqq |
intros eqq];
rewrite eqq in H;
try discriminate)
| (
match_case_in H;
[
intros eqq |
intros ? ?
eqq];
try rewrite eqq in H;
try discriminate)
| (
match_case_in H;
[
intros eqq |
intros ?
eqq];
try rewrite eqq in H;
try discriminate)
];
subst.
Lemma nnrs_stmt_eval_env_stack {
s σ
c σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂} :
nnrs_stmt_eval σ
c σ₁ ψ
c₁ ψ
d₁
s =
Some (σ₂ , ψ
c₂, ψ
d₂ ) ->
σ₁ = σ₂.
Proof.
revert σ₁ ψc₁ ψd₁ σ₂ ψc₂ ψd₂.
nnrs_stmt_cases (induction s) Case; intros σ₁ ψc₁ ψd₁ σ₂ ψc₂ ψd₂ sem; simpl in sem; repeat destr sem.
- Case "NNRSSeq".
apply IHs1 in eqq.
apply IHs2 in sem.
congruence.
- Case "NNRSLet".
invcs sem.
specialize (IHs _ _ _ _ _ _ eqq0).
simpl in IHs; invcs IHs; trivial.
- Case "NNRSLetMut".
invcs sem.
specialize (IHs2 _ _ _ _ _ _ eqq0).
simpl in IHs2; invcs IHs2; trivial.
eauto.
- Case "NNRSLetMutColl".
specialize (IHs1 _ _ _ _ _ _ eqq).
specialize (IHs2 _ _ _ _ _ _ eqq0).
simpl in IHs2; invcs IHs2.
congruence.
- Case "NNRSAssign".
invcs sem; trivial.
- Case "NNRSPush".
invcs sem; trivial.
- Case "NNRSFor".
destruct d; try discriminate.
clear eqq.
revert σ₁ ψc₁ ψd₁ σ₂ ψc₂ ψd₂ sem.
induction l; intros σ₁ ψc₁ ψd₁ σ₂ ψc₂ ψd₂ sem; invcs sem; trivial.
repeat destr H0.
specialize (IHl _ _ _ _ _ _ H0).
specialize (IHs _ _ _ _ _ _ eqq).
simpl in IHs; invcs IHs.
congruence.
- Case "NNRSIf".
destruct d; try discriminate.
destruct b; eauto.
- Case "NNRSEither".
destruct d; try discriminate;
repeat destr sem; invcs sem.
+ specialize (IHs1 _ _ _ _ _ _ eqq0);
simpl in IHs1; invcs IHs1; trivial.
+ specialize (IHs2 _ _ _ _ _ _ eqq0);
simpl in IHs2; invcs IHs2; trivial.
Qed.
Lemma nnrs_stmt_eval_env_domain_stack {
s σ
c σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂} :
nnrs_stmt_eval σ
c σ₁ ψ
c₁ ψ
d₁
s =
Some (σ₂ , ψ
c₂, ψ
d₂ ) ->
domain σ₁ =
domain σ₂.
Proof.
Lemma nnrs_stmt_eval_mcenv_domain_stack {
s σ
c σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂} :
nnrs_stmt_eval σ
c σ₁ ψ
c₁ ψ
d₁
s =
Some (σ₂ , ψ
c₂, ψ
d₂ ) ->
domain ψ
c₁ =
domain ψ
c₂.
Proof.
revert σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂.
nnrs_stmt_cases (
induction s)
Case;
intros σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂
sem;
simpl in sem;
repeat destr sem.
-
Case "
NNRSSeq".
transitivity (
domain m0);
eauto.
-
Case "
NNRSLet".
invcs sem.
specialize (
IHs _ _ _ _ _ _ eqq0).
simpl in IHs;
invcs IHs;
trivial.
-
Case "
NNRSLetMut".
invcs sem.
specialize (
IHs1 _ _ _ _ _ _ eqq).
specialize (
IHs2 _ _ _ _ _ _ eqq0).
etransitivity;
eauto.
-
Case "
NNRSLetMutColl".
specialize (
IHs1 _ _ _ _ _ _ eqq).
specialize (
IHs2 _ _ _ _ _ _ eqq0).
simpl in IHs1;
invcs IHs1.
congruence.
-
Case "
NNRSAssign".
invcs sem;
trivial.
-
Case "
NNRSPush".
invcs sem.
rewrite domain_update_first;
trivial.
-
Case "
NNRSFor".
destruct d;
try discriminate.
clear eqq.
revert σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂
sem.
induction l;
intros σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂
sem;
invcs sem;
trivial.
repeat destr H0.
specialize (
IHl _ _ _ _ _ _ H0).
specialize (
IHs _ _ _ _ _ _ eqq).
simpl in IHs;
invcs IHs.
congruence.
-
Case "
NNRSIf".
destruct d;
try discriminate.
destruct b;
eauto.
-
Case "
NNRSEither".
destruct d;
try discriminate;
repeat destr sem;
invcs sem.
+
specialize (
IHs1 _ _ _ _ _ _ eqq0);
simpl in IHs1;
invcs IHs1;
trivial.
+
specialize (
IHs2 _ _ _ _ _ _ eqq0);
simpl in IHs2;
invcs IHs2;
trivial.
Qed.
Lemma nnrs_stmt_eval_mdenv_domain_stack {
s σ
c σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂} :
nnrs_stmt_eval σ
c σ₁ ψ
c₁ ψ
d₁
s =
Some (σ₂ , ψ
c₂, ψ
d₂ ) ->
domain ψ
d₁ =
domain ψ
d₂.
Proof.
revert σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂.
nnrs_stmt_cases (
induction s)
Case;
intros σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂
sem;
simpl in sem;
repeat destr sem.
-
Case "
NNRSSeq".
transitivity (
domain m);
eauto.
-
Case "
NNRSLet".
invcs sem.
specialize (
IHs _ _ _ _ _ _ eqq0).
simpl in IHs;
invcs IHs;
trivial.
-
Case "
NNRSLetMut".
invcs sem.
specialize (
IHs1 _ _ _ _ _ _ eqq).
specialize (
IHs2 _ _ _ _ _ _ eqq0).
simpl in IHs1;
invcs IHs1;
trivial.
etransitivity;
eauto.
-
Case "
NNRSLetMutColl".
specialize (
IHs1 _ _ _ _ _ _ eqq).
specialize (
IHs2 _ _ _ _ _ _ eqq0).
simpl in IHs1;
invcs IHs1.
congruence.
-
Case "
NNRSAssign".
invcs sem.
rewrite domain_update_first;
trivial.
-
Case "
NNRSPush".
invcs sem;
trivial.
-
Case "
NNRSFor".
destruct d;
try discriminate.
clear eqq.
revert σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂
sem.
induction l;
intros σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂
sem;
invcs sem;
trivial.
repeat destr H0.
specialize (
IHl _ _ _ _ _ _ H0).
specialize (
IHs _ _ _ _ _ _ eqq).
simpl in IHs;
invcs IHs.
congruence.
-
Case "
NNRSIf".
destruct d;
try discriminate.
destruct b;
eauto.
-
Case "
NNRSEither".
destruct d;
try discriminate;
repeat destr sem;
invcs sem.
+
specialize (
IHs1 _ _ _ _ _ _ eqq0);
simpl in IHs1;
invcs IHs1;
trivial.
+
specialize (
IHs2 _ _ _ _ _ _ eqq0);
simpl in IHs2;
invcs IHs2;
trivial.
Qed.
Lemma nnrs_stmt_eval_domain_stack {
s σ
c σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂} :
nnrs_stmt_eval σ
c σ₁ ψ
c₁ ψ
d₁
s =
Some (σ₂ , ψ
c₂, ψ
d₂ ) ->
σ₁ = σ₂
/\
domain ψ
c₁ =
domain ψ
c₂
/\
domain ψ
d₁ =
domain ψ
d₂.
Proof.
Local Close Scope string.
Lemma nnrs_expr_eval_group_by_unfold σ
c σ
g sl e :
nnrs_expr_eval σ
c σ (
NNRSGroupBy g sl e) =
match nnrs_expr_eval σ
c σ
e with
|
Some (
dcoll dl) =>
lift dcoll (
group_by_nested_eval_table g sl dl)
|
_ =>
None
end.
Proof.
reflexivity.
Qed.
End props.
Section eval_eqs.
Local Close Scope string.
Lemma nnrs_expr_eval_same σ
c pd₁
pd₂
e :
lookup_equiv_on (
nnrs_expr_free_vars e)
pd₁
pd₂ ->
nnrs_expr_eval σ
c pd₁
e =
nnrs_expr_eval σ
c pd₂
e.
Proof.
revert pd₁
pd₂.
induction e;
simpl;
intros;
eauto 3.
-
rewrite H;
simpl;
tauto.
-
apply lookup_equiv_on_dom_app in H;
destruct H as [
leo1 leo2].
rewrite (
IHe1 _ _ leo1).
rewrite (
IHe2 _ _ leo2).
trivial.
-
rewrite (
IHe _ _ H);
trivial.
-
rewrite (
IHe _ _ H);
trivial.
Qed.
Lemma nnrs_expr_eval_free_env σ
c (
l1 l2 l3:
pd_bindings)
e :
disjoint (
nnrs_expr_free_vars e) (
domain l2) ->
nnrs_expr_eval σ
c (
l1 ++
l2 ++
l3)
e
=
nnrs_expr_eval σ
c (
l1 ++
l3)
e.
Proof.
induction e;
simpl;
eauto;
intros.
-
repeat rewrite lookup_app.
repeat match_option.
specialize (
H v);
simpl in H.
apply lookup_in_domain in eqq0.
intuition.
-
apply disjoint_app_l in H.
rewrite IHe1,
IHe2;
tauto.
-
rewrite IHe;
tauto.
-
rewrite IHe;
tauto.
Qed.
Lemma nnrs_expr_eval_free_env_tail σ
c (
l1 l2:
pd_bindings)
e :
disjoint (
nnrs_expr_free_vars e) (
domain l2) ->
nnrs_expr_eval σ
c (
l1 ++
l2)
e
=
nnrs_expr_eval σ
c l1 e.
Proof.
Lemma nnrs_expr_eval_unused_env c l σ
e v d :
(
In v (
domain l)
\/ ~
In v (
nnrs_expr_free_vars e)) ->
nnrs_expr_eval c (
l ++ (
v,
d) :: σ)
e
=
nnrs_expr_eval c (
l ++ σ)
e.
Proof.
Section swap.
Lemma nnrs_expr_eval_swap_env c l σ
e v₁
v₂
d₁
d₂:
v₁ <>
v₂ ->
nnrs_expr_eval c (
l++(
v₁,
d₁)::(
v₂,
d₂)::σ)
e =
nnrs_expr_eval c (
l++(
v₂,
d₂)::(
v₁,
d₁)::σ)
e.
Proof.
Lemma nnrs_stmt_eval_swap_env c l σ ψ
c ψ
d s v₁
v₂
d₁
d₂:
v₁ <>
v₂ ->
lift2P
(
fun '(σ₁', ψ
c₁', ψ
d₁') '(σ₂', ψ
c₂', ψ
d₂') =>
(
forall l'
d₁'
d₂' σ'',
domain l' =
domain l ->
σ₁' =
l' ++ (
v₁,
d₁')::(
v₂,
d₂')::σ'' ->
σ₂' =
l' ++ (
v₂,
d₂')::(
v₁,
d₁')::σ'')
/\ ψ
c₁' = ψ
c₂'
/\ ψ
d₁' = ψ
d₂'
)
(
nnrs_stmt_eval c (
l++(
v₁,
d₁)::(
v₂,
d₂)::σ) ψ
c ψ
d s)
(
nnrs_stmt_eval c (
l++(
v₂,
d₂)::(
v₁,
d₁)::σ) ψ
c ψ
d s).
Proof.
intros neq.
revert l σ ψ
c ψ
d d₁
d₂.
nnrs_stmt_cases (
induction s)
Case
;
simpl;
intros l σ ψ
c ψ
d d₁
d₂.
-
Case "
NNRSSeq"%
string.
specialize (
IHs1 l σ ψ
c ψ
d d₁
d₂).
unfold lift2P in *.
repeat match_option_in IHs1;
try contradiction.
destruct p as [[??]?].
destruct p0 as [[??]?].
destruct IHs1 as [
eqs1 [
eqs2 eqs3]].
subst.
apply nnrs_stmt_eval_domain_stack in eqq.
destruct eqq as [
eqd1 [
eqd2 eqd3]].
subst.
specialize (
eqs1 _ _ _ _ (
eq_refl _) (
eq_refl _)).
subst.
specialize (
IHs2 l σ
m1 m2 d₁
d₂).
repeat match_option_in IHs2;
try contradiction.
-
Case "
NNRSLet"%
string.
rewrite nnrs_expr_eval_swap_env by trivial.
match_destr;
simpl;
trivial.
unfold lift2P in *.
specialize (
IHs ((
v,
Some d) ::
l) σ ψ
c ψ
d d₁
d₂).
simpl in IHs.
unfold var in *.
repeat match_option_in IHs;
try contradiction.
destruct p as [[??]?].
destruct p0 as [[??]?].
destruct IHs as [
eqs1 [
eqs2 eqs3]].
subst.
apply nnrs_stmt_eval_domain_stack in eqq.
destruct eqq as [
eqd1 [
eqd2 eqd3]].
subst.
specialize (
eqs1 ((
v,
Some d)::
l)
_ _ _ (
eq_refl _) (
eq_refl _)).
subst;
simpl.
repeat split;
trivial;
intros.
apply app_inv_head_domain in H0;
trivial.
destruct H0 as [
eql1 eql2].
invcs eql2;
trivial.
-
Case "
NNRSLetMut"%
string.
specialize (
IHs1 l σ ψ
c ((
v,
None) :: ψ
d)
d₁
d₂).
unfold lift2P in *.
repeat match_option_in IHs1;
try contradiction.
destruct p as [[??]?].
destruct p0 as [[??]?].
destruct IHs1 as [
eqs1 [
eqs2 eqs3]];
subst.
apply nnrs_stmt_eval_domain_stack in eqq.
destruct eqq as [
eqd1 [
eqd2 eqd3]];
subst.
destruct m2;
try discriminate.
destruct p;
simpl in *.
simpl in eqd3;
invcs eqd3.
specialize (
eqs1 _ _ _ _ (
eq_refl _) (
eq_refl _));
subst.
specialize (
IHs2 ((
s,
o) ::
l) σ
m1 m2 d₁
d₂).
simpl in *.
unfold var in *.
repeat match_option_in IHs2;
try contradiction.
destruct p as [[??]?].
destruct p0 as [[??]?].
apply nnrs_stmt_eval_domain_stack in eqq.
destruct eqq as [
eqd1' [
eqd2'
eqd3']];
subst.
destruct IHs2 as [
eqs1' [
eqs2'
eqs3']];
subst.
specialize (
eqs1' ((
s,
o)::
l)
_ _ _ (
eq_refl _) (
eq_refl _));
subst;
simpl.
repeat split;
trivial;
intros.
apply app_inv_head_domain in H0;
trivial.
destruct H0 as [
eql1 eql2].
invcs eql2;
trivial.
-
Case "
NNRSLetMutColl"%
string.
specialize (
IHs1 l σ ((
v,
nil)::ψ
c) ψ
d d₁
d₂).
unfold lift2P in *.
repeat match_option_in IHs1;
try contradiction.
destruct p as [[??]?].
destruct p0 as [[??]?].
destruct IHs1 as [
eqs1 [
eqs2 eqs3]];
subst.
apply nnrs_stmt_eval_domain_stack in eqq.
destruct eqq as [
eqd1 [
eqd2 eqd3]];
subst.
destruct m1;
try discriminate.
destruct p;
simpl in *.
simpl in eqd3;
invcs eqd3.
specialize (
eqs1 _ _ _ _ (
eq_refl _) (
eq_refl _));
subst.
specialize (
IHs2 ((
v, (
Some (
dcoll l0))) ::
l) σ
m1 m2 d₁
d₂).
simpl in *.
unfold var in *.
repeat match_option_in IHs2;
try contradiction.
destruct p as [[??]?].
destruct p0 as [[??]?].
apply nnrs_stmt_eval_domain_stack in eqq.
destruct eqq as [
eqd1' [
eqd2'
eqd3']];
subst.
destruct IHs2 as [
eqs1' [
eqs2'
eqs3']];
subst.
specialize (
eqs1' ((
v,
Some (
dcoll l0))::
l)
_ _ _ (
eq_refl _) (
eq_refl _));
subst;
simpl.
repeat split;
trivial;
intros.
apply app_inv_head_domain in H1;
trivial.
destruct H1 as [
eql1 eql2].
invcs eql2;
trivial.
-
Case "
NNRSAssign"%
string.
rewrite nnrs_expr_eval_swap_env by trivial.
destruct (
nnrs_expr_eval c (
l ++ (
v₂,
d₂) :: (
v₁,
d₁) :: σ)
n);
simpl;
trivial.
match_destr;
simpl;
trivial.
repeat split;
trivial;
intros.
apply app_inv_head_domain in H0;
trivial.
destruct H0 as [
eql1 eql2].
invcs eql2;
trivial.
-
Case "
NNRSPush"%
string.
rewrite nnrs_expr_eval_swap_env by trivial.
destruct (
nnrs_expr_eval c (
l ++ (
v₂,
d₂) :: (
v₁,
d₁):: σ)
n);
simpl;
trivial.
match_destr;
simpl;
trivial.
repeat split;
trivial;
intros.
apply app_inv_head_domain in H0;
trivial.
destruct H0 as [
eql1 eql2].
invcs eql2;
trivial.
-
Case "
NNRSFor"%
string.
rewrite nnrs_expr_eval_swap_env by trivial.
destruct (
nnrs_expr_eval c (
l ++ (
v₂,
d₂) :: (
v₁,
d₁) :: σ)
n);
simpl;
trivial.
match_destr;
simpl;
trivial.
revert l σ ψ
c ψ
d d₁
d₂
;
induction l0
;
intros l σ ψ
c ψ
d d₁
d₂;
simpl.
+
repeat split;
trivial;
intros.
apply app_inv_head_domain in H0;
trivial.
destruct H0 as [
eql1 eql2].
invcs eql2;
trivial.
+
specialize (
IHs ((
v,
Some a) ::
l) σ ψ
c ψ
d d₁
d₂).
simpl in IHs.
unfold lift2P in *.
unfold var in *.
repeat match_option_in IHs;
try contradiction.
destruct p as [[??]?].
destruct p0 as [[??]?].
destruct IHs as [
eqs1 [
eqs2 eqs3]].
subst.
apply nnrs_stmt_eval_domain_stack in eqq.
destruct eqq as [
eqd1 [
eqd2 eqd3]].
subst.
specialize (
eqs1 ((
v,
Some a)::
l)
_ _ _ (
eq_refl _) (
eq_refl _)).
subst;
simpl.
specialize (
IHl0 l σ
m1 m2 d₁
d₂).
simpl in *.
unfold lift2P in *.
unfold var in *.
repeat match_option_in IHl0;
try contradiction.
-
Case "
NNRSIf"%
string.
rewrite nnrs_expr_eval_swap_env by trivial.
match_destr;
simpl;
trivial.
destruct d;
simpl;
trivial.
destruct b;
eauto.
-
Case "
NNRSEither"%
string.
rewrite nnrs_expr_eval_swap_env by trivial.
match_destr;
simpl;
trivial.
destruct d;
simpl;
trivial.
+
unfold lift2P in *.
specialize (
IHs1 ((
v,
Some d) ::
l) σ ψ
c ψ
d d₁
d₂).
simpl in IHs1.
unfold var in *.
repeat match_option_in IHs1;
try contradiction.
destruct p as [[??]?].
destruct p0 as [[??]?].
destruct IHs1 as [
eqs1 [
eqs2 eqs3]].
subst.
apply nnrs_stmt_eval_domain_stack in eqq.
destruct eqq as [
eqd1 [
eqd2 eqd3]].
subst.
specialize (
eqs1 ((
v,
Some d)::
l)
_ _ _ (
eq_refl _) (
eq_refl _)).
subst;
simpl.
repeat split;
trivial;
intros.
apply app_inv_head_domain in H0;
trivial.
destruct H0 as [
eql1 eql2].
invcs eql2;
trivial.
+
unfold lift2P in *.
specialize (
IHs2 ((
v0,
Some d) ::
l) σ ψ
c ψ
d d₁
d₂).
simpl in IHs2.
unfold var in *.
repeat match_option_in IHs2;
try contradiction.
destruct p as [[??]?].
destruct p0 as [[??]?].
destruct IHs2 as [
eqs1 [
eqs2 eqs3]].
subst.
apply nnrs_stmt_eval_domain_stack in eqq.
destruct eqq as [
eqd1 [
eqd2 eqd3]].
subst.
specialize (
eqs1 ((
v0,
Some d)::
l)
_ _ _ (
eq_refl _) (
eq_refl _)).
subst;
simpl.
repeat split;
trivial;
intros.
apply app_inv_head_domain in H0;
trivial.
destruct H0 as [
eql1 eql2].
invcs eql2;
trivial.
Qed.
End swap.
Section unused.
Ltac disect_tac H stac
:=
unfold var in *
;
cut_to H;
unfold domain in *; [ |
solve[
stac]..]
;
unfold lift2P in H
; (
repeat match_option_in H;
try contradiction).
Ltac rename_inv_tac1 stac
:=
unfold var in *
;
repeat rewrite or_assoc
;
try match goal with
| [
H:
domain (
_ ++
_) =
domain _ |-
_ ] =>
rewrite domain_app in H
;
unfold domain in H
;
symmetry in H;
apply map_app_break in H
;
destruct H as [? [?[?[??]]]];
subst;
simpl in *
| [
H:
map (
_ ++
_) =
map _ |-
_ ] =>
rewrite map_app in H
;
symmetry in H;
apply map_app_break in H
;
destruct H as [? [?[?[??]]]];
subst;
simpl in *
| [
H:
_ ::
_ =
map _ ?
x |-
_ ] =>
destruct x;
try discriminate;
simpl in H;
invcs H
| [
H:
_ ::
_ =
domain ?
x |-
_ ] =>
destruct x;
try discriminate;
simpl in H;
invcs H
| [
H:
_ *
_ *
_ |-
_ ] =>
destruct H as [[??]?];
simpl in *
| [
H:
_ *
_ |-
_ ] =>
destruct H as [??];
simpl in *
| [
H :
nnrs_stmt_eval _ ?
p1 _ _ _ =
Some (?
p2,
_,
_) |-
_ ] =>
match p1 with
|
p2 =>
fail 1
|
_ =>
generalize (
nnrs_stmt_eval_domain_stack H)
;
intros [?[??]]
end
| [
H: ~ (
_ \/
_) |-
_] =>
apply not_or in H
| [
H:
_ /\
_ |-
_ ] =>
destruct H
| [
H: ?
x = ?
x |-
_] =>
clear H
| [
H:
forall a b c,
_ -> ?
x :: ?
x1 ++ ?
dd :: ?
x2 =
_ ++
_ ::
_ ->
_ |-
_] =>
specialize (
H (
x::
x1) (
snd dd)
x2);
simpl in H
;
match dd with
| (
_,
_) =>
idtac
|
_ =>
destruct dd
end
;
simpl in *
;
cut_to H; [ |
eauto 3 |
reflexivity]
| [
H:
forall a b c,
_ -> ?
x1 ++ ?
dd :: ?
x2 =
_ ++
_ ::
_ ->
_ |-
_] =>
specialize (
H x1 (
snd dd)
x2)
;
match dd with
| (
_,
_) =>
idtac
|
_ =>
destruct dd
end
;
simpl in *
;
cut_to H; [ |
eauto 3 |
reflexivity]
| [
H : ?
x ++
_ = ?
y ++
_ |-
_ ] =>
let HH :=
fresh in
assert (
HH:
domain y =
domain x)
by (
unfold domain in *;
intuition congruence)
;
apply app_inv_head_domain in H;[
clear HH|
apply HH]
| [
H:
_ ::
_ =
_ ::
_ |-
_] =>
invcs H
| [
H: ?
x = (
_,
_) |-
_ ] =>
match x with
| (
_,
_) =>
idtac
|
_ =>
destruct x;
simpl in H
end
;
invcs H
| [
H: (
_,
_) = ?
x |-
_ ] =>
match x with
| (
_,
_) =>
fail 1
|
_ =>
destruct x;
simpl in H
end
;
invcs H
| [|-
_ /\
_ ] =>
try split; [|
tauto]
| [ |-
lift2P _ (
match ?
x with
_ =>
_
end)
(
match ?
x with
_ =>
_
end) ] =>
destruct x;
try reflexivity
| [
H:
forall l es ec ed d,
_ ->
lift2P _ (
nnrs_stmt_eval _ _ _ _ ?
s)
_
|-
lift2P _ (
nnrs_stmt_eval _ (?
l ++ (
_, ?
d) :: ?σ) ?ψ
c ?ψ
d ?
s)
_ ] =>
specialize (
H l σ ψ
c ψ
d d)
;
disect_tac H stac
| [
H:
forall l es ec ed d,
_ ->
lift2P _ (
nnrs_stmt_eval _ _ _ _ ?
s)
_
|-
lift2P _ (
match nnrs_stmt_eval _ (?
l ++ (
_, ?
d) :: ?σ) ?ψ
c ?ψ
d ?
s with
|
Some _ =>
_
|
None =>
_
end)
_ ] =>
specialize (
H l σ ψ
c ψ
d d)
;
disect_tac H stac
| [
H:
forall l es ec ed d,
_ ->
lift2P _ (
nnrs_stmt_eval _ _ _ _ ?
s)
_
|-
lift2P _ (
match nnrs_stmt_eval _ (?
x :: ?
l ++ (
_, ?
d) :: ?σ) ?ψ
c ?ψ
d ?
s with
|
Some _ =>
_
|
None =>
_
end)
_ ] =>
specialize (
H (
x::
l) σ ψ
c ψ
d d);
simpl in H
;
disect_tac H stac
| [
H:
forall l es ec ed d,
_ ->
lift2P _ (
nnrs_stmt_eval _ _ _ _ ?
s)
_
|-
lift2P _ (
nnrs_stmt_eval _ ?σ ?ψ
c (?
l ++ (
_, ?
d) :: ?ψ
d) ?
s)
_ ] =>
specialize (
H l σ ψ
c ψ
d d)
;
disect_tac H stac
| [
H:
forall l es ec ed d,
_ ->
lift2P _ (
nnrs_stmt_eval _ _ _ _ ?
s)
_
|-
lift2P _ (
match nnrs_stmt_eval _ ?σ ?ψ
c (?
l ++ (
_, ?
d) :: ?ψ
d) ?
s with
|
Some _ =>
_
|
None =>
_
end)
_ ] =>
specialize (
H l σ ψ
c ψ
d d)
;
disect_tac H stac
| [
H:
forall l es ec ed d,
_ ->
lift2P _ (
nnrs_stmt_eval _ _ _ _ ?
s)
_
|-
lift2P _ (
match nnrs_stmt_eval _ ?σ ?ψ
c (?
x::?
l ++ (
_, ?
d) :: ?ψ
d) ?
s with
|
Some _ =>
_
|
None =>
_
end)
_ ] =>
specialize (
H (
x::
l) σ ψ
c ψ
d d);
simpl in H
;
disect_tac H stac
| [
H:
forall l es ec ed d,
_ ->
lift2P _ (
nnrs_stmt_eval _ _ _ _ ?
s)
_
|-
lift2P _ (
nnrs_stmt_eval _ ?σ (?
l ++ (
_, ?
d) :: ?ψ
c) ?ψ
d ?
s)
_ ] =>
specialize (
H l σ ψ
c ψ
d d)
;
disect_tac H stac
| [
H:
forall l es ec ed d,
_ ->
lift2P _ (
nnrs_stmt_eval _ _ _ _ ?
s)
_
|-
lift2P _ (
match nnrs_stmt_eval _ ?σ (?
l ++ (
_, ?
d) :: ?ψ
c) ?ψ
d ?
s with
|
Some _ =>
_
|
None =>
_
end)
_ ] =>
specialize (
H l σ ψ
c ψ
d d)
;
disect_tac H stac
| [
H:
forall l es ec ed d,
_ ->
lift2P _ (
nnrs_stmt_eval _ _ _ _ ?
s)
_
|-
lift2P _ (
match nnrs_stmt_eval _ ?σ (?
x::?
l ++ (
_, ?
d) :: ?ψ
c) ?ψ
d ?
s with
|
Some _ =>
_
|
None =>
_
end)
_ ] =>
specialize (
H (
x::
l) σ ψ
c ψ
d d);
simpl in H
;
disect_tac H stac
| [
H : ~
In _ (
remove equiv_dec _ _) |-
_ ] =>
apply not_in_remove_impl_not_in in H; [|
congruence]
| [
H :
In _ (
remove equiv_dec _ _) ->
False |-
_ ] =>
apply not_in_remove_impl_not_in in H; [|
congruence]
| [
H1: ?
x =
Some ?
y,
H2: ?
x =
Some ?
z |-
_ ] =>
rewrite H1 in H2;
invcs H2
| [|- ?
x = ?
y \/
_ ] =>
destruct (
x ==
y);
unfold equiv,
complement in *
; [
left;
trivial |
right]
end
;
try subst;
simpl in *;
intros
;
try congruence
.
Ltac unused_inv_tac :=
repeat progress (
try rename_inv_tac1 ltac:(
unused_inv_tac ;
intuition unused_inv_tac);
try rewrite nnrs_expr_eval_unused_env by tauto).
Lemma nnrs_stmt_eval_unused_env c l σ ψ
c ψ
d s v d:
(
In v (
domain l) \/
~
In v (
nnrs_stmt_free_env_vars s)) ->
lift2P
(
fun '(σ₁', ψ
c₁', ψ
d₁') '(σ₂', ψ
c₂', ψ
d₂') =>
(
forall l'
d' σ'',
domain l' =
domain l ->
σ₁' =
l' ++ (
v,
d')::σ'' ->
σ₂' =
l' ++ σ''
/\ ψ
c₁' = ψ
c₂'
/\ ψ
d₁' = ψ
d₂'
/\
d =
d')
)
(
nnrs_stmt_eval c (
l++(
v,
d)::σ) ψ
c ψ
d s)
(
nnrs_stmt_eval c (
l++σ) ψ
c ψ
d s).
Proof.
revert l σ ψ
c ψ
d d.
nnrs_stmt_cases (
induction s)
Case
;
simpl;
intros l σ ψ
c ψ
d d inn
;
repeat rewrite in_app_iff in inn
;
unused_inv_tac.
-
Case "
NNRSFor"%
string.
revert l σ ψ
c ψ
d d inn
;
induction l0
;
intros l σ ψ
c ψ
d d inn;
simpl.
+
unused_inv_tac.
+
unused_inv_tac.
specialize (
IHl0 l σ
m m0 d inn).
unused_inv_tac.
Qed.
Lemma nnrs_stmt_eval_unused_mdenv c l σ ψ
c ψ
d s v d:
(
In v (
domain l) \/
~
In v (
nnrs_stmt_free_mdenv_vars s)) ->
lift2P
(
fun '(σ₁', ψ
c₁', ψ
d₁') '(σ₂', ψ
c₂', ψ
d₂') =>
(
forall l'
d' ψ
d'',
domain l' =
domain l ->
ψ
d₁' =
l' ++ (
v,
d')::ψ
d'' ->
σ₁' = σ₂'
/\ ψ
c₁' = ψ
c₂'
/\ ψ
d₂' =
l' ++ ψ
d''
/\
d =
d')
)
(
nnrs_stmt_eval c σ ψ
c (
l++(
v,
d)::ψ
d)
s)
(
nnrs_stmt_eval c σ ψ
c (
l++ψ
d)
s).
Proof.
Lemma nnrs_stmt_eval_unused_mcenv c l σ ψ
c ψ
d s v d:
(
In v (
domain l) \/
~
In v (
nnrs_stmt_free_mcenv_vars s)) ->
lift2P
(
fun '(σ₁', ψ
c₁', ψ
d₁') '(σ₂', ψ
c₂', ψ
d₂') =>
(
forall l'
d' ψ
c'',
domain l' =
domain l ->
ψ
c₁' =
l' ++ (
v,
d')::ψ
c'' ->
σ₁' = σ₂'
/\ ψ
c₂' =
l' ++ ψ
c''
/\ ψ
d₁' = ψ
d₂'
/\
d =
d')
)
(
nnrs_stmt_eval c σ (
l++(
v,
d)::ψ
c) ψ
d s)
(
nnrs_stmt_eval c σ (
l++ψ
c) ψ
d s).
Proof.
End unused.
End eval_eqs.
End NNRSEval.
Arguments nnrs_stmt_eval_env_stack {
fruntime h s σ
c σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂}.
Arguments nnrs_stmt_eval_env_domain_stack {
fruntime h s σ
c σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂}.
Arguments nnrs_stmt_eval_mcenv_domain_stack {
fruntime h s σ
c σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂}.
Arguments nnrs_stmt_eval_mdenv_domain_stack {
fruntime h s σ
c σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂}.
Arguments nnrs_stmt_eval_domain_stack {
fruntime h s σ
c σ₁ ψ
c₁ ψ
d₁ σ₂ ψ
c₂ ψ
d₂}.