NNRSimp 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.
Declare Scope nnrs_imp_scope.
Section NNRSimp.
Section Syntax.
Context {
fruntime:
foreign_runtime}.
Inductive nnrs_imp_expr :=
|
NNRSimpGetConstant :
var ->
nnrs_imp_expr (* global variable lookup ($$v) *)
|
NNRSimpVar :
var ->
nnrs_imp_expr (* local variable lookup ($v) *)
|
NNRSimpConst :
data ->
nnrs_imp_expr (* constant data (d) *)
|
NNRSimpBinop :
binary_op ->
nnrs_imp_expr ->
nnrs_imp_expr ->
nnrs_imp_expr (* binary operator (e₁ ⊠ e₂) *)
|
NNRSimpUnop :
unary_op ->
nnrs_imp_expr ->
nnrs_imp_expr (* unary operator (⊞ e) *)
|
NNRSimpGroupBy :
string ->
list string ->
nnrs_imp_expr ->
nnrs_imp_expr (* group by expression (e groupby g fields) -- only in full NNRC *)
.
Inductive nnrs_imp_stmt :=
|
NNRSimpSkip :
nnrs_imp_stmt
|
NNRSimpSeq :
nnrs_imp_stmt ->
nnrs_imp_stmt ->
nnrs_imp_stmt (* sequence (s₁; s₂]) *)
|
NNRSimpAssign :
var ->
nnrs_imp_expr ->
nnrs_imp_stmt (* variable assignent ($v := e) *)
|
NNRSimpLet :
var ->
option nnrs_imp_expr ->
nnrs_imp_stmt ->
nnrs_imp_stmt (* variable declaration (var $v := e₁?; s₂) *)
|
NNRSimpFor :
var ->
nnrs_imp_expr ->
nnrs_imp_stmt ->
nnrs_imp_stmt (* for loop (for ($v in e₁) { s₂ }) *)
|
NNRSimpIf :
nnrs_imp_expr ->
nnrs_imp_stmt ->
nnrs_imp_stmt ->
nnrs_imp_stmt (* conditional (if e₁ { s₂ } else { s₃ }) *)
|
NNRSimpEither :
nnrs_imp_expr (* case expression (either e case left $v₁ { s₁ } case right $v₂ { s₂ }) *)
->
var ->
nnrs_imp_stmt
->
var ->
nnrs_imp_stmt ->
nnrs_imp_stmt
.
nnrs_imp is composed of the statement evaluating the query
and the variable containing the result of the evaluation
Definition nnrs_imp :
Set := (
nnrs_imp_stmt *
var).
End Syntax.
Section dec.
Context {
fruntime:
foreign_runtime}.
Global Instance nnrs_imp_expr_eqdec :
EqDec nnrs_imp_expr eq.
Proof.
Global Instance nnrs_imp_stmt_eqdec :
EqDec nnrs_imp_stmt eq.
Proof.
Global Instance nnrs_imp_eqdec :
EqDec nnrs_imp eq.
Proof.
intros [s1 r1] [s2 r2].
destruct (r1 == r2).
- destruct (s1 == s2).
+ left; congruence.
+ right; congruence.
- right; congruence.
Defined.
End dec.
Section Core.
Context {
fruntime:
foreign_runtime}.
Fixpoint nnrs_imp_exprIsCore (
e:
nnrs_imp_expr) :
Prop :=
match e with
|
NNRSimpGetConstant _ =>
True
|
NNRSimpVar _ =>
True
|
NNRSimpConst _ =>
True
|
NNRSimpBinop _ e1 e2 =>
nnrs_imp_exprIsCore e1 /\
nnrs_imp_exprIsCore e2
|
NNRSimpUnop _ e1 =>
nnrs_imp_exprIsCore e1
|
NNRSimpGroupBy _ _ _ =>
False
end.
Fixpoint nnrs_imp_stmtIsCore (
s:
nnrs_imp_stmt) :
Prop :=
match s with
|
NNRSimpSkip =>
True
|
NNRSimpSeq s1 s2 =>
nnrs_imp_stmtIsCore s1 /\
nnrs_imp_stmtIsCore s2
|
NNRSimpLet _ (
Some e)
s1 =>
nnrs_imp_exprIsCore e /\
nnrs_imp_stmtIsCore s1
|
NNRSimpLet _ None s1 =>
nnrs_imp_stmtIsCore s1
|
NNRSimpAssign _ e =>
nnrs_imp_exprIsCore e
|
NNRSimpFor _ e s1 =>
nnrs_imp_exprIsCore e /\
nnrs_imp_stmtIsCore s1
|
NNRSimpIf e s1 s2 =>
nnrs_imp_exprIsCore e /\
nnrs_imp_stmtIsCore s1 /\
nnrs_imp_stmtIsCore s2
|
NNRSimpEither e _ s1 _ s2 =>
nnrs_imp_exprIsCore e /\
nnrs_imp_stmtIsCore s1 /\
nnrs_imp_stmtIsCore s2
end .
Definition nnrs_impIsCore (
sr:
nnrs_imp) :=
nnrs_imp_stmtIsCore (
fst sr).
Definition nnrs_imp_core :
Set := {
sr:
nnrs_imp |
nnrs_impIsCore sr}.
Definition nnrs_imp_core_to_nnrs_imp (
sr:
nnrs_imp_core) :
nnrs_imp :=
proj1_sig sr.
Section ext.
Lemma nnrs_imp_exprIsCore_ext (
e:
nnrs_imp_expr) (
pf1 pf2:
nnrs_imp_exprIsCore e) :
pf1 =
pf2.
Proof.
induction e; simpl in *;
try (destruct pf1; destruct pf2; trivial);
try f_equal; auto.
Qed.
Lemma nnrs_imp_stmtIsCore_ext (
s:
nnrs_imp_stmt) (
pf1 pf2:
nnrs_imp_stmtIsCore s) :
pf1 =
pf2.
Proof.
induction s;
simpl in *;
try (
destruct o);
try (
destruct pf1;
destruct pf2;
trivial);
try (
destruct a;
destruct a0);
try f_equal;
eauto;
try eapply nnrs_imp_exprIsCore_ext;
eauto
;
try f_equal;
eauto.
Qed.
Lemma nnrs_impIsCore_ext (
e:
nnrs_imp) (
pf1 pf2:
nnrs_impIsCore e) :
pf1 =
pf2.
Proof.
Lemma nnrs_imp_core_ext e (
pf1 pf2:
nnrs_impIsCore e) :
exist _ e pf1 =
exist _ e pf2.
Proof.
Lemma nnrs_imp_core_fequal (
e1 e2:
nnrs_imp_core) :
proj1_sig e1 =
proj1_sig e2 ->
e1 =
e2.
Proof.
destruct e1;
destruct e2;
simpl;
intros eqq.
destruct eqq.
apply nnrs_imp_core_ext.
Qed.
End ext.
Section dec.
Lemma nnrs_imp_exprIsCore_dec (
e:
nnrs_imp_expr) :
{
nnrs_imp_exprIsCore e} + {~
nnrs_imp_exprIsCore e}.
Proof.
induction e; simpl; try eauto 3.
destruct IHe1.
- destruct IHe2; [left|right]; intuition.
- right; intuition.
Defined.
Lemma nnrs_imp_stmtIsCore_dec (
s:
nnrs_imp_stmt) :
{
nnrs_imp_stmtIsCore s} + {~
nnrs_imp_stmtIsCore s}.
Proof.
induction s;
simpl.
-
left;
trivial.
-
destruct IHs1.
+
destruct IHs2; [
left|
right];
intuition.
+
right;
intuition.
-
apply (
nnrs_imp_exprIsCore_dec n).
-
destruct o.
+
destruct (
nnrs_imp_exprIsCore_dec n).
*
destruct IHs; [
left|
right];
intuition.
*
right;
intuition.
+
apply IHs.
-
destruct (
nnrs_imp_exprIsCore_dec n).
+
destruct IHs; [
left|
right];
intuition.
+
right;
intuition.
-
destruct (
nnrs_imp_exprIsCore_dec n).
+
destruct IHs1.
*
destruct IHs2; [
left|
right];
intuition.
*
right;
intuition.
+
right;
intuition.
-
destruct (
nnrs_imp_exprIsCore_dec n).
+
destruct IHs1.
*
destruct IHs2; [
left|
right];
intuition.
*
right;
intuition.
+
right;
intuition.
Defined.
Lemma nnrs_impIsCore_dec (
sr:
nnrs_imp) :
{
nnrs_impIsCore sr} + {~
nnrs_impIsCore sr}.
Proof.
Global Instance nnrs_imp_core_eqdec :
EqDec nnrs_imp_core eq.
Proof.
intros x y.
destruct x as [
x xpf];
destruct y as [
y ypf].
destruct (
x ==
y).
-
left.
apply nnrs_imp_core_fequal;
simpl;
trivial.
-
right.
inversion 1;
congruence.
Defined.
End dec.
End Core.
Section Env.
Context {
fruntime:
foreign_runtime}.
Definition pd_bindings :=
list (
string*
option data).
End Env.
End NNRSimp.
Tactic Notation "
nnrs_imp_expr_cases"
tactic(
first)
ident(
c) :=
first;
[
Case_aux c "
NNRSimpGetConstant"%
string
|
Case_aux c "
NNRSimpVar"%
string
|
Case_aux c "
NNRSimpConst"%
string
|
Case_aux c "
NNRSimpBinop"%
string
|
Case_aux c "
NNRSimpUnop"%
string
|
Case_aux c "
NNRSimpGroupBy"%
string].
Tactic Notation "
nnrs_imp_stmt_cases"
tactic(
first)
ident(
c) :=
first;
[
Case_aux c "
NNRSimpSkip"%
string
|
Case_aux c "
NNRSimpSeq"%
string
|
Case_aux c "
NNRSimpAssign"%
string
|
Case_aux c "
NNRSimpLet"%
string
|
Case_aux c "
NNRSimpFor"%
string
|
Case_aux c "
NNRSimpIf"%
string
|
Case_aux c "
NNRSimpEither"%
string].
Delimit Scope nnrs_imp_scope with nnrs_imp.
Notation "‵‵
c" := (
NNRSimpConst (
dconst c)) (
at level 0) :
nnrs_imp_scope.
Notation "‵
c" := (
NNRSimpConst c) (
at level 0) :
nnrs_imp_scope.
Notation "‵{||}" := (
NNRSimpConst (
dcoll nil)) (
at level 0) :
nnrs_imp_scope.
Notation "‵[||]" := (
NNRSimpConst (
drec nil)) (
at level 50) :
nnrs_imp_scope.
Notation "
r1 ∧
r2" := (
NNRSimpBinop OpAnd r1 r2) (
right associativity,
at level 65):
nnrs_imp_scope.
Notation "
r1 ∨
r2" := (
NNRSimpBinop OpOr r1 r2) (
right associativity,
at level 70):
nnrs_imp_scope.
Notation "
r1 ≐
r2" := (
NNRSimpBinop OpEqual r1 r2) (
right associativity,
at level 70):
nnrs_imp_scope.
Notation "
r1 ≤
r2" := (
NNRSimpBinop OpLe r1 r2) (
no associativity,
at level 70):
nnrs_imp_scope.
Notation "
r1 ⋃
r2" := (
NNRSimpBinop OpBagUnion r1 r2) (
right associativity,
at level 70):
nnrs_imp_scope.
Notation "
r1 −
r2" := (
NNRSimpBinop OpBagDiff r1 r2) (
right associativity,
at level 70):
nnrs_imp_scope.
Notation "
r1 ⋂
min r2" := (
NNRSimpBinop OpBagMin r1 r2) (
right associativity,
at level 70):
nnrs_imp_scope.
Notation "
r1 ⋃
max r2" := (
NNRSimpBinop OpBagMax r1 r2) (
right associativity,
at level 70):
nnrs_imp_scope.
Notation "
p ⊕
r" := ((
NNRSimpBinop OpRecConcat)
p r) (
at level 70) :
nnrs_imp_scope.
Notation "
p ⊗
r" := ((
NNRSimpBinop OpRecMerge)
p r) (
at level 70) :
nnrs_imp_scope.
Notation "¬(
r1 )" := (
NNRSimpUnop OpNeg r1) (
right associativity,
at level 70):
nnrs_imp_scope.
Notation "ε(
r1 )" := (
NNRSimpUnop OpDistinct r1) (
right associativity,
at level 70):
nnrs_imp_scope.
Notation "♯
count(
r1 )" := (
NNRSimpUnop OpCount r1) (
right associativity,
at level 70):
nnrs_imp_scope.
Notation "♯
flatten(
d )" := (
NNRSimpUnop OpFlatten d) (
at level 50) :
nnrs_imp_scope.
Notation "‵{|
d |}" := ((
NNRSimpUnop OpBag)
d) (
at level 50) :
nnrs_imp_scope.
Notation "‵[| (
s ,
r ) |]" := ((
NNRSimpUnop (
OpRec s))
r) (
at level 50) :
nnrs_imp_scope.
Notation "¬π[
s1 ](
r )" := ((
NNRSimpUnop (
OpRecRemove s1))
r) (
at level 50) :
nnrs_imp_scope.
Notation "π[
s1 ](
r )" := ((
NNRSimpUnop (
OpRecProject s1))
r) (
at level 50) :
nnrs_imp_scope.
Notation "
p ·
r" := ((
NNRSimpUnop (
OpDot r))
p) (
left associativity,
at level 40):
nnrs_imp_scope.
Notation "
r1 ‵+
r2" := (
NNRSimpBinop (
OpNatBinary NatPlus)
r1 r2) (
right associativity,
at level 65):
nnrs_imp_scope.
Notation "
r1 ‵*
r2" := (
NNRSimpBinop (
OpNatBinary NatMult)
r1 r2) (
right associativity,
at level 65):
nnrs_imp_scope.
Notation "‵
abs r" := (
NNRSimpUnop (
OpNatUnary NatAbs)
r) (
right associativity,
at level 64):
nnrs_imp_scope.