Module LambdaNRA
Require Import String.
Require Import List.
Require Import Arith.
Require Import EquivDec.
Require Import Morphisms.
Require Import Utils BasicRuntime.
Section LambdaNRA.
Context {
fruntime:
foreign_runtime}.
Unset Elimination Schemes.
Lambda NRA AST
Inductive lambda_nra :
Set :=
|
LNRAVar :
string ->
lambda_nra
|
LNRATable :
string ->
lambda_nra
|
LNRAConst :
data ->
lambda_nra
|
LNRABinop :
binOp ->
lambda_nra ->
lambda_nra ->
lambda_nra
|
LNRAUnop :
unaryOp ->
lambda_nra ->
lambda_nra
|
LNRAMap :
lnra_lambda ->
lambda_nra ->
lambda_nra
|
LNRAMapConcat :
lnra_lambda ->
lambda_nra ->
lambda_nra
|
LNRAProduct :
lambda_nra ->
lambda_nra ->
lambda_nra
|
LNRAFilter :
lnra_lambda ->
lambda_nra ->
lambda_nra
with lnra_lambda :
Set :=
|
LNRALambda :
string ->
lambda_nra ->
lnra_lambda
.
Tactic Notation "
lambda_nra_cases"
tactic(
first)
ident(
c) :=
first;
[
Case_aux c "
LNRAVar"%
string
|
Case_aux c "
LNRATable"%
string
|
Case_aux c "
LNRAConst"%
string
|
Case_aux c "
LNRABinop"%
string
|
Case_aux c "
LNRAUnop"%
string
|
Case_aux c "
LNRAMap"%
string
|
Case_aux c "
LNRAMapConcat"%
string
|
Case_aux c "
LNRAProduct"%
string
|
Case_aux c "
LNRAFilter"%
string
].
Set Elimination Schemes.
Definition lambda_nra_rect
(
P :
lambda_nra ->
Type)
(
fvar :
forall s :
string,
P (
LNRAVar s))
(
ftable :
forall t :
string,
P (
LNRATable t))
(
fconst :
forall d :
data,
P (
LNRAConst d))
(
fbinop :
forall (
b :
binOp) (
l0 l1:
lambda_nra),
P l0 ->
P l1 ->
P (
LNRABinop b l0 l1))
(
funop :
forall (
u :
unaryOp) (
l :
lambda_nra),
P l ->
P (
LNRAUnop u l))
(
fmap :
forall (
s:
string) (
l0 l1 :
lambda_nra),
P l0 ->
P l1 ->
P (
LNRAMap (
LNRALambda s l0)
l1))
(
fmapconcat :
forall (
s:
string) (
l0 l1 :
lambda_nra),
P l0 ->
P l1 ->
P (
LNRAMapConcat (
LNRALambda s l0)
l1))
(
fproduct :
forall l :
lambda_nra,
P l ->
forall l0 :
lambda_nra,
P l0 ->
P (
LNRAProduct l l0))
(
ffilter :
forall (
s:
string) (
l0 l1 :
lambda_nra),
P l0 ->
P l1 ->
P (
LNRAFilter (
LNRALambda s l0)
l1)) :
forall l,
P l
:=
fix F (
l :
lambda_nra) :
P l :=
match l as l0 return (
P l0)
with
|
LNRAVar s =>
fvar s
|
LNRATable t =>
ftable t
|
LNRAConst d =>
fconst d
|
LNRABinop b l0 l1 =>
fbinop b l0 l1 (
F l0) (
F l1)
|
LNRAUnop u l0 =>
funop u l0 (
F l0)
|
LNRAMap (
LNRALambda s l0)
l1 =>
fmap s l0 l1 (
F l0) (
F l1)
|
LNRAMapConcat (
LNRALambda s l0)
l1 =>
fmapconcat s l0 l1 (
F l0) (
F l1)
|
LNRAProduct l0 l1 =>
fproduct l0 (
F l0)
l1 (
F l1)
|
LNRAFilter (
LNRALambda s l0)
l1 =>
ffilter s l0 l1 (
F l0) (
F l1)
end.
Definition lambda_nra_ind (
P :
lambda_nra ->
Prop) :=
lambda_nra_rect P.
Definition lambda_nra_rec (
P:
lambda_nra->
Set) :=
lambda_nra_rect P.
Semantics of Lambda NRA
Context (
h:
brand_relation_t).
Section Semantics.
Context (
global_env:
list (
string*
data)).
Fixpoint lambda_nra_eval (
env:
bindings) (
op:
lambda_nra) :
option data :=
match op with
|
LNRAVar x =>
edot env x
|
LNRATable t =>
edot global_env t
|
LNRAConst d =>
Some (
normalize_data h d)
|
LNRABinop b op1 op2 =>
olift2 (
fun d1 d2 =>
fun_of_binop h b d1 d2) (
lambda_nra_eval env op1) (
lambda_nra_eval env op2)
|
LNRAUnop u op1 =>
olift (
fun d1 =>
fun_of_unaryop h u d1) (
lambda_nra_eval env op1)
|
LNRAMap lop1 op2 =>
let aux_map d :=
lift_oncoll (
fun c1 =>
lift dcoll (
rmap (
lnra_lambda_eval env lop1)
c1))
d
in olift aux_map (
lambda_nra_eval env op2)
|
LNRAMapConcat lop1 op2 =>
let aux_mapconcat d :=
lift_oncoll (
fun c1 =>
lift dcoll (
rmap_concat (
lnra_lambda_eval env lop1)
c1))
d
in olift aux_mapconcat (
lambda_nra_eval env op2)
|
LNRAProduct op1 op2 =>
let aux_product d :=
lift_oncoll (
fun c1 =>
lift dcoll (
rmap_concat (
fun _ =>
lambda_nra_eval env op2)
c1))
d
in olift aux_product (
lambda_nra_eval env op1)
|
LNRAFilter lop1 op2 =>
let pred x' :=
match lnra_lambda_eval env lop1 x'
with
|
Some (
dbool b) =>
Some b
|
_ =>
None
end
in
let aux_map d :=
lift_oncoll (
fun c1 =>
lift dcoll (
lift_filter pred c1))
d
in
olift aux_map (
lambda_nra_eval env op2)
end
with lnra_lambda_eval (
env:
bindings)
(
lop:
lnra_lambda) (
d:
data)
:
option data :=
match lop with
|
LNRALambda x op =>
(
lambda_nra_eval (
rec_sort (
env++((
x,
d)::
nil)))
op)
end.
Lemma lnra_lambda_eval_lambda_eq env x lop d:
lnra_lambda_eval env (
LNRALambda x lop)
d =
(
lambda_nra_eval (
rec_sort (
env++((
x,
d)::
nil)))
lop).
Proof.
reflexivity.
Qed.
Lemma lambda_nra_eval_var_eq env s :
lambda_nra_eval env (
LNRAVar s) =
edot env s.
Proof.
reflexivity.
Qed.
Lemma lambda_nra_eval_binop_eq env b op1 op2 :
lambda_nra_eval env (
LNRABinop b op1 op2) =
olift2 (
fun d1 d2 =>
fun_of_binop h b d1 d2) (
lambda_nra_eval env op1) (
lambda_nra_eval env op2).
Proof.
reflexivity.
Qed.
Lemma lambda_nra_eval_unop_eq env u op1 :
lambda_nra_eval env (
LNRAUnop u op1) =
olift (
fun d1 =>
fun_of_unaryop h u d1) (
lambda_nra_eval env op1).
Proof.
reflexivity.
Qed.
Lemma lambda_nra_eval_map_eq env lop1 op2 :
lambda_nra_eval env (
LNRAMap lop1 op2) =
let aux_map d :=
lift_oncoll (
fun c1 =>
lift dcoll (
rmap (
lnra_lambda_eval env lop1)
c1))
d
in olift aux_map (
lambda_nra_eval env op2).
Proof.
reflexivity.
Qed.
Lemma lambda_nra_eval_map_concat_eq env lop1 op2 :
lambda_nra_eval env (
LNRAMapConcat lop1 op2) =
let aux_mapconcat d :=
lift_oncoll (
fun c1 =>
lift dcoll (
rmap_concat (
lnra_lambda_eval env lop1)
c1))
d
in olift aux_mapconcat (
lambda_nra_eval env op2).
Proof.
reflexivity.
Qed.
Lemma lambda_nra_eval_product_eq env op1 op2 :
lambda_nra_eval env (
LNRAProduct op1 op2) =
let aux_product d :=
lift_oncoll (
fun c1 =>
lift dcoll (
rmap_concat (
fun _ =>
lambda_nra_eval env op2)
c1))
d
in olift aux_product (
lambda_nra_eval env op1).
Proof.
reflexivity.
Qed.
Lemma lambda_nra_eval_filter_eq env lop1 op2 :
lambda_nra_eval env (
LNRAFilter lop1 op2) =
let pred x' :=
match lnra_lambda_eval env lop1 x'
with
|
Some (
dbool b) =>
Some b
|
_ =>
None
end
in
let aux_map d :=
lift_oncoll (
fun c1 =>
lift dcoll (
lift_filter pred c1))
d
in
olift aux_map (
lambda_nra_eval env op2).
Proof.
reflexivity.
Qed.
Lemma lambda_nra_eval_normalized {
op:
lambda_nra} {
env:
bindings} {
o} :
lambda_nra_eval env op=
Some o ->
Forall (
fun x =>
data_normalized h (
snd x))
env ->
Forall (
fun x =>
data_normalized h (
snd x))
global_env ->
data_normalized h o.
Proof.
revert env o.
lambda_nra_cases (
induction op)
Case
;
intros;
simpl in *.
-
Case "
LNRAVar"%
string.
unfold edot in H.
apply assoc_lookupr_in in H.
rewrite Forall_forall in H0.
specialize (
H0 _ H).
simpl in H0.
trivial.
-
Case "
LNRATable"%
string.
unfold edot in H.
apply assoc_lookupr_in in H.
rewrite Forall_forall in H1.
specialize (
H1 _ H).
simpl in H1.
trivial.
-
Case "
LNRAConst"%
string.
invcs H.
apply normalize_normalizes.
-
Case "
LNRABinop"%
string.
unfold olift2 in H.
match_case_in H;
intros;
rewrite H2 in H;
try discriminate.
match_case_in H;
intros;
rewrite H3 in H;
try discriminate.
eapply fun_of_binop_normalized;
eauto.
-
Case "
LNRAUnop"%
string.
unfold olift in H.
match_case_in H;
intros;
rewrite H2 in H;
try discriminate.
eapply fun_of_unaryop_normalized;
eauto.
-
Case "
LNRAMap"%
string.
unfold olift in H.
match_case_in H;
intros;
rewrite H2 in H;
try discriminate.
specialize (
IHop2 _ _ H2 H0 H1).
unfold lift_oncoll in H.
match_destr_in H.
apply some_lift in H.
destruct H as [? ? ?];
subst.
constructor.
invcs IHop2.
eapply (
rmap_Forall e).
+
apply H3.
+
intros.
eapply IHop1;
eauto.
apply Forall_sorted.
apply Forall_app;
auto.
-
Case "
LNRAMapConcat"%
string.
unfold olift in H.
match_case_in H;
intros;
rewrite H2 in H;
try discriminate.
specialize (
IHop2 _ _ H2 H0 H1).
unfold lift_oncoll in H.
match_destr_in H.
apply some_lift in H.
destruct H as [? ? ?];
subst.
constructor.
invcs IHop2.
unfold rmap_concat in e.
eapply (
oflat_map_Forall e).
+
apply H3.
+
intros.
unfold oomap_concat in H.
match_case_in H;
intros;
rewrite H5 in H;
try discriminate.
match_destr_in H.
unfold omap_concat in H.
specialize (
IHop1 _ _ H5).
cut_to IHop1.
{
invcs IHop1.
eapply (
rmap_Forall H).
-
eapply H7.
-
intros.
simpl in *.
unfold orecconcat in H6.
match_destr_in H6.
match_destr_in H6.
invcs H6.
constructor.
+
apply Forall_sorted.
apply Forall_app.
*
invcs H4;
trivial.
*
invcs H8;
trivial.
+
eauto.
}
apply Forall_sorted.
apply Forall_app;
trivial.
constructor;
trivial.
trivial.
-
Case "
LNRAProduct"%
string.
unfold olift in H.
match_case_in H;
intros;
rewrite H2 in H;
try discriminate.
specialize (
IHop1 _ _ H2 H0 H1).
unfold lift_oncoll in H.
match_destr_in H.
apply some_lift in H.
destruct H as [? ? ?];
subst.
constructor.
invcs IHop1.
unfold rmap_concat in e.
eapply (
oflat_map_Forall e).
+
apply H3.
+
intros.
unfold oomap_concat in H.
match_case_in H;
intros;
rewrite H5 in H;
try discriminate.
match_destr_in H.
unfold omap_concat in H.
specialize (
IHop2 _ _ H5).
cut_to IHop2.
{
invcs IHop2.
eapply (
rmap_Forall H).
-
eapply H7.
-
intros.
simpl in *.
unfold orecconcat in H6.
match_destr_in H6.
match_destr_in H6.
invcs H6.
constructor.
+
apply Forall_sorted.
apply Forall_app.
*
invcs H4;
trivial.
*
invcs H8;
trivial.
+
eauto.
}
trivial.
trivial.
-
Case "
LNRAFilter"%
string.
unfold olift in H.
match_case_in H;
intros;
rewrite H2 in H;
try discriminate.
specialize (
IHop2 _ _ H2 H0 H1).
unfold lift_oncoll in H.
match_destr_in H.
apply some_lift in H.
destruct H as [? ? ?];
subst.
constructor.
invcs IHop2.
eapply (
lift_filter_Forall e).
trivial.
Qed.
End Semantics.
Section LambdaNRAScope.
Fixpoint lambda_nra_free_vars (
e:
lambda_nra) :=
match e with
|
LNRAConst d =>
nil
|
LNRAVar v =>
v ::
nil
|
LNRATable t =>
nil
|
LNRABinop bop e1 e2 =>
lambda_nra_free_vars e1 ++
lambda_nra_free_vars e2
|
LNRAUnop uop e1 =>
lambda_nra_free_vars e1
|
LNRAMap (
LNRALambda x e1)
e2 =>
(
remove string_eqdec x (
lambda_nra_free_vars e1)) ++ (
lambda_nra_free_vars e2)
|
LNRAMapConcat (
LNRALambda x e1)
e2 =>
(
remove string_eqdec x (
lambda_nra_free_vars e1)) ++ (
lambda_nra_free_vars e2)
|
LNRAProduct e1 e2 =>
(
lambda_nra_free_vars e1) ++ (
lambda_nra_free_vars e2)
|
LNRAFilter (
LNRALambda x e1)
e2 =>
(
remove string_eqdec x (
lambda_nra_free_vars e1)) ++ (
lambda_nra_free_vars e2)
end.
Fixpoint lambda_nra_subst (
e:
lambda_nra) (
x:
string) (
e':
lambda_nra) :
lambda_nra :=
match e with
|
LNRAConst d =>
LNRAConst d
|
LNRAVar y =>
if y ==
x then e'
else LNRAVar y
|
LNRATable t =>
LNRATable t
|
LNRABinop bop e1 e2 =>
LNRABinop bop
(
lambda_nra_subst e1 x e')
(
lambda_nra_subst e2 x e')
|
LNRAUnop uop e1 =>
LNRAUnop uop (
lambda_nra_subst e1 x e')
|
LNRAMap (
LNRALambda y e1)
e2 =>
if (
y ==
x)
then LNRAMap (
LNRALambda y e1) (
lambda_nra_subst e2 x e')
else LNRAMap (
LNRALambda y (
lambda_nra_subst e1 x e')) (
lambda_nra_subst e2 x e')
|
LNRAMapConcat (
LNRALambda y e1)
e2 =>
if (
y ==
x)
then LNRAMapConcat (
LNRALambda y e1) (
lambda_nra_subst e2 x e')
else LNRAMapConcat (
LNRALambda y (
lambda_nra_subst e1 x e')) (
lambda_nra_subst e2 x e')
|
LNRAProduct e1 e2 =>
LNRAProduct (
lambda_nra_subst e1 x e') (
lambda_nra_subst e2 x e')
|
LNRAFilter (
LNRALambda y e1)
e2 =>
if (
y ==
x)
then LNRAFilter (
LNRALambda y e1) (
lambda_nra_subst e2 x e')
else LNRAFilter (
LNRALambda y (
lambda_nra_subst e1 x e')) (
lambda_nra_subst e2 x e')
end.
End LambdaNRAScope.
Section Top.
Definition q_to_lambda (
Q:
lambda_nra ->
lambda_nra) :
lnra_lambda :=
(
LNRALambda "
input" (
Q (
LNRAVar "
input"))).
Definition lnra_lambda_eval_top (
Q:
lambda_nra ->
lambda_nra)
(
global_env:
bindings) (
input:
data) :
option data :=
lnra_lambda_eval global_env nil (
q_to_lambda Q)
input.
Definition lambda_nra_eval_top (
q:
lambda_nra) (
env:
bindings) :
option data :=
lambda_nra_eval (
rec_sort env)
nil q.
End Top.
End LambdaNRA.
Hint Rewrite @
lnra_lambda_eval_lambda_eq :
lambda_nra.
Hint Rewrite @
lambda_nra_eval_var_eq :
lambda_nra.
Hint Rewrite @
lambda_nra_eval_binop_eq :
lambda_nra.
Hint Rewrite @
lambda_nra_eval_unop_eq :
lambda_nra.
Hint Rewrite @
lambda_nra_eval_map_eq :
lambda_nra.
Hint Rewrite @
lambda_nra_eval_map_concat_eq :
lambda_nra.
Hint Rewrite @
lambda_nra_eval_product_eq :
lambda_nra.
Hint Rewrite @
lambda_nra_eval_filter_eq :
lambda_nra.
Tactic Notation "
lambda_nra_cases"
tactic(
first)
ident(
c) :=
first;
[
Case_aux c "
LNRAVar"%
string
|
Case_aux c "
LNRATable"%
string
|
Case_aux c "
LNRAConst"%
string
|
Case_aux c "
LNRABinop"%
string
|
Case_aux c "
LNRAUnop"%
string
|
Case_aux c "
LNRAMap"%
string
|
Case_aux c "
LNRAMapConcat"%
string
|
Case_aux c "
LNRAProduct"%
string
|
Case_aux c "
LNRAFilter"%
string
].