Module Qcert.Translation.Lang.NNRSimptoImpData
Require Import String.
Require Import List.
Require Import Bool.
Require Import Arith.
Require Import EquivDec.
Require Import Morphisms.
Require Import Permutation.
Require Import Eqdep_dec.
Require Import Utils.
Require Import DataRuntime.
Require Import NNRSimpRuntime.
Require Import Imp.
Require Import ImpData.
Require Import ImpDataEval.
Section NNRSimptoImpData.
Import ListNotations.
Context {
fruntime:
foreign_runtime}.
Translation
Section Translation.
Fixpoint nnrs_imp_expr_to_imp_data (
constants:
string) (
exp:
nnrs_imp_expr):
imp_data_expr :=
match exp with
|
NNRSimpGetConstant x =>
ImpExprOp (
DataOpUnary (
OpDot x)) [
ImpExprVar constants ]
|
NNRSimpVar x =>
ImpExprVar x
|
NNRSimpConst d =>
ImpExprConst d
|
NNRSimpBinop op e1 e2 =>
let e1' :=
nnrs_imp_expr_to_imp_data constants e1 in
let e2' :=
nnrs_imp_expr_to_imp_data constants e2 in
ImpExprOp (
DataOpBinary op) [
e1';
e2']
|
NNRSimpUnop op e =>
let e' :=
nnrs_imp_expr_to_imp_data constants e in
ImpExprOp (
DataOpUnary op) [
e']
|
NNRSimpGroupBy g fields e =>
let e' :=
nnrs_imp_expr_to_imp_data constants e in
ImpExprRuntimeCall (
DataRuntimeGroupby g fields) [
e' ]
end.
Fixpoint nnrs_imp_stmt_to_imp_data (
constants:
string) (
stmt:
nnrs_imp_stmt):
imp_data_stmt :=
match stmt with
|
NNRSimpSkip =>
@
ImpStmtBlock imp_data_model imp_data_op imp_data_runtime_op [] []
|
NNRSimpSeq s1 s2 =>
ImpStmtBlock
[]
[
nnrs_imp_stmt_to_imp_data constants s1;
nnrs_imp_stmt_to_imp_data constants s2 ]
|
NNRSimpLet x e s =>
ImpStmtBlock
[ (
x,
lift (
nnrs_imp_expr_to_imp_data constants)
e) ]
[
nnrs_imp_stmt_to_imp_data constants s ]
|
NNRSimpAssign x e =>
ImpStmtAssign x (
nnrs_imp_expr_to_imp_data constants e)
|
NNRSimpFor x e s =>
ImpStmtFor x (
nnrs_imp_expr_to_imp_data constants e) (
nnrs_imp_stmt_to_imp_data constants s)
|
NNRSimpIf e s1 s2 =>
ImpStmtIf
(
nnrs_imp_expr_to_imp_data constants e)
(
nnrs_imp_stmt_to_imp_data constants s1)
(
nnrs_imp_stmt_to_imp_data constants s2)
|
NNRSimpEither e x1 s1 x2 s2 =>
let e' :=
nnrs_imp_expr_to_imp_data constants e in
ImpStmtIf
(
ImpExprRuntimeCall DataRuntimeEither [
e'])
(
ImpStmtBlock
[ (
x1,
Some (
ImpExprRuntimeCall DataRuntimeToLeft [
e'])) ]
[
nnrs_imp_stmt_to_imp_data constants s1 ])
(
ImpStmtBlock
[ (
x2,
Some (
ImpExprRuntimeCall DataRuntimeToRight [
e'])) ]
[
nnrs_imp_stmt_to_imp_data constants s2 ])
end.
Definition nnrs_imp_to_imp_data_function (
q:
nnrs_imp):
imp_function :=
let (
stmt,
ret) :=
q in
let constants :=
let fv :=
nnrs_imp_stmt_free_vars stmt in
let bv :=
nnrs_imp_stmt_bound_vars stmt in
fresh_var "
constants"%
string (
ret ::
fv ++
bv)
in
let body :=
nnrs_imp_stmt_to_imp_data constants stmt in
ImpFun constants body ret.
Definition nnrs_imp_to_imp_data_top (
qname:
string) (
q:
nnrs_imp):
imp :=
ImpLib [ (
qname,
nnrs_imp_to_imp_data_function q) ].
End Translation.
Section Correctness.
Lemma nnrs_imp_expr_to_imp_data_correct h (σ
c:
bindings) (σ:
pd_bindings) (
exp:
nnrs_imp_expr) :
forall constants:
string,
let σ0 :
pd_bindings :=
σ ++ [(
constants,
Some (
drec σ
c))]
in
~
In constants (
nnrs_imp_expr_free_vars exp) ->
lookup equiv_dec σ
constants =
None ->
nnrs_imp_expr_eval h σ
c σ
exp =
imp_data_expr_eval h σ0 (
nnrs_imp_expr_to_imp_data constants exp).
Proof.
intros constants.
nnrs_imp_expr_cases (
induction exp)
Case;
simpl.
-
Case "
NNRSimpGetConstant"%
string.
intros Hfv Hσ.
rewrite (
lookup_app equiv_dec constants).
unfold olift.
unfold Var.var.
unfold imp_data_model.
case_eq (
lookup equiv_dec σ
constants);
try congruence.
intros.
unfold lookup.
case (
equiv_dec constants constants);
try congruence.
intros.
reflexivity.
-
Case "
NNRSimpVar"%
string.
intros Hfv Hσ.
rewrite (
lookup_app equiv_dec v).
unfold id.
unfold olift.
unfold Var.var.
unfold imp_data_model.
case_eq (
lookup equiv_dec σ
v);
try reflexivity.
intros Hv.
case_eq (
lookup equiv_dec [(
constants,
Some (
drec σ
c))]
v);
try congruence.
intros.
simpl in H.
destruct Hfv.
left.
case_eq (
equiv_dec v constants);
try congruence.
intros.
unfold Var.var in *.
rewrite H0 in H.
congruence.
-
Case "
NNRSimpConst"%
string.
reflexivity.
-
Case "
NNRSimpBinop"%
string.
intros Hfv Hσ.
simpl in *.
rewrite app_or_in_iff in Hfv.
apply notand in Hfv.
destruct Hfv as [
Hfv1 Hfv2 ].
rewrite <- (
IHexp1 Hfv1 Hσ).
rewrite <- (
IHexp2 Hfv2 Hσ).
match_destr.
match_destr.
-
Case "
NNRSimpUnop"%
string.
intros Hfv Hσ.
simpl in *.
rewrite <-
IHexp;
trivial.
match_destr.
-
Case "
NNRSimpGroupBy"%
string.
intros Hfv Hσ.
simpl in *.
rewrite <-
IHexp;
trivial.
match_destr.
Qed.
Lemma nnrs_imp_stmt_to_imp_data_correct h (σ
c:
bindings) (σ:
pd_bindings) (
stmt:
nnrs_imp_stmt) :
forall constants:
string,
let σ0 :
pd_bindings :=
σ ++ [(
constants,
Some (
drec σ
c))]
in
~
In constants (
nnrs_imp_stmt_free_vars stmt) ->
~
In constants (
nnrs_imp_stmt_bound_vars stmt) ->
lookup equiv_dec σ
constants =
None ->
olift (
fun σ
r =>
Some (σ
r ++ [(
constants,
Some (
drec σ
c))]))
(
nnrs_imp_stmt_eval h σ
c stmt σ) =
imp_data_stmt_eval h (
nnrs_imp_stmt_to_imp_data constants stmt) σ0.
Proof.
Lemma nnrs_imp_to_imp_data_function_correct h (σ
c:
bindings) (
q:
nnrs_imp) :
olift id (
nnrs_imp_eval h (
rec_sort σ
c)
q) =
imp_data_function_eval h (
nnrs_imp_to_imp_data_function q) (
drec (
rec_sort σ
c)).
Proof.
Theorem nnrs_imp_to_imp_data_top_correct h (σ
c:
bindings) (
qname:
string) (
q:
nnrs_imp) :
nnrs_imp_eval_top h σ
c q =
imp_data_eval_top h σ
c (
nnrs_imp_to_imp_data_top qname q).
Proof.
End Correctness.
End NNRSimptoImpData.