Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
AVA
FloVer
Commits
ddca2214
Commit
ddca2214
authored
Oct 13, 2016
by
Heiko Becker
Browse files
Options
Browse Files
Download
Plain Diff
Prove soundness of Range validator for unary operators and division
parents
b7ef63c0
3eb5483d
Changes
15
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
515 additions
and
3699 deletions
+515
-3699
README.md
README.md
+2
-0
coq/ErrorValidation.v
coq/ErrorValidation.v
+6
-3
coq/Expressions.v
coq/Expressions.v
+70
-11
coq/Infra/RealRationalProps.v
coq/Infra/RealRationalProps.v
+4
-3
coq/IntervalValidation.v
coq/IntervalValidation.v
+174
-55
hol/ErrorValidation.hl
hol/ErrorValidation.hl
+6
-3
hol/IntervalValidation.hl
hol/IntervalValidation.hl
+5
-2
hol/foo
hol/foo
+0
-65
hol/hol-light.el
hol/hol-light.el
+0
-3469
scripts/formal/cpp_2017_times.sh
scripts/formal/cpp_2017_times.sh
+5
-4
src/main/scala/daisy/backend/CertificatePhase.scala
src/main/scala/daisy/backend/CertificatePhase.scala
+86
-83
testcases/formal/ExampleOverview.scala
testcases/formal/ExampleOverview.scala
+1
-1
testcases/formal/Floudas.scala
testcases/formal/Floudas.scala
+92
-0
testcases/formal/Himmilbeau.scala
testcases/formal/Himmilbeau.scala
+23
-0
testcases/formal/Kepler.scala
testcases/formal/Kepler.scala
+41
-0
No files found.
README.md
View file @
ddca2214
...
@@ -58,6 +58,8 @@ You can then run Daisy on an input file as follows:
...
@@ -58,6 +58,8 @@ You can then run Daisy on an input file as follows:
$
./daisy testcases/rosa/Doppler.scala
$
./daisy testcases/rosa/Doppler.scala
```
```
## Checking Interval Arithmetic Certificates
If you want to produce certificates to check them in either of the supported backends,
If you want to produce certificates to check them in either of the supported backends,
you have to call Daisy as with
you have to call Daisy as with
```
bash
```
bash
...
...
coq/ErrorValidation.v
View file @
ddca2214
(
**
(
**
This
file
contains
the
coq
implementation
of
the
error
bound
validator
as
well
as
its
soundness
proof
.
This
file
contains
the
coq
implementation
of
the
error
bound
validator
as
well
It
is
explained
in
section
5
of
the
paper
.
as
its
soundness
proof
.
The
function
validErrorbound
is
the
Error
bound
The
validator
is
used
in
the
file
CertificateChecker
.
v
to
build
the
complete
checker
.
validator
from
the
certificate
checking
process
.
Under
the
assumption
that
a
valid
range
arithmetic
result
has
been
computed
,
it
can
validate
error
bounds
encoded
in
the
analysis
result
.
The
validator
is
used
in
the
file
CertificateChecker
.
v
to
build
the
complete
checker
.
**
)
**
)
Require
Import
Coq
.
QArith
.
QArith
Coq
.
QArith
.
Qminmax
Coq
.
QArith
.
Qabs
Coq
.
QArith
.
Qreals
Coq
.
Lists
.
List
.
Require
Import
Coq
.
QArith
.
QArith
Coq
.
QArith
.
Qminmax
Coq
.
QArith
.
Qabs
Coq
.
QArith
.
Qreals
Coq
.
Lists
.
List
.
Require
Import
Coq
.
micromega
.
Psatz
Coq
.
Reals
.
Reals
.
Require
Import
Coq
.
micromega
.
Psatz
Coq
.
Reals
.
Reals
.
...
...
coq/Expressions.v
View file @
ddca2214
...
@@ -23,13 +23,36 @@ Definition binop_eq_bool (b1:binop) (b2:binop) :=
...
@@ -23,13 +23,36 @@ Definition binop_eq_bool (b1:binop) (b2:binop) :=
Next
define
an
evaluation
function
for
binary
operators
on
reals
.
Next
define
an
evaluation
function
for
binary
operators
on
reals
.
Errors
are
added
on
the
expression
evaluation
level
later
.
Errors
are
added
on
the
expression
evaluation
level
later
.
**
)
**
)
Fixpoint
eval_binop
(
o
:
binop
)
(
v1
:
R
)
(
v2
:
R
)
:=
Definition
eval_binop
(
o
:
binop
)
(
v1
:
R
)
(
v2
:
R
)
:=
match
o
with
match
o
with
|
Plus
=>
Rplus
v1
v2
|
Plus
=>
Rplus
v1
v2
|
Sub
=>
Rminus
v1
v2
|
Sub
=>
Rminus
v1
v2
|
Mult
=>
Rmult
v1
v2
|
Mult
=>
Rmult
v1
v2
|
Div
=>
Rdiv
v1
v2
|
Div
=>
Rdiv
v1
v2
end
.
end
.
(
**
Expressions
will
use
unary
operators
.
Define
them
first
**
)
Inductive
unop
:
Type
:=
Neg
|
Inv
.
Definition
unop_eq_bool
(
o1
:
unop
)
(
o2
:
unop
)
:=
match
o1
with
|
Neg
=>
match
o2
with
|
Neg
=>
true
|
_
=>
false
end
|
Inv
=>
match
o2
with
|
Inv
=>
true
|
_
=>
false
end
end
.
(
**
Define
evaluation
for
unary
operators
on
reals
.
Errors
are
added
on
the
expression
evaluation
level
later
.
**
)
Definition
eval_unop
(
o
:
unop
)
(
v
:
R
)
:=
match
o
with
|
Neg
=>
(
-
v
)
%
R
|
Inv
=>
(
/
v
)
%
R
end
.
(
**
(
**
Define
expressions
parametric
over
some
value
type
V
.
Define
expressions
parametric
over
some
value
type
V
.
Will
ease
reasoning
about
different
instantiations
later
.
Will
ease
reasoning
about
different
instantiations
later
.
...
@@ -41,6 +64,7 @@ Inductive exp (V:Type): Type :=
...
@@ -41,6 +64,7 @@ Inductive exp (V:Type): Type :=
Var:
nat
->
exp
V
Var:
nat
->
exp
V
|
Param
:
nat
->
exp
V
|
Param
:
nat
->
exp
V
|
Const
:
V
->
exp
V
|
Const
:
V
->
exp
V
|
Unop
:
unop
->
exp
V
->
exp
V
|
Binop
:
binop
->
exp
V
->
exp
V
->
exp
V
.
|
Binop
:
binop
->
exp
V
->
exp
V
->
exp
V
.
...
@@ -61,9 +85,14 @@ Fixpoint exp_eq_bool (e1:exp Q) (e2:exp Q) :=
...
@@ -61,9 +85,14 @@ Fixpoint exp_eq_bool (e1:exp Q) (e2:exp Q) :=
|
Const
n2
=>
Qeq_bool
n1
n2
|
Const
n2
=>
Qeq_bool
n1
n2
|
_
=>
false
|
_
=>
false
end
end
|
Binop
b1
e11
e12
=>
|
Unop
o1
e11
=>
match
e2
with
|
Unop
o2
e22
=>
andb
(
unop_eq_bool
o1
o2
)
(
exp_eq_bool
e11
e22
)
|
_
=>
false
end
|
Binop
o1
e11
e12
=>
match
e2
with
match
e2
with
|
Binop
b
2
e21
e22
=>
andb
(
binop_eq_bool
b
1
b
2
)
(
andb
(
exp_eq_bool
e11
e21
)
(
exp_eq_bool
e12
e22
))
|
Binop
o
2
e21
e22
=>
andb
(
binop_eq_bool
o
1
o
2
)
(
andb
(
exp_eq_bool
e11
e21
)
(
exp_eq_bool
e12
e22
))
|
_
=>
false
|
_
=>
false
end
end
end
.
end
.
...
@@ -89,8 +118,13 @@ Inductive eval_exp (eps:R) (env:env_ty) : (exp R) -> R -> Prop :=
...
@@ -89,8 +118,13 @@ Inductive eval_exp (eps:R) (env:env_ty) : (exp R) -> R -> Prop :=
|
Const_dist
n
delta
:
|
Const_dist
n
delta
:
Rle
(
Rabs
delta
)
eps
->
Rle
(
Rabs
delta
)
eps
->
eval_exp
eps
env
(
Const
n
)
(
perturb
n
delta
)
eval_exp
eps
env
(
Const
n
)
(
perturb
n
delta
)
|
Binop_dist
op
e1
e2
v1
v2
delta
:
(
**
Unary
negation
is
special
!
We
do
not
have
a
new
error
here
since
IEE
754
gives
us
a
sign
bit
**
)
Rle
(
Rabs
delta
)
eps
->
|
Unop_neg
e1
v1
:
eval_exp
eps
env
e1
v1
->
eval_exp
eps
env
(
Unop
Neg
e1
)
(
eval_unop
Neg
v1
)
|
Unop_inv
e1
v1
delta
:
Rle
(
Rabs
delta
)
eps
->
eval_exp
eps
env
e1
v1
->
eval_exp
eps
env
(
Unop
Inv
e1
)
(
perturb
(
eval_unop
Inv
v1
)
delta
)
|
Binop_dist
op
e1
e2
v1
v2
delta
:
Rle
(
Rabs
delta
)
eps
->
eval_exp
eps
env
e1
v1
->
eval_exp
eps
env
e1
v1
->
eval_exp
eps
env
e2
v2
->
eval_exp
eps
env
e2
v2
->
eval_exp
eps
env
(
Binop
op
e1
e2
)
(
perturb
(
eval_binop
op
v1
v2
)
delta
).
eval_exp
eps
env
(
Binop
op
e1
e2
)
(
perturb
(
eval_binop
op
v1
v2
)
delta
).
...
@@ -120,11 +154,14 @@ Lemma eval_0_det (e:exp R) (env:env_ty):
...
@@ -120,11 +154,14 @@ Lemma eval_0_det (e:exp R) (env:env_ty):
v1
=
v2
.
v1
=
v2
.
Proof
.
Proof
.
induction
e
;
intros
v1
v2
eval_v1
eval_v2
;
induction
e
;
intros
v1
v2
eval_v1
eval_v2
;
inversion
eval_v1
;
inversion
eval_v2
;
[
auto
|
|
|
];
inversion
eval_v1
;
inversion
eval_v2
;
[
auto
|
|
|
|
|
|
|
];
repeat
try
rewrite
perturb_0_val
;
auto
.
repeat
try
rewrite
perturb_0_val
;
subst
;
auto
.
subst
.
-
rewrite
(
IHe
v0
v3
);
auto
.
rewrite
(
IHe1
v0
v4
);
auto
.
-
inversion
H3
.
rewrite
(
IHe2
v3
v5
);
auto
.
-
inversion
H4
.
-
rewrite
(
IHe
v0
v3
);
auto
.
-
rewrite
(
IHe1
v0
v4
);
auto
.
rewrite
(
IHe2
v3
v5
);
auto
.
Qed
.
Qed
.
(
**
(
**
...
@@ -134,7 +171,7 @@ evaluating the subexpressions and then binding the result values to different
...
@@ -134,7 +171,7 @@ evaluating the subexpressions and then binding the result values to different
variables
in
the
environment
.
variables
in
the
environment
.
This
needs
the
property
that
variables
are
not
perturbed
as
opposed
to
parameters
This
needs
the
property
that
variables
are
not
perturbed
as
opposed
to
parameters
**
)
**
)
Lemma
existential_rewriting
(
b
:
binop
)
(
e1
:
exp
R
)
(
e2
:
exp
R
)
(
eps
:
R
)
(
cenv
:
env_ty
)
(
v
:
R
)
:
Lemma
existential_rewriting
_binary
(
b
:
binop
)
(
e1
:
exp
R
)
(
e2
:
exp
R
)
(
eps
:
R
)
(
cenv
:
env_ty
)
(
v
:
R
)
:
(
eval_exp
eps
cenv
(
Binop
b
e1
e2
)
v
<->
(
eval_exp
eps
cenv
(
Binop
b
e1
e2
)
v
<->
exists
v1
v2
,
exists
v1
v2
,
eval_exp
eps
cenv
e1
v1
/
\
eval_exp
eps
cenv
e1
v1
/
\
...
@@ -157,6 +194,28 @@ Proof.
...
@@ -157,6 +194,28 @@ Proof.
constructor
;
auto
.
constructor
;
auto
.
Qed
.
Qed
.
Lemma
existential_rewriting_unary
(
e
:
exp
R
)
(
eps
:
R
)
(
cenv
:
env_ty
)
(
v
:
R
)
:
(
eval_exp
eps
cenv
(
Unop
Inv
e
)
v
<->
exists
v1
,
eval_exp
eps
cenv
e
v1
/
\
eval_exp
eps
(
updEnv
1
v1
cenv
)
(
Unop
Inv
(
Var
R
1
))
v
).
Proof
.
split
.
-
intros
eval_un
.
inversion
eval_un
;
subst
.
exists
v1
.
repeat
split
;
try
auto
.
constructor
;
try
auto
.
constructor
;
auto
.
-
intros
exists_val
.
destruct
exists_val
as
[
v1
[
eval_e1
eval_e_env
]].
inversion
eval_e_env
;
subst
.
inversion
H1
;
subst
.
unfold
updEnv
in
*
;
simpl
in
*
.
constructor
;
auto
.
Qed
.
(
**
(
**
Using
the
parametric
expressions
,
define
boolean
expressions
for
conditionals
Using
the
parametric
expressions
,
define
boolean
expressions
for
conditionals
**
)
**
)
...
...
coq/Infra/RealRationalProps.v
View file @
ddca2214
...
@@ -6,12 +6,13 @@ Require Import Coq.QArith.QArith Coq.QArith.Qminmax Coq.QArith.Qabs Coq.QArith.Q
...
@@ -6,12 +6,13 @@ Require Import Coq.QArith.QArith Coq.QArith.Qminmax Coq.QArith.Qabs Coq.QArith.Q
Require
Import
Coq
.
Reals
.
Reals
Coq
.
micromega
.
Psatz
.
Require
Import
Coq
.
Reals
.
Reals
Coq
.
micromega
.
Psatz
.
Require
Import
Daisy
.
Infra
.
RationalSimps
Daisy
.
Infra
.
Abbrevs
Daisy
.
Expressions
Daisy
.
IntervalArith
.
Require
Import
Daisy
.
Infra
.
RationalSimps
Daisy
.
Infra
.
Abbrevs
Daisy
.
Expressions
Daisy
.
IntervalArith
.
Fixpoint
toRExp
(
e
:
exp
Q
)
:=
Fixpoint
toRExp
(
f
:
exp
Q
)
:=
match
e
with
match
f
with
|
Var
_
v
=>
Var
R
v
|
Var
_
v
=>
Var
R
v
|
Param
_
v
=>
Param
R
v
|
Param
_
v
=>
Param
R
v
|
Const
n
=>
Const
(
Q2R
n
)
|
Const
n
=>
Const
(
Q2R
n
)
|
Binop
b
e1
e2
=>
Binop
b
(
toRExp
e1
)
(
toRExp
e2
)
|
Unop
o
f1
=>
Unop
o
(
toRExp
f1
)
|
Binop
o
f1
f2
=>
Binop
o
(
toRExp
f1
)
(
toRExp
f2
)
end
.
end
.
Lemma
Q2R0_is_0
:
Lemma
Q2R0_is_0
:
...
...
coq/IntervalValidation.v
View file @
ddca2214
(
**
(
**
Interval
arithmetic
checker
and
its
soundness
proof
Interval
arithmetic
checker
and
its
soundness
proof
.
Explained
in
section
4
of
the
paper
,
used
in
CertificateChecker
.
v
to
build
full
checker
,
The
function
validIntervalbounds
checks
wether
the
given
analysis
result
is
a
valid
range
arithmetic
for
each
sub
term
of
the
given
expression
e
.
The
computation
is
done
using
our
formalized
interval
arithmetic
.
The
function
is
used
in
CertificateChecker
.
v
to
build
the
full
checker
.
**
)
**
)
Require
Import
Coq
.
QArith
.
QArith
Coq
.
QArith
.
Qreals
QArith
.
Qminmax
Coq
.
Lists
.
List
Coq
.
micromega
.
Psatz
.
Require
Import
Coq
.
QArith
.
QArith
Coq
.
QArith
.
Qreals
QArith
.
Qminmax
Coq
.
Lists
.
List
Coq
.
micromega
.
Psatz
.
Require
Import
Daisy
.
Infra
.
Abbrevs
Daisy
.
Infra
.
RationalSimps
Daisy
.
Infra
.
RealRationalProps
.
Require
Import
Daisy
.
Infra
.
Abbrevs
Daisy
.
Infra
.
RationalSimps
Daisy
.
Infra
.
RealRationalProps
.
...
@@ -8,12 +11,13 @@ Require Import Daisy.Infra.ExpressionAbbrevs Daisy.IntervalArithQ Daisy.Interval
...
@@ -8,12 +11,13 @@ Require Import Daisy.Infra.ExpressionAbbrevs Daisy.IntervalArithQ Daisy.Interval
Import
Lists
.
List
.
ListNotations
.
Import
Lists
.
List
.
ListNotations
.
Fixpoint
freeVars
(
V
:
Type
)
(
e
:
exp
V
)
:
list
nat
:=
Fixpoint
freeVars
(
V
:
Type
)
(
f
:
exp
V
)
:
list
nat
:=
match
e
with
match
f
with
|
Const
n
=>
[]
|
Const
n
=>
[]
|
Var
_
v
=>
[]
|
Var
_
v
=>
[]
|
Param
_
v
=>
[
v
]
|
Param
_
v
=>
[
v
]
|
Binop
b
e1
e2
=>
(
freeVars
V
e1
)
++
(
freeVars
V
e2
)
|
Unop
o
f1
=>
freeVars
V
f1
|
Binop
o
f1
f2
=>
(
freeVars
V
f1
)
++
(
freeVars
V
f2
)
end
.
end
.
Fixpoint
validIntervalbounds
(
e
:
exp
Q
)
(
absenv
:
analysisResult
)
(
P
:
precond
)
:=
Fixpoint
validIntervalbounds
(
e
:
exp
Q
)
(
absenv
:
analysisResult
)
(
P
:
precond
)
:=
...
@@ -24,6 +28,23 @@ Fixpoint validIntervalbounds (e:exp Q) (absenv:analysisResult) (P:precond):=
...
@@ -24,6 +28,23 @@ Fixpoint validIntervalbounds (e:exp Q) (absenv:analysisResult) (P:precond):=
isSupersetIntv
(
P
v
)
intv
isSupersetIntv
(
P
v
)
intv
|
Const
n
=>
|
Const
n
=>
isSupersetIntv
(
n
,
n
)
intv
isSupersetIntv
(
n
,
n
)
intv
|
Unop
o
f1
=>
let
rec
:=
validIntervalbounds
f1
absenv
P
in
let
(
iv1
,
_
)
:=
absenv
f1
in
let
opres
:=
match
o
with
|
Neg
=>
let
new_iv
:=
negateIntv
iv1
in
isSupersetIntv
new_iv
intv
|
Inv
=>
let
nodiv0
:=
orb
(
andb
(
Qleb
(
ivhi
iv1
)
0
)
(
negb
(
Qeq_bool
(
ivhi
iv1
)
0
)))
(
andb
(
Qleb
0
(
ivlo
iv1
))
(
negb
(
Qeq_bool
(
ivlo
iv1
)
0
)))
in
let
new_iv
:=
invertIntv
iv1
in
andb
(
isSupersetIntv
new_iv
intv
)
nodiv0
end
in
andb
rec
opres
|
Binop
b
e1
e2
=>
|
Binop
b
e1
e2
=>
let
rec
:=
andb
(
validIntervalbounds
e1
absenv
P
)
(
validIntervalbounds
e2
absenv
P
)
in
let
rec
:=
andb
(
validIntervalbounds
e1
absenv
P
)
(
validIntervalbounds
e2
absenv
P
)
in
let
(
iv1
,
_
)
:=
absenv
e1
in
let
(
iv1
,
_
)
:=
absenv
e1
in
...
@@ -50,12 +71,12 @@ Fixpoint validIntervalbounds (e:exp Q) (absenv:analysisResult) (P:precond):=
...
@@ -50,12 +71,12 @@ Fixpoint validIntervalbounds (e:exp Q) (absenv:analysisResult) (P:precond):=
andb
rec
opres
andb
rec
opres
end
.
end
.
Theorem
ivbounds_approximatesPrecond_sound
e
absenv
P
:
Theorem
ivbounds_approximatesPrecond_sound
f
absenv
P
:
validIntervalbounds
e
absenv
P
=
true
->
validIntervalbounds
f
absenv
P
=
true
->
forall
v
,
In
v
(
freeVars
Q
e
)
->
forall
v
,
In
v
(
freeVars
Q
f
)
->
Is_true
(
isSupersetIntv
(
P
v
)
(
fst
(
absenv
(
Param
Q
v
)))).
Is_true
(
isSupersetIntv
(
P
v
)
(
fst
(
absenv
(
Param
Q
v
)))).
Proof
.
Proof
.
induction
e
;
unfold
validIntervalbounds
.
induction
f
;
unfold
validIntervalbounds
.
-
intros
approx_true
v
v_in_fV
;
simpl
in
*
;
contradiction
.
-
intros
approx_true
v
v_in_fV
;
simpl
in
*
;
contradiction
.
-
intros
approx_true
v
v_in_fV
;
simpl
in
*
.
-
intros
approx_true
v
v_in_fV
;
simpl
in
*
.
unfold
isSupersetIntv
.
unfold
isSupersetIntv
.
...
@@ -65,19 +86,27 @@ Proof.
...
@@ -65,19 +86,27 @@ Proof.
destruct
i
;
simpl
in
*
.
destruct
i
;
simpl
in
*
.
apply
Is_true_eq_left
in
approx_true
;
auto
.
apply
Is_true_eq_left
in
approx_true
;
auto
.
-
intros
approx_true
v0
v_in_fV
;
simpl
in
*
;
contradiction
.
-
intros
approx_true
v0
v_in_fV
;
simpl
in
*
;
contradiction
.
-
intros
approx_unary_true
v
v_in_fV
.
unfold
freeVars
in
v_in_fV
.
apply
Is_true_eq_left
in
approx_unary_true
.
destruct
(
absenv
(
Unop
u
f
));
destruct
(
absenv
f
);
simpl
in
*
.
apply
andb_prop_elim
in
approx_unary_true
.
destruct
approx_unary_true
.
apply
IHf
;
try
auto
.
apply
Is_true_eq_true
;
auto
.
-
intros
approx_bin_true
v
v_in_fV
.
-
intros
approx_bin_true
v
v_in_fV
.
unfold
freeVars
in
v_in_fV
.
unfold
freeVars
in
v_in_fV
.
apply
in_app_or
in
v_in_fV
.
apply
in_app_or
in
v_in_fV
.
apply
Is_true_eq_left
in
approx_bin_true
.
apply
Is_true_eq_left
in
approx_bin_true
.
destruct
(
absenv
(
Binop
b
e
1
e
2
));
destruct
(
absenv
e
1
);
destruct
(
absenv
e
2
);
simpl
in
*
.
destruct
(
absenv
(
Binop
b
f
1
f
2
));
destruct
(
absenv
f
1
);
destruct
(
absenv
f
2
);
simpl
in
*
.
apply
andb_prop_elim
in
approx_bin_true
.
apply
andb_prop_elim
in
approx_bin_true
.
destruct
approx_bin_true
.
destruct
approx_bin_true
.
apply
andb_prop_elim
in
H
.
apply
andb_prop_elim
in
H
.
destruct
H
.
destruct
H
.
destruct
v_in_fV
as
[
v_in_fV_
e
1
|
v_in_fV_
e
2
].
destruct
v_in_fV
as
[
v_in_fV_
f
1
|
v_in_fV_
f
2
].
+
apply
IH
e
1
;
auto
.
+
apply
IH
f
1
;
auto
.
apply
Is_true_eq_true
;
auto
.
apply
Is_true_eq_true
;
auto
.
+
apply
IH
e
2
;
auto
.
+
apply
IH
f
2
;
auto
.
apply
Is_true_eq_true
;
auto
.
apply
Is_true_eq_true
;
auto
.
Qed
.
Qed
.
...
@@ -114,38 +143,33 @@ Proof.
...
@@ -114,38 +143,33 @@ Proof.
apply
le_neq_bool_to_lt_prop
;
auto
.
apply
le_neq_bool_to_lt_prop
;
auto
.
Qed
.
Qed
.
Theorem
validIntervalbounds_sound
(
e
:
exp
Q
)
:
Theorem
validIntervalbounds_sound
(
f
:
exp
Q
)
(
absenv
:
analysisResult
)
(
P
:
precond
)
cenv
:
forall
(
absenv
:
analysisResult
)
(
P
:
precond
)
cenv
vR
,
forall
vR
,
precondValidForExec
P
cenv
->
precondValidForExec
P
cenv
->
validIntervalbounds
e
absenv
P
=
true
->
validIntervalbounds
f
absenv
P
=
true
->
eval_exp
0
%
R
cenv
(
toRExp
e
)
vR
->
eval_exp
0
%
R
cenv
(
toRExp
f
)
vR
->
(
Q2R
(
fst
(
fst
(
absenv
e
)))
<=
vR
<=
Q2R
(
snd
(
fst
(
absenv
e
))))
%
R
.
(
Q2R
(
fst
(
fst
(
absenv
f
)))
<=
vR
<=
Q2R
(
snd
(
fst
(
absenv
f
))))
%
R
.
Proof
.
Proof
.
induction
e
.
induction
f
.
-
intros
absenv
P
cenv
vR
precond_valid
valid_bounds
eval_
e
.
-
intros
vR
precond_valid
valid_bounds
eval_
f
.
pose
proof
(
ivbounds_approximatesPrecond_sound
(
Var
Q
n
)
absenv
P
valid_bounds
)
as
env_approx_p
.
pose
proof
(
ivbounds_approximatesPrecond_sound
(
Var
Q
n
)
absenv
P
valid_bounds
)
as
env_approx_p
.
unfold
validIntervalbounds
in
valid_bounds
.
unfold
validIntervalbounds
in
valid_bounds
.
destruct
(
absenv
(
Var
Q
n
));
inversion
valid_bounds
.
destruct
(
absenv
(
Var
Q
n
));
inversion
valid_bounds
.
-
intros
absenv
P
cenv
vR
precond_valid
valid_bounds
eval_
e
.
-
intros
vR
precond_valid
valid_bounds
eval_
f
.
pose
proof
(
ivbounds_approximatesPrecond_sound
(
Param
Q
n
)
absenv
P
valid_bounds
)
as
env_approx_p
.
pose
proof
(
ivbounds_approximatesPrecond_sound
(
Param
Q
n
)
absenv
P
valid_bounds
)
as
env_approx_p
.
unfold
validIntervalbounds
in
valid_bounds
.
unfold
validIntervalbounds
in
valid_bounds
.
assert
(
exists
intv
err
,
absenv
(
Param
Q
n
)
=
(
intv
,
err
))
case_eq
(
absenv
(
Param
Q
n
)).
as
absenv_n
intros
intv
err
absenv_n
.
by
(
destruct
(
absenv
(
Param
Q
n
));
repeat
eexists
;
auto
).
destruct
absenv_n
as
[
intv
[
err
absenv_n
]].
rewrite
absenv_n
in
valid_bounds
.
rewrite
absenv_n
in
valid_bounds
.
unfold
precondValidForExec
in
precond_valid
.
unfold
precondValidForExec
in
precond_valid
.
specialize
(
env_approx_p
n
).
specialize
(
env_approx_p
n
).
assert
(
exists
ivlo
ivhi
,
P
n
=
(
ivlo
,
ivhi
))
as
p_n
case_eq
(
P
n
);
intros
ivlo
ivhi
p_n
.
by
(
destruct
(
P
n
);
repeat
eexists
;
auto
).
destruct
p_n
as
[
ivlo
[
ivhi
p_n
]].
unfold
isSupersetIntv
,
freeVars
in
env_approx_p
.
unfold
isSupersetIntv
,
freeVars
in
env_approx_p
.
assert
(
In
n
(
n
::
nil
))
by
(
unfold
In
;
auto
).
assert
(
In
n
(
n
::
nil
))
as
n_in_n
by
(
unfold
In
;
auto
).
specialize
(
env_approx_p
H
).
specialize
(
env_approx_p
n_in_n
).
rewrite
p_n
,
absenv_n
in
env_approx_p
.
rewrite
p_n
,
absenv_n
in
env_approx_p
.
specialize
(
precond_valid
n
);
rewrite
p_n
in
precond_valid
.
specialize
(
precond_valid
n
);
rewrite
p_n
in
precond_valid
.
inversion
eval_e
;
subst
.
inversion
eval_f
;
subst
.
rewrite
absenv_n
;
simpl
.
rewrite
perturb_0_val
;
auto
.
rewrite
perturb_0_val
;
auto
.
destruct
intv
as
[
abslo
abshi
];
simpl
in
*
.
destruct
intv
as
[
abslo
abshi
];
simpl
in
*
.
apply
andb_prop_elim
in
env_approx_p
.
apply
andb_prop_elim
in
env_approx_p
.
...
@@ -162,15 +186,14 @@ Proof.
...
@@ -162,15 +186,14 @@ Proof.
+
eapply
Rle_trans
.
+
eapply
Rle_trans
.
apply
env_le_ivhi
.
apply
env_le_ivhi
.
apply
ivhi_le_abshi
.
apply
ivhi_le_abshi
.
-
intros
absenv
P
cenv
vR
valid_precond
valid_bounds
eval_
e
.
-
intros
vR
valid_precond
valid_bounds
eval_
f
.
pose
proof
(
ivbounds_approximatesPrecond_sound
(
Const
v
)
absenv
P
valid_bounds
)
as
env_approx_p
.
pose
proof
(
ivbounds_approximatesPrecond_sound
(
Const
v
)
absenv
P
valid_bounds
)
as
env_approx_p
.
unfold
validIntervalbounds
in
valid_bounds
.
unfold
validIntervalbounds
in
valid_bounds
.
destruct
(
absenv
(
Const
v
))
as
[
intv
err
].
destruct
(
absenv
(
Const
v
))
as
[
intv
err
];
simpl
.
simpl
.
apply
Is_true_eq_left
in
valid_bounds
.
apply
Is_true_eq_left
in
valid_bounds
.
apply
andb_prop_elim
in
valid_bounds
.
apply
andb_prop_elim
in
valid_bounds
.
destruct
valid_bounds
as
[
valid_lo
valid_hi
].
destruct
valid_bounds
as
[
valid_lo
valid_hi
].
inversion
eval_
e
;
subst
.
inversion
eval_
f
;
subst
.
rewrite
perturb_0_val
;
auto
.
rewrite
perturb_0_val
;
auto
.
unfold
contained
;
simpl
.
unfold
contained
;
simpl
.
split
.
split
.
...
@@ -182,32 +205,128 @@ Proof.
...
@@ -182,32 +205,128 @@ Proof.
unfold
Qleb
in
*
.
unfold
Qleb
in
*
.
apply
Qle_bool_iff
in
valid_hi
.
apply
Qle_bool_iff
in
valid_hi
.
apply
Qle_Rle
in
valid_hi
;
auto
.
apply
Qle_Rle
in
valid_hi
;
auto
.
-
intros
absenv
P
cenv
vR
valid_precond
valid_bounds
eval_e
;
-
intros
vR
valid_precond
valid_bounds
eval_f
;
inversion
eval_e
;
subst
.
pose
proof
(
ivbounds_approximatesPrecond_sound
(
Unop
u
f
)
absenv
P
valid_bounds
)
as
env_approx_p
.
pose
proof
(
ivbounds_approximatesPrecond_sound
(
Binop
b
e1
e2
)
absenv
P
valid_bounds
)
as
env_approx_p
.
case_eq
(
absenv
(
Unop
u
f
));
intros
intv
err
absenv_unop
.
rewrite
perturb_0_val
in
eval_e
;
auto
.
destruct
intv
as
[
unop_lo
unop_hi
];
simpl
.
unfold
validIntervalbounds
in
valid_bounds
.
rewrite
absenv_unop
in
valid_bounds
.
case_eq
(
absenv
f
);
intros
intv_f
err_f
absenv_f
.
rewrite
absenv_f
in
valid_bounds
.
apply
Is_true_eq_left
in
valid_bounds
.
apply
andb_prop_elim
in
valid_bounds
.
destruct
valid_bounds
as
[
valid_rec
valid_unop
].
apply
Is_true_eq_true
in
valid_rec
.
inversion
eval_f
;
subst
.
+
specialize
(
IHf
v1
valid_precond
valid_rec
H2
).
rewrite
absenv_f
in
IHf
;
simpl
in
IHf
.
(
*
TODO
:
Make
lemma
*
)
unfold
isSupersetIntv
in
valid_unop
.
apply
andb_prop_elim
in
valid_unop
.
destruct
valid_unop
as
[
valid_lo
valid_hi
].
apply
Is_true_eq_true
in
valid_lo
;
apply
Is_true_eq_true
in
valid_hi
.
apply
Qle_bool_iff
in
valid_lo
;
apply
Qle_bool_iff
in
valid_hi
.
pose
proof
(
interval_negation_valid
(
Q2R
(
fst
intv_f
),(
Q2R
(
snd
intv_f
)))
v1
)
as
negation_valid
.
unfold
contained
,
negateInterval
in
negation_valid
;
simpl
in
*
.
apply
Qle_Rle
in
valid_lo
;
apply
Qle_Rle
in
valid_hi
.
destruct
IHf
.
unfold
eval_unop
;
split
.
*
eapply
Rle_trans
.
apply
valid_lo
.
rewrite
Q2R_opp
;
lra
.
*
eapply
Rle_trans
.
Focus
2.
apply
valid_hi
.
rewrite
Q2R_opp
;
lra
.
+
specialize
(
IHf
v1
valid_precond
valid_rec
H3
).
rewrite
absenv_f
in
IHf
;
simpl
in
IHf
.
apply
andb_prop_elim
in
valid_unop
.
destruct
valid_unop
as
[
valid_unop
nodiv0
].
(
*
TODO
:
Make
lemma
*
)
unfold
isSupersetIntv
in
valid_unop
.
apply
andb_prop_elim
in
valid_unop
.
destruct
valid_unop
as
[
valid_lo
valid_hi
].
apply
Is_true_eq_true
in
valid_lo
;
apply
Is_true_eq_true
in
valid_hi
.
apply
Qle_bool_iff
in
valid_lo
;
apply
Qle_bool_iff
in
valid_hi
.
assert
((
Q2R
(
ivhi
intv_f
)
<
0
)
%
R
\
/
(
0
<
Q2R
(
ivlo
intv_f
))
%
R
)
as
nodiv0_prop
.
*
apply
Is_true_eq_true
in
nodiv0
.
apply
le_neq_bool_to_lt_prop
in
nodiv0
.
destruct
nodiv0
.
{
left
;
rewrite
<-
Q2R0_is_0
;
apply
Qlt_Rlt
;
auto
.
}
{
right
;
rewrite
<-
Q2R0_is_0
;
apply
Qlt_Rlt
;
auto
.
}
*
pose
proof
(
interval_inversion_valid
(
Q2R
(
fst
intv_f
),(
Q2R
(
snd
intv_f
)))
v1
)
as
inv_valid
.
unfold
contained
,
invertInterval
in
inv_valid
;
simpl
in
*
.
apply
Qle_Rle
in
valid_lo
;
apply
Qle_Rle
in
valid_hi
.
destruct
IHf
.
rewrite
perturb_0_val
;
auto
.
unfold
eval_unop
,
perturb
;
split
.
{
eapply
Rle_trans
.
apply
valid_lo
.
destruct
nodiv0_prop
as
[
nodiv0_neg
|
nodiv0_pos
].
(
*
TODO
:
Extract
lemma
maybe
*
)
-
assert
(
0
<
-
(
Q2R
(
snd
intv_f
)))
%
R
as
negation_pos
by
lra
.
assert
(
-
(
Q2R
(
snd
intv_f
))
<=
-
v1
)
%
R
as
negation_flipped_hi
by
lra
.
apply
Rinv_le_contravar
in
negation_flipped_hi
;
try
auto
.
rewrite
<-
Ropp_inv_permute
in
negation_flipped_hi
;
try
lra
.
rewrite
<-
Ropp_inv_permute
in
negation_flipped_hi
;
try
lra
.
apply
Ropp_le_contravar
in
negation_flipped_hi
.
repeat
rewrite
Ropp_involutive
in
negation_flipped_hi
;
rewrite
Q2R_inv
;
auto
.
hnf
;
intros
is_0
.
rewrite
<-
Q2R0_is_0
in
nodiv0_neg
.
apply
Rlt_Qlt
in
nodiv0_neg
;
lra
.
-
rewrite
Q2R_inv
.
apply
Rinv_le_contravar
;
try
lra
.
hnf
;
intros
is_0
.
assert
(
Q2R
(
fst
intv_f
)
<=
Q2R
(
snd
intv_f
))
%
R
by
lra
.
rewrite
<-
Q2R0_is_0
in
nodiv0_pos
.
apply
Rlt_Qlt
in
nodiv0_pos
;
apply
Rle_Qle
in
H2
;
lra
.
}
{
eapply
Rle_trans
.
Focus
2.
apply
valid_hi
.
destruct
nodiv0_prop
as
[
nodiv0_neg
|
nodiv0_pos
].
-
assert
(
Q2R
(
fst
intv_f
)
<
0
)
%
R
as
fst_lt_0
by
lra
.
assert
(
0
<
-
(
Q2R
(
fst
intv_f
)))
%
R
as
negation_pos
by
lra
.
assert
(
-
v1
<=
-
(
Q2R
(
fst
intv_f
)))
%
R
as
negation_flipped_lo
by
lra
.
apply
Rinv_le_contravar
in
negation_flipped_lo
;
try
auto
.
rewrite
<-
Ropp_inv_permute
in
negation_flipped_lo
;
try
lra
.
rewrite
<-
Ropp_inv_permute
in
negation_flipped_lo
;
try
lra
.
apply
Ropp_le_contravar
in
negation_flipped_lo
.
repeat
rewrite
Ropp_involutive
in
negation_flipped_lo
;
rewrite
Q2R_inv
;
auto
.
hnf
;
intros
is_0
.
rewrite
<-
Q2R0_is_0
in
negation_pos
.
rewrite
<-
Q2R_opp
in
negation_pos
.
apply
Rlt_Qlt
in
negation_pos
;
lra
.
assert
(
0
<
-
(
Q2R
(
snd
intv_f
)))
%
R
by
lra
.
lra
.
-
rewrite
Q2R_inv
.
apply
Rinv_le_contravar
;
try
lra
.
hnf
;
intros
is_0
.
assert
(
Q2R
(
fst
intv_f
)
<=
Q2R
(
snd
intv_f
))
%
R
by
lra
.
rewrite
<-
Q2R0_is_0
in
nodiv0_pos
.
apply
Rlt_Qlt
in
nodiv0_pos
;
apply
Rle_Qle
in
H2
;
lra
.
}
-
intros
vR
valid_precond
valid_bounds
eval_f
;
inversion
eval_f
;
subst
.
pose
proof
(
ivbounds_approximatesPrecond_sound
(
Binop
b
f1
f2
)
absenv
P
valid_bounds
)
as
env_approx_p
.
rewrite
perturb_0_val
in
eval_f
;
auto
.
rewrite
perturb_0_val
;
auto
.
rewrite
perturb_0_val
;
auto
.
simpl
in
valid_bounds
.
simpl
in
valid_bounds
.
env_assert
absenv
(
Binop
b
e1
e2
)
absenv_bin
.
case_eq
(
absenv
(
Binop
b
f1
f2
));
intros
iv
err
absenv_bin
.
env_assert
absenv
e1
absenv_e1
.
case_eq
(
absenv
f1
);
intros
iv1
err1
absenv_f1
.
env_assert
absenv
e2
absenv_e2
.
case_eq
(
absenv
f2
);
intros
iv2
err2
absenv_f2
.
destruct
absenv_bin
as
[
iv
[
err
absenv_bin
]];
rewrite
absenv_bin
in
valid_bounds
;
rewrite
absenv_bin
.
rewrite
absenv_bin
,
absenv_f1
,
absenv_f2
in
valid_bounds
.
destruct
absenv_e1
as
[
iv1
[
err1
absenv_e1
]];
rewrite
absenv_e1
in
valid_bounds
.
destruct
absenv_e2
as
[
iv2
[
err2
absenv_e2
]];
rewrite
absenv_e2
in
valid_bounds
.
apply
Is_true_eq_left
in
valid_bounds
.
apply
Is_true_eq_left
in
valid_bounds
.
apply
andb_prop_elim
in
valid_bounds
.
apply
andb_prop_elim
in
valid_bounds
.
destruct
valid_bounds
as
[
valid_rec
valid_bin
].
destruct
valid_bounds
as
[
valid_rec
valid_bin
].
apply
andb_prop_elim
in
valid_rec
.
apply
andb_prop_elim
in
valid_rec
.
destruct
valid_rec
as
[
valid_e1
valid_e2
].
destruct
valid_rec
as
[
valid_e1
valid_e2
].
apply
Is_true_eq_true
in
valid_e1
;
apply
Is_true_eq_true
in
valid_e2
.
apply
Is_true_eq_true
in
valid_e1
;
apply
Is_true_eq_true
in
valid_e2
.
specialize
(
IH
e1
absenv
P
cenv
v1
valid_precond
valid_e1
H4
);