Module Qcert.Imp.Optim.ImpEJsonOptimizerEngine
Imp is a simpl imperative intermediate language.
Require
Import
String
.
Require
Import
List
.
Require
Import
Bool
.
Require
Import
Arith
.
Require
Import
ZArith
.
Require
Import
Utils
.
Require
Import
JsAst.JsNumber
.
Require
Import
EJsonRuntime
.
Require
Import
Imp
.
Require
Import
ImpEJson
.
Require
Import
ImpEJsonVars
.
Require
Import
ImpEJsonEval
.
Section
ImpEJsonOptimizerEngine
.
Import
ListNotations
.
Context
{
foreign_ejson_model
:
Set
}.
Context
{
fejson
:
foreign_ejson
foreign_ejson_model
}.
Context
{
foreign_ejson_runtime_op
:
Set
}.
Context
{
fejruntime
:
foreign_ejson_runtime
foreign_ejson_runtime_op
}.
Section
OptimizerEngine
.
Fixpoint
imp_ejson_stmt_block_rewrite
(
fs
:
imp_stmt
->
imp_stmt
)
(
stmt
: @
imp_ejson_stmt
foreign_ejson_model
foreign_ejson_runtime_op
)
:
imp_ejson_stmt
:=
match
stmt
with
|
ImpStmtBlock
lv
ls
=>
fs
(
ImpStmtBlock
lv
(
map
(
imp_ejson_stmt_block_rewrite
fs
)
ls
))
|
ImpStmtAssign
v
e
=>
fs
(
ImpStmtAssign
v
e
)
|
ImpStmtFor
v
e
s
=>
fs
(
ImpStmtFor
v
e
(
imp_ejson_stmt_block_rewrite
fs
s
))
|
ImpStmtForRange
v
e1
e2
s
=>
fs
(
ImpStmtForRange
v
e1
e2
(
imp_ejson_stmt_block_rewrite
fs
s
))
|
ImpStmtIf
e
s1
s2
=>
fs
(
ImpStmtIf
e
(
imp_ejson_stmt_block_rewrite
fs
s1
)
(
imp_ejson_stmt_block_rewrite
fs
s2
))
end
.
Definition
imp_ejson_function_block_rewrite
(
fs
:
imp_stmt
->
imp_stmt
)
(
f
:
imp_function
) :
imp_function
:=
match
f
with
|
ImpFun
v1
s
v2
=>
ImpFun
v1
(
imp_ejson_stmt_block_rewrite
fs
s
)
v2
end
.
Definition
imp_ejson_block_rewrite
(
fs
:
imp_stmt
->
imp_stmt
)
(
q
:
imp_ejson
) :
imp_ejson
:=
match
q
with
|
ImpLib
l
=>
ImpLib
(
map
(
fun
xy
=> (
fst
xy
,
imp_ejson_function_block_rewrite
fs
(
snd
xy
)))
l
)
end
.
End
OptimizerEngine
.
Section
CorrectnessOptimizerEngine
.
Lemma
imp_ejson_function_stmt_rewrite_correct
(
fs
:
imp_stmt
->
imp_stmt
)
h
(
j
:
pd_jbindings
) (
s
:
imp_ejson_stmt
) :
(
forall
s0
,
forall
j0
,
imp_ejson_stmt_eval
h
s0
j0
=
imp_ejson_stmt_eval
h
(
fs
s0
)
j0
) ->
imp_ejson_stmt_eval
h
s
j
=
imp_ejson_stmt_eval
h
(
imp_ejson_stmt_block_rewrite
fs
s
)
j
.
Proof.
revert
j
.
induction
s
;
intros
;
simpl
in
*.
-
rewrite
<-
H0
;
simpl
.
generalize
(@
ImpEval.imp_decls_eval
(@
imp_ejson_model
foreign_ejson_model
)
(@
imp_ejson_constant
foreign_ejson_model
)
imp_ejson_op
(@
imp_ejson_runtime_op
foreign_ejson_runtime_op
)
(@
imp_ejson_model_normalize
foreign_ejson_model
)
(@
imp_ejson_runtime_eval
foreign_ejson_model
fejson
foreign_ejson_runtime_op
fejruntime
h
) (@
imp_ejson_op_eval
foreign_ejson_model
)
j
el
);
intros
.
induction
el
;
intros
;
simpl
in
*;
try
reflexivity
.
+
destruct
o
;
intros
;
simpl
;
try
reflexivity
.
generalize
(
Some
p
).
induction
sl
;
intros
;
simpl
in
*;
try
reflexivity
.
inversion
H
;
clear
H
;
subst
.
destruct
o
;
simpl
;
try
reflexivity
.
*
rewrite
IHsl
;
clear
IHsl
; [|
assumption
].
assert
(
imp_ejson_stmt_eval
h
a
p0
=
imp_ejson_stmt_eval
h
(
imp_ejson_stmt_block_rewrite
fs
a
)
p0
)
by
apply
(
H3
p0
H0
).
rewrite
H
;
reflexivity
.
*
rewrite
IHsl
;
clear
IHsl
; [
reflexivity
|
assumption
].
+
rewrite
IHel
;
reflexivity
.
-
rewrite
<-
H
;
simpl
;
reflexivity
.
-
rewrite
<-
H
;
simpl
.
destruct
(@
ImpEval.imp_expr_eval
(@
imp_ejson_model
foreign_ejson_model
)
(@
imp_ejson_constant
foreign_ejson_model
)
imp_ejson_op
(@
imp_ejson_runtime_op
foreign_ejson_runtime_op
)
(@
imp_ejson_model_normalize
foreign_ejson_model
)
(@
imp_ejson_runtime_eval
foreign_ejson_model
fejson
foreign_ejson_runtime_op
fejruntime
h
)
(@
imp_ejson_op_eval
foreign_ejson_model
)
j
e
);
try
reflexivity
.
destruct
(
imp_ejson_model_to_list
i
);
try
reflexivity
.
revert
j
.
induction
l
;
intros
;
try
reflexivity
.
rewrite
<-
IHs
; [|
assumption
].
destruct
(@
imp_ejson_stmt_eval
foreign_ejson_model
fejson
foreign_ejson_runtime_op
fejruntime
h
s
(@
cons
(
prod
var
(
option
(@
imp_ejson_model
foreign_ejson_model
)))
(@
pair
var
(
option
(@
imp_ejson_model
foreign_ejson_model
))
v
(@
Some
(@
imp_ejson_model
foreign_ejson_model
)
a
))
j
));
try
reflexivity
.
destruct
p
;
try
reflexivity
.
apply
IHl
.
-
rewrite
<-
H
;
simpl
.
destruct
(@
olift
(@
imp_ejson_model
foreign_ejson_model
)
Z
(@
imp_ejson_model_to_Z
foreign_ejson_model
)
(@
ImpEval.imp_expr_eval
(@
imp_ejson_model
foreign_ejson_model
)
(@
imp_ejson_constant
foreign_ejson_model
)
imp_ejson_op
(@
imp_ejson_runtime_op
foreign_ejson_runtime_op
)
(@
imp_ejson_model_normalize
foreign_ejson_model
)
(@
imp_ejson_runtime_eval
foreign_ejson_model
fejson
foreign_ejson_runtime_op
fejruntime
h
) (@
imp_ejson_op_eval
foreign_ejson_model
)
j
e1
));
try
reflexivity
.
destruct
(@
olift
(@
imp_ejson_model
foreign_ejson_model
)
Z
(@
imp_ejson_model_to_Z
foreign_ejson_model
)
(@
ImpEval.imp_expr_eval
(@
imp_ejson_model
foreign_ejson_model
)
(@
imp_ejson_constant
foreign_ejson_model
)
imp_ejson_op
(@
imp_ejson_runtime_op
foreign_ejson_runtime_op
)
(@
imp_ejson_model_normalize
foreign_ejson_model
)
(@
imp_ejson_runtime_eval
foreign_ejson_model
fejson
foreign_ejson_runtime_op
fejruntime
h
) (@
imp_ejson_op_eval
foreign_ejson_model
)
j
e2
));
try
reflexivity
.
generalize
(
ImpEval.nb_iter
z
z0
);
clear
z0
;
intros
.
revert
z
j
.
induction
n
;
intros
;
try
reflexivity
.
rewrite
IHs
;
clear
IHs
; [|
assumption
].
destruct
(@
imp_ejson_stmt_eval
foreign_ejson_model
fejson
foreign_ejson_runtime_op
fejruntime
h
(
imp_ejson_stmt_block_rewrite
fs
s
)
(@
cons
(
prod
var
(
option
(@
imp_ejson_model
foreign_ejson_model
)))
(@
pair
var
(
option
(@
imp_ejson_model
foreign_ejson_model
))
v
(@
Some
(@
imp_ejson_model
foreign_ejson_model
)
(@
imp_ejson_Z_to_data
foreign_ejson_model
z
)))
j
));
try
reflexivity
.
destruct
p
;
try
reflexivity
.
apply
IHn
.
-
rewrite
<-
H
;
simpl
.
destruct
(@
ImpEval.imp_expr_eval
(@
imp_ejson_model
foreign_ejson_model
)
(@
imp_ejson_constant
foreign_ejson_model
)
imp_ejson_op
(@
imp_ejson_runtime_op
foreign_ejson_runtime_op
)
(@
imp_ejson_model_normalize
foreign_ejson_model
)
(@
imp_ejson_runtime_eval
foreign_ejson_model
fejson
foreign_ejson_runtime_op
fejruntime
h
)
(@
imp_ejson_op_eval
foreign_ejson_model
)
j
e
);
try
reflexivity
.
destruct
(
imp_ejson_model_to_bool
i
);
try
reflexivity
.
destruct
b
;
auto
.
Qed.
Lemma
imp_ejson_function_block_rewrite_correct
(
fs
:
imp_stmt
->
imp_stmt
)
h
(
j
:
ejson
) (
f
:
imp_ejson_function
) :
(
forall
s0
,
forall
j0
,
imp_ejson_stmt_eval
h
s0
j0
=
imp_ejson_stmt_eval
h
(
fs
s0
)
j0
) ->
imp_ejson_function_eval
h
f
j
=
imp_ejson_function_eval
h
(
imp_ejson_function_block_rewrite
fs
f
)
j
.
Proof.
intros
;
destruct
f
.
simpl
.
assert
(
imp_ejson_stmt_eval
h
i
[(
v0
,
None
); (
v
,
Some
j
)]
=
imp_ejson_stmt_eval
h
(
imp_ejson_stmt_block_rewrite
fs
i
) [(
v0
,
None
); (
v
,
Some
j
)])
by
(
apply
(
imp_ejson_function_stmt_rewrite_correct
fs
);
assumption
).
unfold
imp_ejson_stmt_eval
in
H0
;
simpl
in
*.
assert
(@
ImpEval.imp_stmt_eval
(@
imp_ejson_model
foreign_ejson_model
)
(@
imp_ejson_constant
foreign_ejson_model
)
imp_ejson_op
(@
imp_ejson_runtime_op
foreign_ejson_runtime_op
)
(@
imp_ejson_model_normalize
foreign_ejson_model
)
(@
imp_ejson_model_to_bool
foreign_ejson_model
)
(@
imp_ejson_model_to_Z
foreign_ejson_model
)
(@
imp_ejson_model_to_list
foreign_ejson_model
)
(@
imp_ejson_Z_to_data
foreign_ejson_model
)
(@
imp_ejson_runtime_eval
foreign_ejson_model
fejson
foreign_ejson_runtime_op
fejruntime
h
) (@
imp_ejson_op_eval
foreign_ejson_model
)
i
(@
cons
(
prod
var
(
option
(@
ejson
foreign_ejson_model
)))
(@
pair
var
(
option
(@
ejson
foreign_ejson_model
))
v0
(@
None
(@
ejson
foreign_ejson_model
)))
(@
cons
(
prod
var
(
option
(@
ejson
foreign_ejson_model
)))
(@
pair
var
(
option
(@
ejson
foreign_ejson_model
))
v
(@
Some
(@
ejson
foreign_ejson_model
)
j
))
(@
nil
(
prod
var
(
option
(@
ejson
foreign_ejson_model
))))))
= @
ImpEval.imp_stmt_eval
(@
imp_ejson_model
foreign_ejson_model
)
(@
imp_ejson_constant
foreign_ejson_model
)
imp_ejson_op
(@
imp_ejson_runtime_op
foreign_ejson_runtime_op
)
(@
imp_ejson_model_normalize
foreign_ejson_model
)
(@
imp_ejson_model_to_bool
foreign_ejson_model
) (@
imp_ejson_model_to_Z
foreign_ejson_model
)
(@
imp_ejson_model_to_list
foreign_ejson_model
) (@
imp_ejson_Z_to_data
foreign_ejson_model
)
(@
imp_ejson_runtime_eval
foreign_ejson_model
fejson
foreign_ejson_runtime_op
fejruntime
h
)
(@
imp_ejson_op_eval
foreign_ejson_model
)
i
(@
cons
(
prod
var
(
option
(@
imp_ejson_model
foreign_ejson_model
)))
(@
pair
var
(
option
(@
imp_ejson_model
foreign_ejson_model
))
v0
(@
None
(@
imp_ejson_model
foreign_ejson_model
)))
(@
cons
(
prod
var
(
option
(@
imp_ejson_model
foreign_ejson_model
)))
(@
pair
var
(
option
(@
imp_ejson_model
foreign_ejson_model
))
v
(@
Some
(@
imp_ejson_model
foreign_ejson_model
)
j
))
(@
nil
(
prod
var
(
option
(@
imp_ejson_model
foreign_ejson_model
)))))))
by
reflexivity
.
rewrite
H1
in
H0
.
rewrite
H0
;
reflexivity
.
Qed.
Lemma
imp_ejson_block_rewrite_correct
(
fs
:
imp_stmt
->
imp_stmt
)
h
(
j
:
ejson
) (
q
:
imp_ejson
) :
(
forall
s0
,
forall
j0
,
imp_ejson_stmt_eval
h
s0
j0
=
imp_ejson_stmt_eval
h
(
fs
s0
)
j0
) ->
imp_ejson_eval
h
q
j
=
imp_ejson_eval
h
(
imp_ejson_block_rewrite
fs
q
)
j
.
Proof.
induction
q
;
simpl
;
intros
.
destruct
l
;
simpl
;
intros
; [
reflexivity
|].
destruct
p
;
simpl
.
destruct
l
;
simpl
; [|
reflexivity
].
assert
(
imp_ejson_function_eval
h
i
j
=
imp_ejson_function_eval
h
(
imp_ejson_function_block_rewrite
fs
i
)
j
)
by
(
apply
imp_ejson_function_block_rewrite_correct
;
assumption
).
simpl
in
H0
.
unfold
imp_ejson_function_eval
in
H0
.
rewrite
H0
;
reflexivity
.
Qed.
End
CorrectnessOptimizerEngine
.
End
ImpEJsonOptimizerEngine
.