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.
Require Import NNRSimp.
Section NNRSimpSem.
Context {
fruntime:
foreign_runtime}.
Context (
h:
brand_relation_t).
Local Open Scope nnrs_imp.
Local Open Scope string.
Section Denotation.
Context (σ
c:
list (
string*
data)).
Reserved Notation "[ σ ⊢
e ⇓
d ]".
Inductive nnrs_imp_expr_sem :
pd_bindings ->
nnrs_imp_expr ->
data ->
Prop :=
|
sem_NNRSimpGetConstant :
forall v σ
d,
edot σ
c v =
Some d ->
(* Γc(v) = d *)
[ σ ⊢
NNRSimpGetConstant v ⇓
d ]
|
sem_NNRSimpVar :
forall v σ
d,
lookup equiv_dec σ
v =
Some (
Some d) ->
(* Γ(v) = d *)
[ σ ⊢
NNRSimpVar v ⇓
d ]
|
sem_NNRSimpConst :
forall d₁ σ
d₂,
normalize_data h d₁ =
d₂ ->
(* norm(d₁) = d₂ *)
[ σ ⊢
NNRSimpConst d₁ ⇓
d₂ ]
|
sem_NNRSimpBinop :
forall bop e₁
e₂ σ
d₁
d₂
d,
[ σ ⊢
e₁ ⇓
d₁ ] ->
[ σ ⊢
e₂ ⇓
d₂ ] ->
binary_op_eval h bop d₁
d₂ =
Some d ->
[ σ ⊢
NNRSimpBinop bop e₁
e₂ ⇓
d ]
|
sem_NNRSimpUnop :
forall uop e σ
d₁
d,
[ σ ⊢
e ⇓
d₁ ] ->
unary_op_eval h uop d₁ =
Some d ->
[ σ ⊢
NNRSimpUnop uop e ⇓
d ]
|
sem_NNRSimpGroupBy :
forall g sl e σ
d₁
d₂ ,
[ σ ⊢
e ⇓ (
dcoll d₁) ] ->
group_by_nested_eval_table g sl d₁ =
Some d₂ ->
[ σ ⊢
NNRSimpGroupBy g sl e ⇓ (
dcoll d₂) ]
where
"[ σ ⊢
e ⇓
d ]" := (
nnrs_imp_expr_sem σ
e d) :
nnrs_imp_scope
.
Reserved Notation "[
s₁ , σ₁ ⇓ σ₂ ]".
Reserved Notation "[
s , σ₁ ⇓[
v <-
dl ] σ₂ ]".
Inductive nnrs_imp_stmt_sem :
nnrs_imp_stmt ->
pd_bindings ->
pd_bindings ->
Prop :=
|
sem_NNRSimpSkip σ :
[
NNRSimpSkip, σ ⇓ σ ]
|
sem_NNRSimpSeq s₁
s₂ σ₁ σ₂ σ₃ :
[
s₁, σ₁ ⇓ σ₂ ] ->
[
s₂, σ₂ ⇓ σ₃ ] ->
[
NNRSimpSeq s₁
s₂, σ₁ ⇓ σ₃ ]
|
sem_NNRSimpAssign v e σ
d :
In v (
domain σ) ->
[ σ ⊢
e ⇓
d ] ->
[
NNRSimpAssign v e, σ ⇓
update_first string_dec σ
v (
Some d)]
|
sem_NNRSimpLetNone v s σ₁ σ₂
dd :
[
s, (
v,
None)::σ₁ ⇓ (
v,
dd)::σ₂ ] ->
[
NNRSimpLet v None s, σ₁ ⇓ σ₂ ]
|
sem_NNRSimpLetSome v e s σ₁ σ₂
d dd :
[ σ₁ ⊢
e ⇓
d ] ->
[
s, (
v,
Some d)::σ₁ ⇓ (
v,
dd)::σ₂ ] ->
[
NNRSimpLet v (
Some e)
s, σ₁ ⇓ σ₂ ]
|
sem_NNRSimpFor v e s σ₁ σ₂
dl :
[ σ₁ ⊢
e ⇓ (
dcoll dl) ] ->
[
s, σ₁ ⇓[
v<-
dl] σ₂ ] ->
[
NNRSimpFor v e s, σ₁ ⇓ σ₂ ]
|
sem_NNRSimpIfTrue e s₁
s₂ σ₁ σ₂ :
[ σ₁ ⊢
e ⇓ (
dbool true) ] ->
[
s₁, σ₁ ⇓ σ₂ ] ->
[
NNRSimpIf e s₁
s₂, σ₁ ⇓ σ₂ ]
|
sem_NNRSimpIfFalse e s₁
s₂ σ₁ σ₂ :
[ σ₁ ⊢
e ⇓ (
dbool false) ] ->
[
s₂, σ₁ ⇓ σ₂ ] ->
[
NNRSimpIf e s₁
s₂, σ₁ ⇓ σ₂ ]
|
sem_NNRSimpEitherLeft e x₁
s₁
x₂
s₂ σ₁ σ₂
d dd :
[ σ₁ ⊢
e ⇓ (
dleft d) ] ->
[
s₁, (
x₁,
Some d)::σ₁ ⇓ (
x₁,
dd)::σ₂ ] ->
[
NNRSimpEither e x₁
s₁
x₂
s₂, σ₁ ⇓ σ₂]
|
sem_NNRSimpEitherRight e x₁
s₁
x₂
s₂ σ₁ σ₂
d dd :
[ σ₁ ⊢
e ⇓ (
dright d) ] ->
[
s₂, (
x₂,
Some d)::σ₁ ⇓ (
x₂,
dd)::σ₂ ] ->
[
NNRSimpEither e x₁
s₁
x₂
s₂, σ₁ ⇓ σ₂ ]
with nnrs_imp_stmt_sem_iter:
var ->
list data ->
nnrs_imp_stmt ->
pd_bindings ->
pd_bindings ->
Prop :=
|
sem_NNRSimpIter_nil v s σ :
[
s, σ ⇓[
v<-
nil] σ ]
|
sem_NNRSimpIter_cons v s σ₁ σ₂ σ₃
d dl dd:
[
s, (
v,
Some d)::σ₁ ⇓ (
v,
dd)::σ₂] ->
[
s, σ₂ ⇓[
v<-
dl] σ₃ ] ->
[
s, σ₁ ⇓[
v<-
d::
dl] σ₃ ]
where
"[
s , σ₁ ⇓ σ₂ ]" := (
nnrs_imp_stmt_sem s σ₁ σ₂) :
nnrs_imp_scope
and "[
s , σ₁ ⇓[
v <-
dl ] σ₂ ]" := (
nnrs_imp_stmt_sem_iter v dl s σ₁ σ₂ ) :
nnrs_imp_scope.
Notation "[
s , σ₁ ⇓ σ₂ ]" := (
nnrs_imp_stmt_sem s σ₁ σ₂ ) :
nnrs_imp_scope.
Notation "[
s , σ₁ ⇓[
v <-
dl ] σ₂ ]" := (
nnrs_imp_stmt_sem_iter v dl s σ₁ σ₂) :
nnrs_imp_scope.
End Denotation.
Reserved Notation "[ σ
c ⊢
q ⇓
d ]".
Notation "[ σ
c ; σ ⊢
e ⇓
d ]" := (
nnrs_imp_expr_sem σ
c σ
e d) :
nnrs_imp_scope.
Notation "[ σ
c ⊢
s , σ₁ ⇓ σ₂ ]" := (
nnrs_imp_stmt_sem σ
c s σ₁ σ₂ ) :
nnrs_imp_scope.
Notation "[ σ
c ⊢
s , σ₁ ⇓[
v <-
dl ] σ₂ ]" := (
nnrs_imp_stmt_sem_iter σ
c v dl s σ₁ σ₂) :
nnrs_imp_scope.
Inductive nnrs_imp_sem :
bindings ->
nnrs_imp ->
option data ->
Prop
:=
|
sem_NNRSimp (σ
c:
bindings) (
q:
nnrs_imp)
o :
[ σ
c ⊢ (
fst q), ((
snd q),
None)::
nil ⇓ ((
snd q),
o)::
nil ] ->
[ σ
c ⊢
q ⇓
o ]
where
"[ σ
c ⊢
q ⇓
o ]" := (
nnrs_imp_sem σ
c q o ) :
nnrs_imp_scope.
Definition nnrs_imp_sem_top (σ
c:
bindings) (
q:
nnrs_imp) (
d:
data) :
Prop
:= [ (
rec_sort σ
c) ⊢
q ⇓
Some d ].
Notation "[ σ
c ⊢
q ⇓
d ]" := (
nnrs_imp_sem σ
c q d ) :
nnrs_imp_scope.
Section Core.
Program Definition nnrs_imp_core_sem σ
c (
q:
nnrs_imp_core) (
d:
option data) :
Prop
:=
nnrs_imp_sem σ
c q d.
Notation "[ σ
c ⊢
q ⇓ᶜ
d ]" := (
nnrs_imp_core_sem σ
c q d ) :
nnrs_imp_scope.
Definition nnrs_imp_core_sem_top (σ
c:
bindings) (
q:
nnrs_imp_core) (
d:
data) :
Prop
:= [ (
rec_sort σ
c) ⊢
q ⇓ᶜ
Some d ].
End Core.
Section props.
Context (σ
c:
list (
string*
data)).
Lemma nnrs_imp_stmt_sem_env_stack {
s σ₁ σ₂ }:
[ σ
c ⊢
s, σ₁ ⇓ σ₂ ] ->
domain σ₁ =
domain σ₂.
Proof.
revert σ₁ σ₂.
nnrs_imp_stmt_cases (
induction s)
Case;
intros σ₁ σ₂
sem;
invcs sem.
-
Case "
NNRSimpSkip".
trivial.
-
Case "
NNRSimpSeq".
transitivity (
domain σ₂0);
eauto.
-
Case "
NNRSimpAssign".
rewrite domain_update_first;
trivial.
-
Case "
NNRSimpLet".
specialize (
IHs _ _ H4).
simpl in IHs;
invcs IHs.
trivial.
-
Case "
NNRSimpLet".
specialize (
IHs _ _ H5).
simpl in IHs;
invcs IHs.
trivial.
-
Case "
NNRSimpFor".
clear H4.
revert σ₁ σ₂
H5.
induction dl;
intros σ₁ σ₂
sem;
invcs sem;
trivial.
specialize (
IHdl _ _ H6).
specialize (
IHs _ _ H2).
simpl in IHs;
invcs IHs.
congruence.
-
Case "
NNRSimpIf".
eauto.
-
Case "
NNRSimpIf".
eauto.
-
Case "
NNRSimpEither".
specialize (
IHs1 _ _ H7).
simpl in IHs1;
invcs IHs1;
trivial.
-
Case "
NNRSimpEither".
specialize (
IHs2 _ _ H7).
simpl in IHs2;
invcs IHs2;
trivial.
Qed.
Lemma nnrs_imp_stmt_sem_env_cons_same
{
s v₁
od₁ σ₁
v₂
od₂ σ₂ } :
[ σ
c ⊢
s, (
v₁,
od₁) :: σ₁ ⇓ (
v₂,
od₂) :: σ₂] ->
[ σ
c ⊢
s, (
v₁,
od₁) :: σ₁ ⇓ (
v₁,
od₂) :: σ₂ ].
Proof.
End props.
End NNRSimpSem.
Notation "[
h , σ
c ; σ ⊢
e ⇓
d ]" := (
nnrs_imp_expr_sem h σ
c σ
e d) :
nnrs_imp_scope.
Notation "[
h , σ
c ⊢
s , σ₁ ⇓ σ₂ ]" := (
nnrs_imp_stmt_sem h σ
c s σ₁ σ₂ ) :
nnrs_imp_scope.
Notation "[
h , σ
c ⊢
s , σ₁ ⇓[
v <-
dl ] σ₂ ]" := (
nnrs_imp_stmt_sem_iter h σ
c v dl s σ₁ σ₂) :
nnrs_imp_scope.
Notation "[
h , σ
c ⊢
q ⇓
d ]" := (
nnrs_imp_sem h σ
c q d ) :
nnrs_imp_scope.
Notation "[
h , σ
c ⊢
q ⇓ᶜ
d ]" := (
nnrs_imp_core_sem h σ
c q d ) :
nnrs_imp_scope.
Arguments nnrs_imp_stmt_sem_env_stack {
fruntime h σ
c s σ₁ σ₂}.
Arguments nnrs_imp_stmt_sem_env_cons_same {
fruntime h σ
c s v₁
od₁ σ₁
v₂
od₂ σ₂}.