Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
F
FloVer
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Model registry
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
AVA
FloVer
Commits
8b287a0c
Commit
8b287a0c
authored
3 years ago
by
Heiko Becker
Browse files
Options
Downloads
Patches
Plain Diff
Add a flipped version of the IEEE connection
parent
0764033c
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
hol4/IEEE_reverseScript.sml
+1381
-0
1381 additions, 0 deletions
hol4/IEEE_reverseScript.sml
with
1381 additions
and
0 deletions
hol4/IEEE_reverseScript.sml
0 → 100644
+
1381
−
0
View file @
8b287a0c
(*
*
Connect FloVer's idealized machine semantics to 64-bit
IEEE-754 floating-point semantics
**)
open
machine_ieeeTheory
binary_ieeeTheory
lift_ieeeTheory
realTheory
RealArith
realLib
;
open
MachineTypeTheory
ExpressionsTheory
RealSimpsTheory
FloverTactics
CertificateCheckerTheory
FPRangeValidatorTheory
IntervalValidationTheory
ExpressionAbbrevsTheory
ExpressionSemanticsTheory
FloverMapTheory
RealRangeArithTheory
TypeValidatorTheory
ErrorValidationTheory
IntervalArithTheory
AbbrevsTheory
CommandsTheory
ssaPrgsTheory
EnvironmentsTheory
FloverMapTheory
IEEE_connectionTheory
;
open
preambleFloVer
;
val
_
=
new_theory
"IEEE_reverse"
;
Overload
abs
[
local
]
=
“
real$abs
”
Definition
toFlExp_def
:
toFlExp
((
Var
v
):
real
expr
)
=
Var
v
∧
toFlExp
(
Const
m
c
)
=
Const
m
(
real_to_fp64
dmode
c
)
∧
toFlExp
(
Unop
u
e1
)
=
Unop
u
(
toFlExp
e1
)
∧
toFlExp
(
Binop
b
e1
e2
)
=
Binop
b
(
toFlExp
e1
)
(
toFlExp
e2
)
∧
toFlExp
(
Fma
e1
e2
e3
)
=
Fma
(
toFlExp
e1
)
(
toFlExp
e2
)
(
toFlExp
e3
)
∧
toFlExp
(
Downcast
m
e1
)
=
Downcast
m
(
toFlExp
e1
)
End
Definition
toFlCmd_def
:
toFlCmd
(
Let
m
x
e
g
)
=
Let
m
x
(
toFlExp
e
)
(
toFlCmd
g
)
∧
toFlCmd
(
Ret
e
)
=
Ret
(
toFlExp
e
)
End
Definition
toFlEnv_def
:
toFlEnv
(
E
:
num
->
real
option
)
:
num
->
word64
option
=
λ
x
.
case
E
x
of
|
NONE
=>
NONE
|
SOME
v
=>
SOME
(
real_to_fp64
dmode
v
)
End
Theorem
float_to_real_round_robin
:
!
(
f
:(
'a
,
'b
)
float
)
.
float_is_finite
f
⇒
float_to_real
((
real_to_float
dmode
(
float_to_real
f
)):(
'a
,
'b
)
float
)
=
(
float_to_real
f
)
Proof
rpt
strip_tac
\\
fs
[
dmode_def
,
real_to_float_def
,
float_round_def
]
\\
reverse
$
Cases_on
‘
float_is_zero
f
’
>-
gs
[
round_finite_normal_float_id
]
\\
‘∃
s
e
m
.
f
=
<|Sign
:=
s
;
Exponent
:=
e
;
Significand
:=
m
|>
’
by
(
Cases_on
‘
f
’
\\
gs
[
float_component_equality
])
\\
‘
float_to_real
f
=
0
’
by
(
rveq
\\
gs
[
float_tests
,
float_to_real_def
])
\\
simp
[]
(*
Just for simplicity, could also prove that condition is true... *)
\\
TOP_CASE_TAC
\\
gs
[]
QED
(*
* Some eval test
EVAL “float_to_real ((real_to_float roundTiesToEven (float_to_real <|Sign := 1w; Exponent := 0w:word11; Significand := 0w:52 word |>)):(52,11) float”
|> CONV_RULE (RHS_CONV $ RAND_CONV $ binary_ieeeLib.float_round_CONV)
**)
Theorem
eval_expr_gives_IEEE_reverse
:
!
(
e
:
real
expr
)
E1
E2
Gamma
vR
A
fVars
dVars
.
validTypes
e
Gamma
/\
approxEnv
E1
(
toRExpMap
Gamma
)
A
fVars
dVars
E2
/\
validRanges
e
A
E1
(
toRTMap
(
toRExpMap
Gamma
))
/\
validErrorbound
e
Gamma
A
dVars
/\
FPRangeValidator
e
A
Gamma
dVars
/\
eval_expr
E2
(
toRExpMap
Gamma
)
e
vR
M64
/\
domain
(
usedVars
e
)
DIFF
domain
dVars
⊆
domain
fVars
∧
is64BitEval
e
/\
is64BitEnv
Gamma
/\
noDowncast
e
/\
(
∀
x
v
.
E2
x
=
SOME
v
⇒
float_to_real
((
real_to_float
dmode
v
):(
52
,
11
)
float
)
=
v
)
∧
(
∀
v
.
v
∈
domain
dVars
⇒
∃
vF
m
.
(
E2
v
=
SOME
vF
∧
FloverMapTree_find
(
Var
v
)
Gamma
=
SOME
m
∧
validFloatValue
vF
m
))
==>
?
v
.
eval_expr_float
(
toFlExp
e
)
(
toFlEnv
E2
)
=
SOME
v
/\
eval_expr
E2
(
toRExpMap
Gamma
)
e
(
fp64_to_real
v
)
M64
Proof
Induct_on
`e`
\\
rw
[
toFlExp_def
]
\\
inversion
`eval_expr
_
_
_
_
_
`
eval_expr_cases
\\
once_rewrite_tac
[
eval_expr_float_def
]
\\
fs
[
noDowncast_def
]
>-
(
simp
[
toFlEnv_def
,
eval_expr_cases
,
fp64_to_real_def
,
real_to_fp64_def
,
fp64_to_float_float_to_fp64
]
\\
gs
[
usedVars_def
]
\\
first_x_assum
$
qspecl_then
[
‘
n
’
,
‘
vR
’
]
assume_tac
\\
gs
[])
>-
(
simp
[
eval_expr_cases
,
fp64_to_real_def
,
real_to_fp64_def
,
fp64_to_float_float_to_fp64
,
real_to_float_def
,
dmode_def
,
float_round_def
,
float_is_zero_to_real
]
\\
gs
[
perturb_def
]
\\
‘
eval_expr
E2
(
toRExpMap
Gamma
)
(
Const
M64
v
)
v
M64
’
by
(
gs
[
eval_expr_cases
]
\\
qexists_tac
‘
0
’
\\
gs
[
perturb_def
,
mTypeToR_pos
])
\\
‘
validFloatValue
v
M64
’
by
(
drule
FPRangeValidator_sound
\\
disch_then
$
qspecl_then
[
‘
Const
M64
v
’
,
‘
v
’
,
‘
M64
’
]
mp_tac
\\
gs
[
eval_expr_cases
]
\\
impl_tac
\\
gs
[]
\\
qexists_tac
‘
0
’
\\
gs
[
perturb_def
,
mTypeToR_pos
])
\\
first_x_assum
$
assume_tac
o
SIMP_RULE
std_ss
[
validFloatValue_def
]
\\
gs
[]
>-
(
‘
normalizes
(:
52
# 11
)
v
’
by
gs
[
normalValue_implies_normalization
]
\\
imp_res_tac
relative_error
\\
qexists_tac
‘
e
’
\\
simp
[
float_is_zero_to_real
]
\\
‘
~
(
v
=
0
∨
1
+
e
=
0
)
’
by
(
CCONTR_TAC
\\
gs
[]
\\
rveq
>-
(
gs
[
normalizes_def
]
\\
‘
0
<
inv
(
2
pow
1022
)
’
by
gs
[]
\\
‘
0
<
0
’
suffices_by
gs
[]
\\
irule
REAL_LTE_TRANS
\\
first_assum
$
irule_at
Any
\\
gs
[])
\\
‘
e
=
-
1
’
by
(
pop_assum
$
mp_tac
\\
REAL_ARITH_TAC
)
\\
‘
1
/
2
pow
53
<
1
’
by
(
irule
REAL_LTE_TRANS
\\
qexists_tac
‘
1
/
1
’
\\
reverse
conj_tac
>-
gs
[]
\\
rewrite_tac
[
real_div
]
\\
irule
REAL_LT_LMUL_IMP
\\
reverse
conj_tac
>-
gs
[]
\\
irule
REAL_LT_INV
\\
gs
[]
\\
irule
REAL_LT_TRANS
\\
qexists_tac
‘
&
53
’
\\
gs
[
POW_2_LT
])
\\
‘
1
<
1
:
real
’
suffices_by
gs
[]
\\
irule
REAL_LET_TRANS
\\
first_x_assum
$
irule_at
Any
\\
gs
[])
\\
gs
[
perturb_def
]
\\
imp_res_tac
normal_not_denormal
\\
gs
[]
\\
fs
[
REAL_INV_1OVER
,
mTypeToR_def
,
isCompat_def
])
>-
(
gs
[
perturb_def
,
mTypeToR_def
,
float_is_zero_to_real
]
\\
qspec_then
‘
v
’
mp_tac
(
Q
.
INST_TYPE
[
‘
:
't
’
|->
‘
:
52
’
,
‘
:
'w
’
|->
‘
:
11
’
]
absolute_error_denormal
)
\\
impl_tac
>-
(
‘
abs
v
<
2
/
2
pow
(
INT_MAX
(:
11
)
-
1
)
’
by
(
fs
[
denormalTranslatedValue_implies_finiteness
,
float_is_finite
,
denormal_def
,
minValue_pos_def
]
\\
rewrite_tac
[
INT_MAX_def
,
INT_MIN_def
,
dimindex_11
,
EVAL
“
2
**
(
11
-
1
)
-
1
-
1
”
]
\\
irule
REAL_LT_TRANS
\\
first_assum
$
irule_at
Any
\\
fs
[
minExponentPos_def
])
\\
rpt
conj_tac
>-
gs
[]
>~
[
‘
1
<
INT_MAX
(:
11
)
’
]
>-
gs
[]
\\
irule
REAL_LET_TRANS
\\
qexists_tac
‘
2
/
2
pow
(
INT_MAX
(:
11
)
-
1
)
’
\\
reverse
conj_tac
>-
(
pop_assum
$
mp_tac
\\
REAL_ARITH_TAC
)
\\
gs
[
threshold_def
]
\\
rewrite_tac
[
REAL_INV_1OVER
]
\\
EVAL_TAC
)
\\
rpt
strip_tac
\\
qexists_tac
‘
e
’
\\
gs
[]
\\
TOP_CASE_TAC
\\
gs
[
minExponentPos_def
])
>-
(
gvs
[
denormal_def
]
\\
qexists_tac
‘
0
’
\\
gs
[
mTypeToR_pos
])
)
>-
(
gs
[
eval_expr_float_def
,
eval_expr_cases
]
\\
qpat_x_assum
‘
validTypes
_
_
’
$
assume_tac
o
ONCE_REWRITE_RULE
[
validTypes_def
]
\\
gs
[]
\\
first_x_assum
$
drule_then
drule
\\
qpat_x_assum
‘
validRanges
_
_
_
_
’
$
assume_tac
o
ONCE_REWRITE_RULE
[
validRanges_def
]
\\
gs
[]
\\
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
$
assume_tac
o
ONCE_REWRITE_RULE
[
validErrorbound_def
]
\\
gs
[]
\\
‘
FPRangeValidator
e
A
Gamma
dVars
’
by
(
qpat_x_assum
‘
FPRangeValidator
_
_
_
_
’
$
assume_tac
o
ONCE_REWRITE_RULE
[
FPRangeValidator_def
]
\\
gs
[])
\\
gs
[]
\\
‘
m'
=
M64
’
by
(
Cases_on
‘
m'
’
\\
gs
[
isCompat_def
])
\\
gvs
[]
\\
disch_then
drule
\\
impl_tac
>-
(
gs
[
Once
usedVars_def
,
Once
is64BitEval_def
]
\\
metis_tac
[])
\\
strip_tac
\\
gs
[
eval_expr_float_def
]
\\
simp
[
Once
eval_expr_cases
]
\\
first_x_assum
$
irule_at
Any
\\
gs
[
isCompat_def
]
\\
gs
[
fp64_negate_def
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
,
evalUnop_def
,
float_to_real_negate
])
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
$
mp_tac
o
ONCE_REWRITE_RULE
[
validErrorbound_def
]
\\
fs
[
option_case_eq
]
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
>-
(
gs
[
eval_expr_float_def
,
eval_expr_cases
]
\\
qpat_x_assum
‘
validTypes
_
_
’
$
assume_tac
o
ONCE_REWRITE_RULE
[
validTypes_def
]
\\
gs
[]
\\
first_x_assum
$
drule_then
drule
\\
qpat_x_assum
‘
validRanges
_
_
_
_
’
$
assume_tac
o
ONCE_REWRITE_RULE
[
validRanges_def
]
\\
gs
[]
\\
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
$
assume_tac
o
ONCE_REWRITE_RULE
[
validErrorbound_def
]
\\
gs
[]
\\
Cases_on
‘
FloverMapTree_find
e
A
’
\\
gs
[]
\\
PairCases_on
‘
x
’
\\
gs
[]
\\
‘
FPRangeValidator
e
A
Gamma
dVars
’
by
(
qpat_x_assum
‘
FPRangeValidator
_
_
_
_
’
$
assume_tac
o
ONCE_REWRITE_RULE
[
FPRangeValidator_def
]
\\
gs
[])
\\
gs
[]
\\
‘
m1
=
M64
’
by
(
Cases_on
‘
m1
’
\\
gs
[
isCompat_def
])
\\
gvs
[]
\\
disch_then
drule
\\
impl_tac
>-
(
gs
[
Once
usedVars_def
,
Once
is64BitEval_def
]
\\
metis_tac
[])
\\
strip_tac
\\
gs
[
eval_expr_float_def
]
\\
first_assum
$
irule_at
Any
\\
gs
[
isCompat_def
]
\\
gs
[
fp64_to_real_def
,
fp64_sqrt_def
,
fp64_to_float_float_to_fp64
,
dmode_def
,
evalUnop_def
]
\\
‘
validFloatValue
(
float_to_real
(
fp64_to_float
v
))
M64
’
by
(
drule
FPRangeValidator_sound
\\
rpt
$
disch_then
drule
\\
impl_tac
>-
gs
[
Once
usedVars_def
]
\\
gs
[])
\\
qpat_assum
‘
validRanges
e
_
_
_
’
$
mp_then
Any
strip_assume_tac
validRanges_single
\\
rename
[
‘
eval_expr
E1
_
(
toREval
e
)
vR_e
REAL
’
,
‘
FloverMapTree_find
e
A
=
SOME
(
iv_e
,
err_e
)
’
]
\\
‘
contained
(
float_to_real
(
fp64_to_float
v
))
(
widenInterval
(
FST
iv_e
,
SND
iv_e
)
err_e
)
’
by
(
irule
distance_gives_iv
\\
qexists_tac
`vR_e`
\\
gvs
[
contained_def
]
\\
drule
validErrorbound_sound
\\
disch_then
drule
\\
gs
[
eval_Real_def
,
eval_Fin_def
]
\\
disch_then
$
qspec_then
‘
vR_e
’
mp_tac
\\
impl_tac
>-
gs
[
Once
usedVars_def
]
\\
strip_tac
\\
first_x_assum
irule
\\
qexists_tac
`M64`
\\
gs
[])
\\
‘
0
<
FST
(
widenInterval
(
FST
iv_e
,
SND
iv_e
)
err_e
)
’
by
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
mp_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
\\
‘
0
<
float_to_real
(
fp64_to_float
v
)
’
by
(
gs
[
contained_def
,
widenInterval_def
]
\\
irule
REAL_LTE_TRANS
\\
asm_exists_tac
\\
gs
[])
\\
‘
(
fp64_to_float
v
)
.
Sign
=
0
w
’
by
imp_res_tac
zero_lt_sign_zero
\\
‘
validFloatValue
(
evalUnop
Sqrt
(
float_to_real
(
fp64_to_float
v
)))
M64
’
by
(
drule
FPRangeValidator_sound
\\
disch_then
(
qspecl_then
[
`Unop
Sqrt
e`
,
`evalUnop
Sqrt
(
float_to_real
(
fp64_to_float
v
))
`
,
`M64`
]
irule
)
\\
gvs
[]
\\
qexists_tac
‘
e
’
\\
fs
[]
\\
rpt
conj_tac
>-
(
simp
[
Once
validTypes_def
,
isCompat_def
]
\\
first_x_assum
MATCH_ACCEPT_TAC
)
>-
simp
[
Once
validErrorbound_def
]
>-
(
simp
[
Once
validRanges_def
]
\\
asm_exists_tac
\\
fs
[]
\\
fs
[]
\\
rveq
\\
fs
[])
\\
irule
Unop_sqrt'
\\
qexistsl_tac
[
‘
0
’
,
`M64`
,
‘
M64
’
,
`float_to_real
(
fp64_to_float
v
)
`
]
\\
fs
[
perturb_def
,
evalUnop_def
,
mTypeToR_pos
,
isCompat_def
])
\\
qpat_x_assum
`validFloatValue
(
evalUnop
_
_)
M64`
$
assume_tac
o
SIMP_RULE
std_ss
[
validFloatValue_def
]
\\
gs
[]
(*
normal sqrt *)
>-
(
Q
.
ISPEC_THEN
`
(
fp64_to_float
v
):(
52
,
11
)
float`
impl_subgoal_tac
float_sqrt_relative
>-
(
rpt
conj_tac
\\
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
GSYM
float_is_zero_to_real
,
float_is_finite
,
evalUnop_def
,
sqrtable_def
,
normalizes_def
])
\\
gvs
[
dmode_def
]
\\
qexists_tac
‘
e'
’
\\
fs
[
perturb_def
,
evalUnop_def
]
\\
imp_res_tac
normal_not_denormal
\\
simp
[]
\\
simp
[
REAL_INV_1OVER
,
mTypeToR_def
,
isCompat_def
])
(*
denormal sqrt *)
>-
(
Q
.
ISPEC_THEN
`
(
fp64_to_float
v
):(
52
,
11
)
float`
impl_subgoal_tac
float_sqrt_relative_denorm
>-
(
rpt
conj_tac
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalUnop_def
]
>-
fs
[
sqrtable_def
]
>-
(
fs
[
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalUnop_def
,
denormal_def
,
minValue_pos_def
]
\\
irule
REAL_LT_TRANS
\\
qexists_tac
‘
abs
(
sqrt
(
float_to_real
(
fp64_to_float
v
)))
*
&
(
2
**
minExponentPos
M64
)
’
\\
gs
[]
\\
EVAL_TAC
)
>-
(
irule
REAL_LT_TRANS
\\
qexists_tac
‘
maxValue
M64
’
\\
fs
[
threshold_64_bit_lt_maxValue
,
denormal_def
]
\\
irule
REAL_LTE_TRANS
\\
qexists_tac
‘
minValue_pos
M64
’
\\
fs
[
minValue_pos_def
,
maxValue_def
,
GSYM
REAL_OF_NUM_POW
,
evalUnop_def
]
\\
EVAL_TAC
)
\\
fs
[
INT_MAX_def
,
INT_MIN_def
,
dimindex_11
])
\\
gvs
[
dmode_def
]
\\
qexists_tac
‘
e'
’
\\
fs
[
perturb_def
,
evalUnop_def
]
\\
simp
[
REAL_INV_1OVER
,
mTypeToR_def
,
minExponentPos_def
])
(*
sqrt 0 *)
\\
‘
0
<
sqrt
(
float_to_real
(
fp64_to_float
v
))
’
by
(
irule
SQRT_POS_LT
\\
gs
[])
\\
gs
[
evalUnop_def
])
>~
[
‘
Binop
b
e1
e2
’
]
>-
(
imp_res_tac
validRanges_single
\\
rw_thm_asm
`validTypes
_
_
`
validTypes_def
\\
rw_thm_asm
`validRanges
_
_
_
_
`
validRanges_def
\\
fs
[
eval_expr_float_def
,
optionLift_def
]
\\
imp_res_tac
validTypes_exec
\\
rveq
\\
`m1
=
M64
/\
m2
=
M64`
by
(
fs
[
is64BitEnv_def
]
\\
conj_tac
\\
first_x_assum
irule
\\
find_exists_tac
\\
fs
[])
\\
rveq
\\
rw_thm_asm
`is64BitEval
_
`
is64BitEval_def
\\
fs
[]
\\
ntac
2
(
first_x_assum
(
qspecl_then
[
`E1`
,
`E2`
,
`Gamma`
]
assume_tac
))
\\
first_x_assum
(
qspecl_then
[
`v1`
,
`A`
,
`fVars`
,
`dVars`
]
destruct
)
>-
(
rpt
conj_tac
\\
fs
[]
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
mp_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
>-
(
rw_thm_asm
`FPRangeValidator
_
_
_
_
`
FPRangeValidator_def
\\
fs
[]
\\
rveq
\\
rw_asm_star
`FloverMapTree_find
(
Binop
_
_
_)
A
=
_
`
\\
rw_asm_star
`FloverMapTree_find
(
Binop
_
_
_)
Gamma
=
_
`
)
\\
rw_thm_asm
`domain
(
usedVars
_)
DIFF
_
SUBSET
_
`
usedVars_def
\\
fs
[
domain_union
,
DIFF_DEF
,
SUBSET_DEF
,
Once
usedVars_def
]
\\
rpt
strip_tac
\\
first_x_assum
irule
\\
simp
[
Once
usedVars_def
])
\\
first_x_assum
(
qspecl_then
[
`v2`
,
`A`
,
`fVars`
,
`dVars`
]
destruct
)
>-
(
rpt
conj_tac
\\
fs
[]
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
mp_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
>-
(
rw_thm_asm
`FPRangeValidator
_
_
_
_
`
FPRangeValidator_def
\\
fs
[]
\\
rveq
\\
rw_asm_star
`FloverMapTree_find
(
Binop
_
_
_)
A
=
_
`
\\
rw_asm_star
`FloverMapTree_find
(
Binop
_
_
_)
Gamma
=
_
`
)
\\
rw_thm_asm
`domain
(
usedVars
_)
DIFF
_
SUBSET
_
`
usedVars_def
\\
fs
[
domain_union
,
DIFF_DEF
,
SUBSET_DEF
])
\\
fs
[]
\\
rename1
`eval_expr_float
(
toFlExp
e1
)
_
=
SOME
vF1`
\\
rename1
`eval_expr_float
(
toFlExp
e2
)
_
=
SOME
vF2`
\\
imp_res_tac
validRanges_single
\\
rename1
`FloverMapTree_find
e2
A
=
SOME
(
iv2
,
err2
)
`
\\
rename1
`FloverMapTree_find
e1
A
=
SOME
(
iv1
,
err1
)
`
\\
rename1
`eval_expr
E1
_
(
toREval
e2
)
nR2
REAL`
\\
rename1
`eval_expr
E1
_
(
toREval
e1
)
nR1
REAL`
(*
Obtain evaluation for E2 *)
\\
‘
!vF2
m2
.
eval_expr
E2
(
toRExpMap
Gamma
)
e2
vF2
m2
==>
abs
(
nR2
-
vF2
)
<=
err2
’
by
(
qspecl_then
[
`e2`
,
`E1`
,
`E2`
,
`A`
,
`nR2`
,
`err2`
,
`FST
iv2`
,
`SND
iv2`
,
`fVars`
,
`dVars`
,
`Gamma`
]
destruct
validErrorbound_sound
\\
rpt
conj_tac
\\
fs
[]
>-
(
fs
[
DIFF_DEF
,
SUBSET_DEF
]
\\
rpt
strip_tac
\\
first_x_assum
irule
\\
once_rewrite_tac
[
usedVars_def
]
\\
fs
[
domain_union
])
\\
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
mp_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
\\
`contained
(
float_to_real
(
fp64_to_float
vF2
))
(
widenInterval
(
FST
iv2
,
SND
iv2
)
err2
)
`
by
(
irule
distance_gives_iv
\\
qexists_tac
`nR2`
\\
fs
[
contained_def
]
\\
first_x_assum
irule
\\
qexists_tac
`M64`
\\
gs
[
fp64_to_real_def
])
\\
`b
=
Div
==>
float_to_real
(
fp64_to_float
vF2
)
<>
0
`
by
(
strip_tac
\\
rveq
\\
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
mp_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
widenInterval_def
,
contained_def
,
noDivzero_def
]
\\
rpt
strip_tac
>-
(
CCONTR_TAC
\\
fs
[]
\\
rveq
\\
`
0
<
0
:
real`
by
(
irule
REAL_LET_TRANS
\\
qexists_tac
`SND
iv2
+
err2`
\\
fs
[])
\\
fs
[])
>-
(
CCONTR_TAC
\\
fs
[]
\\
rveq
\\
`
0
<
0
:
real`
by
(
irule
REAL_LTE_TRANS
\\
qexists_tac
`FST
iv2
-
err2`
\\
fs
[])
\\
fs
[])
>-
(
CCONTR_TAC
\\
fs
[]
\\
rveq
\\
`
0
<
0
:
real`
by
(
irule
REAL_LET_TRANS
\\
qexists_tac
`SND
iv2
+
err2`
\\
fs
[])
\\
fs
[])
\\
CCONTR_TAC
\\
fs
[]
\\
rveq
\\
`
0
<
0
:
real`
by
(
irule
REAL_LTE_TRANS
\\
qexists_tac
`FST
iv2
-
err2`
\\
fs
[])
\\
fs
[])
\\
`validFloatValue
(
evalBinop
b
(
float_to_real
(
fp64_to_float
vF1
))
(
float_to_real
(
fp64_to_float
vF2
)))
M64`
by
(
drule
FPRangeValidator_sound
\\
disch_then
(
qspecl_then
[
`Binop
b
e1
e2`
,
`evalBinop
b
(
float_to_real
(
fp64_to_float
vF1
))
(
float_to_real
(
fp64_to_float
vF2
))
`
,
`M64`
]
irule
)
\\
fs
[]
\\
qexistsl_tac
[
`e1`
,
`e2`
]
\\
fs
[]
\\
rpt
conj_tac
>-
(
simp
[
Once
validTypes_def
]
\\
first_x_assum
MATCH_ACCEPT_TAC
)
>-
(
simp
[
Once
validRanges_def
]
\\
asm_exists_tac
\\
fs
[]
\\
fs
[]
\\
rveq
\\
fs
[])
\\
irule
Binop_dist'
\\
qexistsl_tac
[
‘
0
’
,
`M64`
,
`M64`
,
‘
M64
’
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
]
\\
Cases_on
`b`
\\
fs
[
perturb_def
,
evalBinop_def
,
mTypeToR_pos
,
fp64_to_real_def
])
\\
`validFloatValue
(
float_to_real
(
fp64_to_float
vF1
))
M64`
by
(
drule
FPRangeValidator_sound
\\
disch_then
(
qspecl_then
[
`e1`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`M64`
]
irule
)
\\
fs
[]
\\
qexistsl_tac
[
`e1`
]
\\
fs
[]
\\
rpt
conj_tac
>-
(
rw_thm_asm
`domain
(
usedVars
_)
DIFF
_
SUBSET
_
`
usedVars_def
\\
fs
[
domain_union
,
DIFF_DEF
,
SUBSET_DEF
,
Once
usedVars_def
])
>-
(
rw_thm_asm
`FPRangeValidator
_
_
_
_
`
FPRangeValidator_def
\\
fs
[]
\\
rveq
\\
rw_asm_star
`FloverMapTree_find
(
Binop
_
_
_)
A
=
_
`
\\
rw_asm_star
`FloverMapTree_find
(
Binop
_
_
_)
Gamma
=
_
`
)
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
mp_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
\\
gs
[
fp64_to_real_def
])
\\
`validFloatValue
(
float_to_real
(
fp64_to_float
vF2
))
M64`
by
(
drule
FPRangeValidator_sound
\\
disch_then
(
qspecl_then
[
`e2`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`M64`
]
irule
)
\\
fs
[]
\\
qexists_tac
`e2`
\\
fs
[]
\\
rpt
conj_tac
>-
(
rw_thm_asm
`domain
(
usedVars
_)
DIFF
_
SUBSET
_
`
usedVars_def
\\
fs
[
domain_union
,
DIFF_DEF
,
SUBSET_DEF
])
>-
(
rw_thm_asm
`FPRangeValidator
_
_
_
_
`
FPRangeValidator_def
\\
fs
[]
\\
rveq
\\
rw_asm_star
`FloverMapTree_find
(
Binop
_
_
_)
A
=
_
`
\\
rw_asm_star
`FloverMapTree_find
(
Binop
_
_
_)
Gamma
=
_
`
)
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
mp_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
\\
gs
[
fp64_to_real_def
])
\\
qpat_x_assum
`validFloatValue
(
evalBinop
_
_
_)
M64`
$
assume_tac
o
SIMP_RULE
std_ss
[
validFloatValue_def
]
(*
* Case distinction for operator **)
\\
Cases_on
`b`
\\
fs
[
GSYM
noDivzero_def
,
optionLift_def
,
PULL_EXISTS
]
\\
simp
[
Once
eval_expr_cases
]
(*
Addition, result normal *)
>-
(
fs
[
fp64_add_def
,
fp64_to_float_float_to_fp64
,
evalBinop_def
]
\\
Q
.
ISPECL_THEN
[
`
(
fp64_to_float
vF1
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF2
):(
52
,
11
)
float`
]
impl_subgoal_tac
float_add_relative
>-
(
rpt
conj_tac
\\
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
GSYM
float_is_zero_to_real
,
float_is_finite
,
evalBinop_def
])
\\
fs
[
dmode_def
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`e`
]
\\
fs
[
perturb_def
,
evalBinop_def
]
\\
imp_res_tac
normal_not_denormal
\\
simp
[
REAL_INV_1OVER
,
mTypeToR_def
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
]
\\
gs
[
fp64_to_real_def
])
(*
addition, result denormal *)
>-
(
fs
[
fp64_add_def
,
fp64_to_float_float_to_fp64
,
evalBinop_def
]
\\
Q
.
ISPECL_THEN
[
`
(
fp64_to_float
vF1
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF2
):(
52
,
11
)
float`
]
impl_subgoal_tac
float_add_relative_denorm
>-
(
rpt
conj_tac
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
(
fs
[
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
,
denormal_def
,
minValue_pos_def
]
\\
irule
REAL_LT_TRANS
\\
qpat_x_assum
‘
abs
_
*
_
<
1
’
$
irule_at
Any
\\
fs
[
GSYM
REAL_OF_NUM_POW
,
minExponentPos_def
])
>-
(
irule
REAL_LT_TRANS
\\
qexists_tac
‘
maxValue
M64
’
\\
fs
[
threshold_64_bit_lt_maxValue
,
denormal_def
]
\\
irule
REAL_LTE_TRANS
\\
qexists_tac
‘
minValue_pos
M64
’
\\
fs
[
minValue_pos_def
,
maxValue_def
,
GSYM
REAL_OF_NUM_POW
]
\\
EVAL_TAC
)
\\
fs
[
INT_MAX_def
,
INT_MIN_def
,
dimindex_11
])
\\
fs
[
dmode_def
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`e`
]
\\
fs
[
perturb_def
,
evalBinop_def
]
\\
fs
[
mTypeToR_def
,
minExponentPos_def
,
REAL_INV_1OVER
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
])
(*
result = 0 *)
>-
(
IMP_RES_TAC
validValue_gives_float_value
\\
fs
[
REAL_LNEG_UNIQ
,
evalBinop_def
]
\\
fs
[
fp64_add_def
,
dmode_def
,
fp64_to_float_float_to_fp64
]
\\
fs
[
float_add_def
,
float_round_with_flags_def
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`
0
:
real`
]
\\
fs
[
perturb_def
,
mTypeToR_pos
,
evalBinop_def
]
\\
`
2
*
abs
(
0
:
real
)
<=
ulp
(:
52
#11
)
`
by
(
fs
[
REAL_ABS_0
,
ulp_def
,
ULP_def
,
REAL_OF_NUM_POW
]
\\
once_rewrite_tac
[
real_div
]
\\
irule
REAL_LE_MUL
\\
fs
[]
\\
irule
REAL_LE_INV
\\
fs
[])
\\
fs
[
float_to_real_round_zero_is_zero
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
])
(*
Subtraction, normal value *)
>-
(
fs
[
fp64_sub_def
,
fp64_to_float_float_to_fp64
,
evalBinop_def
]
\\
Q
.
ISPECL_THEN
[
`
(
fp64_to_float
vF1
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF2
):(
52
,
11
)
float`
]
impl_subgoal_tac
float_sub_relative
>-
(
rpt
conj_tac
\\
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
GSYM
float_is_zero_to_real
,
float_is_finite
,
evalBinop_def
])
\\
fs
[
dmode_def
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`e`
]
\\
fs
[
perturb_def
,
evalBinop_def
]
\\
imp_res_tac
normal_not_denormal
\\
simp
[
REAL_INV_1OVER
,
mTypeToR_def
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
]
\\
gs
[
fp64_to_real_def
])
(*
Subtraction, denormal value *)
>-
(
fs
[
fp64_sub_def
,
fp64_to_float_float_to_fp64
,
evalBinop_def
]
\\
Q
.
ISPECL_THEN
[
`
(
fp64_to_float
vF1
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF2
):(
52
,
11
)
float`
]
impl_subgoal_tac
float_sub_relative_denorm
>-
(
rpt
conj_tac
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
(
fs
[
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
,
denormal_def
,
minValue_pos_def
]
\\
irule
REAL_LT_TRANS
\\
qpat_x_assum
‘
abs
_
*
_
<
1
’
$
irule_at
Any
\\
gs
[]
\\
EVAL_TAC
)
>-
(
irule
REAL_LT_TRANS
\\
qexists_tac
‘
maxValue
M64
’
\\
fs
[
threshold_64_bit_lt_maxValue
,
denormal_def
]
\\
irule
REAL_LTE_TRANS
\\
qexists_tac
‘
minValue_pos
M64
’
\\
fs
[
minValue_pos_def
,
maxValue_def
,
GSYM
REAL_OF_NUM_POW
]
\\
EVAL_TAC
)
\\
fs
[
INT_MAX_def
,
INT_MIN_def
,
dimindex_11
])
\\
fs
[
dmode_def
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`e`
]
\\
fs
[
perturb_def
,
evalBinop_def
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
]
\\
fs
[
mTypeToR_def
,
minExponentPos_def
,
REAL_INV_1OVER
])
(*
subtraction, result = 0 *)
>-
(
fs
[
evalBinop_def
]
\\
qpat_x_assum
`float_to_real
(
fp64_to_float
_)
=
_
`
MP_TAC
\\
simp
[
real_sub
,
REAL_LNEG_UNIQ
,
evalBinop_def
]
\\
fs
[
fp64_sub_def
,
dmode_def
,
fp64_to_float_float_to_fp64
]
\\
fs
[
float_sub_def
]
\\
fs
[
perturb_def
,
mTypeToR_pos
,
evalBinop_def
]
\\
fs
[
validValue_gives_float_value
,
float_round_with_flags_def
]
\\
strip_tac
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`
0
:
real`
]
\\
fs
[
perturb_def
,
mTypeToR_pos
,
evalBinop_def
]
\\
fs
[
validValue_gives_float_value
,
float_round_with_flags_def
]
\\
`
2
*
abs
(
0
:
real
)
<=
ulp
(:
52
#11
)
`
by
(
fs
[
REAL_ABS_0
,
ulp_def
,
ULP_def
,
REAL_OF_NUM_POW
]
\\
once_rewrite_tac
[
real_div
]
\\
irule
REAL_LE_MUL
\\
fs
[]
\\
irule
REAL_LE_INV
\\
fs
[])
\\
fs
[
float_to_real_round_zero_is_zero
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
])
(*
Multiplication, normal result *)
>-
(
fs
[
fp64_mul_def
,
fp64_to_float_float_to_fp64
,
evalBinop_def
]
\\
Q
.
ISPECL_THEN
[
`
(
fp64_to_float
vF1
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF2
):(
52
,
11
)
float`
]
impl_subgoal_tac
float_mul_relative
>-
(
rpt
conj_tac
\\
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
GSYM
float_is_zero_to_real
,
float_is_finite
,
evalBinop_def
])
\\
fs
[
dmode_def
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`e`
]
\\
fs
[
perturb_def
,
evalBinop_def
]
\\
imp_res_tac
normal_not_denormal
\\
fs
[
mTypeToR_def
,
REAL_INV_1OVER
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
])
(*
Multiplication, denormal result *)
>-
(
fs
[
fp64_mul_def
,
fp64_to_float_float_to_fp64
,
evalBinop_def
]
\\
Q
.
ISPECL_THEN
[
`
(
fp64_to_float
vF1
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF2
):(
52
,
11
)
float`
]
impl_subgoal_tac
float_mul_relative_denorm
>-
(
rpt
conj_tac
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
(
fs
[
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
,
denormal_def
,
minValue_pos_def
]
\\
irule
REAL_LT_TRANS
\\
qpat_x_assum
‘
abs
_
*
_
<
1
’
$
irule_at
Any
\\
gs
[
minExponentPos_def
]
\\
irule
REAL_LET_TRANS
\\
qexists_tac
‘
1
*
abs
(
float_to_real
(
fp64_to_float
vF1
)
*
float_to_real
(
fp64_to_float
vF2
))
’
\\
reverse
conj_tac
>-
gs
[]
\\
irule
REAL_LT_RMUL_IMP
\\
fs
[
float_is_zero_def
]
\\
imp_res_tac
validValue_gives_float_value
\\
gvs
[])
>-
(
irule
REAL_LT_TRANS
\\
qexists_tac
‘
maxValue
M64
’
\\
fs
[
threshold_64_bit_lt_maxValue
,
denormal_def
]
\\
irule
REAL_LTE_TRANS
\\
qexists_tac
‘
minValue_pos
M64
’
\\
fs
[
minValue_pos_def
,
maxValue_def
,
GSYM
REAL_OF_NUM_POW
]
\\
EVAL_TAC
)
\\
fs
[
INT_MAX_def
,
INT_MIN_def
,
dimindex_11
])
\\
fs
[
dmode_def
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`e`
]
\\
fs
[
perturb_def
,
evalBinop_def
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
]
\\
fs
[
mTypeToR_def
,
minExponentPos_def
,
REAL_INV_1OVER
])
(*
multiplication, result = 0 *)
>-
(
fs
[
evalBinop_def
,
REAL_ENTIRE
,
fp64_mul_def
,
float_mul_def
,
GSYM
float_is_zero_to_real
,
float_is_zero_def
]
THENL
[
Cases_on
`float_value
(
fp64_to_float
vF1
)
`
,
Cases_on
`float_value
(
fp64_to_float
vF2
)
`
]
\\
fs
[
validValue_gives_float_value
]
\\
fs
[
float_round_with_flags_def
,
dmode_def
,
fp64_to_float_float_to_fp64
,
perturb_def
]
\\
Cases_on
`
(
fp64_to_float
vF1
)
.
Sign
≠
(
fp64_to_float
vF2
)
.
Sign`
\\
`
2
*
abs
(
0
:
real
)
<=
ulp
(:
52
#11
)
`
by
(
fs
[
REAL_ABS_0
,
ulp_def
,
ULP_def
,
REAL_OF_NUM_POW
]
\\
once_rewrite_tac
[
real_div
]
\\
irule
REAL_LE_MUL
\\
fs
[]
\\
irule
REAL_LE_INV
\\
fs
[])
\\
fs
[
round_roundTiesToEven_is_plus_zero
,
round_roundTiesToEven_is_minus_zero
,
zero_to_real
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`
0
:
real`
]
\\
rveq
\\
fs
[
GSYM
float_is_zero_to_real
,
float_is_zero_def
,
mTypeToR_pos
,
perturb_def
])
(*
Division, normal result *)
>-
(
fs
[
fp64_div_def
,
fp64_to_float_float_to_fp64
,
evalBinop_def
]
\\
Q
.
ISPECL_THEN
[
`
(
fp64_to_float
vF1
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF2
):(
52
,
11
)
float`
]
impl_subgoal_tac
float_div_relative
>-
(
rpt
conj_tac
\\
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
GSYM
float_is_zero_to_real
,
float_is_finite
,
evalBinop_def
])
\\
fs
[
dmode_def
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`e`
]
\\
fs
[
perturb_def
,
evalBinop_def
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
]
\\
imp_res_tac
normal_not_denormal
\\
gs
[
mTypeToR_def
]
\\
rewrite_tac
[
REAL_INV_1OVER
]
\\
qpat_x_assum
‘
_
≤
1
’
mp_tac
\\
simp
[])
(*
Division, denormal result *)
>-
(
fs
[
fp64_div_def
,
fp64_to_float_float_to_fp64
,
evalBinop_def
]
\\
Q
.
ISPECL_THEN
[
`
(
fp64_to_float
vF1
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF2
):(
52
,
11
)
float`
]
impl_subgoal_tac
float_div_relative_denorm
>-
(
rpt
conj_tac
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
(
fs
[
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
,
denormal_def
,
minValue_pos_def
]
\\
irule
REAL_LT_TRANS
\\
qpat_x_assum
‘
_
<
1
’
$
irule_at
Any
\\
gs
[]
\\
EVAL_TAC
)
>-
(
irule
REAL_LT_TRANS
\\
qexists_tac
‘
maxValue
M64
’
\\
fs
[
threshold_64_bit_lt_maxValue
,
denormal_def
]
\\
irule
REAL_LTE_TRANS
\\
qexists_tac
‘
minValue_pos
M64
’
\\
fs
[
minValue_pos_def
,
maxValue_def
,
GSYM
REAL_OF_NUM_POW
]
\\
irule
REAL_LE_TRANS
\\
qexists_tac
‘
1
’
\\
conj_tac
>-
(
once_rewrite_tac
[
GSYM
REAL_INV1
]
\\
irule
REAL_INV_LE_ANTIMONO_IMPR
\\
fs
[
POW_2_LE1
])
\\
fs
[
POW_2_LE1
]
\\
EVAL_TAC
)
\\
fs
[
INT_MAX_def
,
INT_MIN_def
,
dimindex_11
])
\\
fs
[
dmode_def
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`e`
]
\\
fs
[
perturb_def
,
evalBinop_def
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
]
\\
gs
[
mTypeToR_def
,
minExponentPos_def
]
\\
rewrite_tac
[
REAL_INV_1OVER
]
\\
qpat_x_assum
‘
_
≤
1
’
mp_tac
\\
simp
[])
(*
division, result = 0 *)
>-
(
fs
[
fp64_div_def
,
dmode_def
,
fp64_to_float_float_to_fp64
,
float_div_def
,
evalBinop_def
]
\\
`float_to_real
(
fp64_to_float
vF1
)
=
0
`
by
(
imp_res_tac
div_eq0_general
)
\\
rw_thm_asm
`float_to_real
(
fp64_to_float
vF1
)
=
0
`
(
GSYM
float_is_zero_to_real
)
\\
fs
[
float_is_zero_def
]
\\
Cases_on
`float_value
(
fp64_to_float
vF1
)
`
\\
fs
[
validValue_gives_float_value
]
\\
simp
[
float_round_with_flags_def
]
\\
Cases_on
`
(
fp64_to_float
vF1
)
.
Sign
≠
(
fp64_to_float
vF2
)
.
Sign`
\\
`
2
*
abs
(
0
:
real
)
<=
ulp
(:
52
#11
)
`
by
(
fs
[
REAL_ABS_0
,
ulp_def
,
ULP_def
,
REAL_OF_NUM_POW
]
\\
once_rewrite_tac
[
real_div
]
\\
irule
REAL_LE_MUL
\\
fs
[]
\\
irule
REAL_LE_INV
\\
fs
[])
\\
fs
[
round_roundTiesToEven_is_plus_zero
,
round_roundTiesToEven_is_minus_zero
,
zero_to_real
]
\\
rveq
\\
`float_to_real
(
fp64_to_float
vF1
)
=
0
:
real`
by
(
fs
[
GSYM
float_is_zero_to_real
,
float_is_zero_def
])
\\
qexistsl_tac
[
`M64`
,
`M64`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`
0
:
real`
]
\\
fs
[
perturb_def
,
mTypeToR_pos
,
float_to_real_round_zero_is_zero
]
\\
gs
[
fp64_to_real_def
,
fp64_to_float_float_to_fp64
]))
>~
[
‘
Fma
e1
e2
e3
’
]
>-
(
imp_res_tac
validRanges_single
\\
rw_thm_asm
`validTypes
_
_
`
validTypes_def
\\
rw_thm_asm
`validRanges
_
_
_
_
`
validRanges_def
\\
fs
[
eval_expr_float_def
,
optionLift_def
]
\\
IMP_RES_TAC
validTypes_exec
\\
rveq
\\
first_x_assum
kall_tac
\\
`m1
=
M64
/\
m2
=
M64
/\
m3
=
M64`
by
(
fs
[
is64BitEnv_def
]
\\
rpt
conj_tac
\\
first_x_assum
irule
\\
find_exists_tac
\\
fs
[])
\\
rveq
\\
rw_thm_asm
`is64BitEval
_
`
is64BitEval_def
\\
fs
[]
\\
ntac
3
(
first_x_assum
(
qspecl_then
[
`E1`
,
`E2`
,
`Gamma`
]
assume_tac
))
\\
first_x_assum
(
qspecl_then
[
`v1`
,
`A`
,
`fVars`
,
`dVars`
]
destruct
)
>-
(
rpt
conj_tac
\\
fs
[]
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
assume_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
pop_assum
mp_tac
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
>-
(
rw_thm_asm
`FPRangeValidator
_
_
_
_
`
FPRangeValidator_def
\\
fs
[]
\\
rveq
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
A
=
_
`
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
Gamma
=
_
`
)
\\
rw_thm_asm
`domain
(
usedVars
_)
DIFF
_
SUBSET
_
`
usedVars_def
\\
fs
[
domain_union
,
DIFF_DEF
,
SUBSET_DEF
,
Once
usedVars_def
]
\\
rpt
strip_tac
\\
first_x_assum
irule
\\
simp
[
Once
usedVars_def
])
\\
first_x_assum
(
qspecl_then
[
`v2`
,
`A`
,
`fVars`
,
`dVars`
]
destruct
)
>-
(
rpt
conj_tac
\\
fs
[]
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
assume_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
pop_assum
mp_tac
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
>-
(
rw_thm_asm
`FPRangeValidator
_
_
_
_
`
FPRangeValidator_def
\\
fs
[]
\\
rveq
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
A
=
_
`
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
Gamma
=
_
`
)
\\
rw_thm_asm
`domain
(
usedVars
_)
DIFF
_
SUBSET
_
`
usedVars_def
\\
fs
[
domain_union
,
DIFF_DEF
,
SUBSET_DEF
])
\\
first_x_assum
(
qspecl_then
[
`v3`
,
`A`
,
`fVars`
,
`dVars`
]
destruct
)
>-
(
rpt
conj_tac
\\
fs
[]
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
assume_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
pop_assum
mp_tac
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
>-
(
rw_thm_asm
`FPRangeValidator
_
_
_
_
`
FPRangeValidator_def
\\
fs
[]
\\
rveq
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
A
=
_
`
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
Gamma
=
_
`
)
\\
rw_thm_asm
`domain
(
usedVars
_)
DIFF
_
SUBSET
_
`
usedVars_def
\\
fs
[
domain_union
,
DIFF_DEF
,
SUBSET_DEF
])
\\
rename1
‘
eval_expr_float
(
toFlExp
e1
)
(
toFlEnv
E2
)
=
SOME
vF1
’
\\
rename1
‘
eval_expr_float
(
toFlExp
e2
)
(
toFlEnv
E2
)
=
SOME
vF2
’
\\
rename1
‘
eval_expr_float
(
toFlExp
e3
)
(
toFlEnv
E2
)
=
SOME
vF3
’
\\
`validFloatValue
(
evalFma
(
float_to_real
(
fp64_to_float
vF1
))
(
float_to_real
(
fp64_to_float
vF2
))
(
float_to_real
(
fp64_to_float
vF3
)))
M64`
by
(
drule
FPRangeValidator_sound
\\
disch_then
(
qspecl_then
[
`Fma
e1
e2
e3`
,
`evalFma
(
float_to_real
(
fp64_to_float
vF1
))
(
float_to_real
(
fp64_to_float
vF2
))
(
float_to_real
(
fp64_to_float
vF3
))
`
,
`M64`
]
irule
)
\\
fs
[]
\\
qexistsl_tac
[
`e1`
,
`e2`
,
‘
e3
’
]
\\
fs
[]
\\
rpt
conj_tac
>-
(
simp
[
Once
validTypes_def
]
\\
first_x_assum
MATCH_ACCEPT_TAC
)
>-
(
simp
[
Once
validRanges_def
]
\\
find_exists_tac
\\
fs
[]
\\
fs
[]
\\
rveq
\\
fs
[])
\\
simp
[
Once
eval_expr_cases
]
\\
qexistsl_tac
[
`M64`
,
`M64`
,
‘
M64
’
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`float_to_real
(
fp64_to_float
vF3
)
`
,
`
0
:
real`
]
\\
fs
[
perturb_def
,
evalFma_def
,
mTypeToR_pos
,
fp64_to_real_def
])
\\
`validFloatValue
(
float_to_real
(
fp64_to_float
vF1
))
M64`
by
(
drule
FPRangeValidator_sound
\\
disch_then
(
qspecl_then
[
`e1`
,
`float_to_real
(
fp64_to_float
vF1
)
`
,
`M64`
]
irule
)
\\
fs
[]
\\
qexistsl_tac
[
`e1`
]
\\
fs
[]
\\
rpt
conj_tac
>-
(
rw_thm_asm
`domain
(
usedVars
_)
DIFF
_
SUBSET
_
`
usedVars_def
\\
fs
[
domain_union
,
DIFF_DEF
,
SUBSET_DEF
,
Once
usedVars_def
])
>-
(
rw_thm_asm
`FPRangeValidator
_
_
_
_
`
FPRangeValidator_def
\\
fs
[]
\\
rveq
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
A
=
_
`
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
Gamma
=
_
`
)
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
assume_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
pop_assum
mp_tac
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
\\
fs
[
fp64_to_real_def
])
\\
`validFloatValue
(
float_to_real
(
fp64_to_float
vF2
))
M64`
by
(
drule
FPRangeValidator_sound
\\
disch_then
(
qspecl_then
[
`e2`
,
`float_to_real
(
fp64_to_float
vF2
)
`
,
`M64`
]
irule
)
\\
fs
[]
\\
qexists_tac
`e2`
\\
fs
[]
\\
rpt
conj_tac
>-
(
rw_thm_asm
`domain
(
usedVars
_)
DIFF
_
SUBSET
_
`
usedVars_def
\\
fs
[
domain_union
,
DIFF_DEF
,
SUBSET_DEF
])
>-
(
rw_thm_asm
`FPRangeValidator
_
_
_
_
`
FPRangeValidator_def
\\
fs
[]
\\
rveq
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
A
=
_
`
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
Gamma
=
_
`
)
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
assume_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
pop_assum
mp_tac
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
\\
gs
[
fp64_to_real_def
])
\\
`validFloatValue
(
float_to_real
(
fp64_to_float
vF3
))
M64`
by
(
drule
FPRangeValidator_sound
\\
disch_then
(
qspecl_then
[
`e3`
,
`float_to_real
(
fp64_to_float
vF3
)
`
,
`M64`
]
irule
)
\\
fs
[]
\\
qexists_tac
`e3`
\\
fs
[]
\\
rpt
conj_tac
>-
(
rw_thm_asm
`domain
(
usedVars
_)
DIFF
_
SUBSET
_
`
usedVars_def
\\
fs
[
domain_union
,
DIFF_DEF
,
SUBSET_DEF
])
>-
(
rw_thm_asm
`FPRangeValidator
_
_
_
_
`
FPRangeValidator_def
\\
fs
[]
\\
rveq
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
A
=
_
`
\\
rw_asm_star
`FloverMapTree_find
(
Fma
_
_
_)
Gamma
=
_
`
)
>-
(
qpat_x_assum
‘
validErrorbound
_
_
_
_
’
(
fn
thm
=>
assume_tac
(
ONCE_REWRITE_RULE
[
validErrorbound_def
]
thm
))
\\
fs
[
option_case_eq
]
\\
pop_assum
mp_tac
\\
rpt
(
TOP_CASE_TAC
\\
fs
[]))
\\
gs
[
fp64_to_real_def
])
\\
qpat_x_assum
‘
validFloatValue
(
evalFma
_
_
_)
_
’
(
assume_tac
o
SIMP_RULE
std_ss
[
validFloatValue_def
])
\\
fs
[
optionLift_def
]
\\
simp
[
Once
eval_expr_cases
,
PULL_EXISTS
]
\\
rewrite_tac
[
CONJ_ASSOC
]
\\
ntac
3
(
once_rewrite_tac
[
CONJ_COMM
]
\\
asm_exists_tac
\\
fs
[])
\\
fs
[
evalFma_def
,
evalBinop_def
,
fp64_mul_add_def
,
fp64_to_real_def
,
fp64_to_float_float_to_fp64
]
>-
(
Q
.
ISPECL_THEN
[
`
(
fp64_to_float
vF1
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF2
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF3
):(
52
,
11
)
float`
]
impl_subgoal_tac
float_mul_add_relative
>-
(
rpt
conj_tac
\\
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
GSYM
float_is_zero_to_real
,
float_is_finite
,
evalFma_def
,
evalBinop_def
])
\\
fs
[
dmode_def
]
\\
fs
[
perturb_def
]
\\
qexistsl_tac
[
`e`
]
\\
pop_assum
(
rewrite_tac
o
single
)
\\
fs
[
perturb_def
,
evalBinop_def
]
\\
imp_res_tac
normal_not_denormal
\\
fs
[
mTypeToR_def
,
REAL_INV_1OVER
])
(*
result denormal *)
>-
(
fs
[
fp64_mul_add_def
,
fp64_to_float_float_to_fp64
,
evalFma_def
]
\\
Q
.
ISPECL_THEN
[
`
(
fp64_to_float
vF1
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF2
):(
52
,
11
)
float`
,
`
(
fp64_to_float
vF3
):(
52
,
11
)
float`
]
impl_subgoal_tac
float_mul_add_relative_denorm
>-
(
rpt
conj_tac
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
fs
[
validFloatValue_def
,
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
]
>-
(
fs
[
normalTranslatedValue_implies_finiteness
,
denormalTranslatedValue_implies_finiteness
,
normalValue_implies_normalization
,
float_is_finite
,
GSYM
float_is_zero_to_real
,
evalBinop_def
,
denormal_def
,
minValue_pos_def
]
\\
irule
REAL_LT_TRANS
\\
qpat_x_assum
‘
_
<
1
’
$
irule_at
Any
\\
gs
[]
\\
EVAL_TAC
)
>-
(
irule
REAL_LT_TRANS
\\
qexists_tac
‘
maxValue
M64
’
\\
fs
[
threshold_64_bit_lt_maxValue
,
denormal_def
]
\\
irule
REAL_LTE_TRANS
\\
qexists_tac
‘
minValue_pos
M64
’
\\
fs
[
minValue_pos_def
,
maxValue_def
,
GSYM
REAL_OF_NUM_POW
]
\\
EVAL_TAC
)
\\
fs
[
INT_MAX_def
,
INT_MIN_def
,
dimindex_11
])
\\
fs
[
dmode_def
]
\\
qexists_tac
‘
e
’
\\
fs
[
perturb_def
,
evalFma_def
]
\\
fs
[
mTypeToR_def
,
minExponentPos_def
,
REAL_INV_1OVER
])
(*
result = 0 *)
>-
(
imp_res_tac
validValue_gives_float_value
\\
fs
[
REAL_LNEG_UNIQ
,
evalFma_def
,
evalBinop_def
]
\\
fs
[
fp64_add_def
,
dmode_def
,
fp64_mul_def
,
fp64_to_float_float_to_fp64
]
\\
fs
[
float_mul_add_def
,
float_round_with_flags_def
]
\\
qexists_tac
`
0
:
real`
\\
fs
[
perturb_def
,
mTypeToR_pos
,
evalBinop_def
]
\\
fs
[
float_is_nan_def
,
float_is_infinite_def
]
\\
`
2
*
abs
(
0
:
real
)
<=
ulp
(:
52
#11
)
`
by
(
fs
[
REAL_ABS_0
,
ulp_def
,
ULP_def
,
REAL_OF_NUM_POW
]
\\
once_rewrite_tac
[
real_div
]
\\
irule
REAL_LE_MUL
\\
fs
[]
\\
irule
REAL_LE_INV
\\
fs
[])
\\
fs
[
float_to_real_round_zero_is_zero
]))
QED
(*
* The below does not work because of double-rounding **)
(*
Theorem bstep_gives_IEEE:
!(f:real cmd) E1 E2 Gamma vR vF A fVars dVars outVars.
approxEnv E1 (toRExpMap Gamma) A fVars dVars E2 /\
ssa f (union fVars dVars) outVars /\
validTypesCmd f Gamma /\
validRangesCmd f A E1 (toRTMap (toRExpMap Gamma)) /\
validErrorboundCmd f Gamma A dVars /\
FPRangeValidatorCmd f A Gamma dVars /\
bstep (toREvalCmd f) E1 (toRTMap (toRExpMap Gamma)) vR REAL /\
bstep f E2 (toRExpMap Gamma) vF M64 /\
domain (freeVars f) DIFF domain dVars ⊆ domain fVars ∧
is64BitBstep f /\
is64BitEnv Gamma /\
noDowncastFun f /\
(∀ x v. E2 x = SOME v ⇒ float_to_real ((real_to_float dmode v):(52,11) float) = v) ∧
(∀v.
v ∈ domain dVars ⇒
∃vF m.
(E2 v = SOME vF ∧ FloverMapTree_find (Var v) Gamma = SOME m ∧
validFloatValue vF m)) ==>
?v.
bstep_float (toFlCmd f) (toFlEnv E2) = SOME v /\
bstep f E2 (toRExpMap Gamma)
(fp64_to_real v) M64
Proof
reverse $ Induct_on `f`
\\ simp [toFlCmd_def, Once toREvalCmd_def, is64BitBstep_def,
noDowncastFun_def]
\\ rpt strip_tac
\\ rpt (inversion `bstep (Let _ _ _ _) _ _ _ _` bstep_cases)
\\ inversion `ssa _ _ _` ssa_cases
\\ once_rewrite_tac [bstep_float_def]
\\ fs[noDowncast_def]
\\ qpat_x_assum ‘validErrorboundCmd _ _ _ _’
(fn thm => mp_tac (ONCE_REWRITE_RULE[validErrorboundCmd_def] thm))
\\ fs[option_case_eq]
>- (
strip_tac \\ fs[bstep_cases, bstep_float_def]
\\ irule eval_expr_gives_IEEE_reverse
\\ rpt conj_tac
\\ fs[Once validTypesCmd_def]
>- first_x_assum $ irule_at Any
\\ gs[getRetExp_def, freeVars_def]
\\ rpt $ first_x_assum $ irule_at Any
\\ conj_tac
\\ fs[freeVars_def, Once FPRangeValidatorCmd_def, validRangesCmd_def])
\\ rpt (TOP_CASE_TAC \\ fs[])
\\ rpt strip_tac \\ gvs[]
\\ `?v_e. eval_expr_float (toFlExp e) (toFlEnv E2) = SOME v_e /\
eval_expr E2 (toRExpMap Gamma) e (fp64_to_real v_e) M64`
by (irule eval_expr_gives_IEEE_reverse \\ rpt conj_tac \\ fs[]
>- fs[Once validTypesCmd_def]
>- first_x_assum $ irule_at Any
\\ qexistsl_tac [`A`, `E1`, `dVars`, `fVars`]
\\ rpt conj_tac \\ fs[]
>- (fs[Once freeVars_def, domain_union, DIFF_DEF, SUBSET_DEF]
\\ rpt strip_tac
\\ `x IN domain fVars \/ x IN domain dVars`
by (first_x_assum irule \\ fs[]))
>- (fs [Once FPRangeValidatorCmd_def])
\\ fs[Once validRangesCmd_def])
\\ fs[Once validRangesCmd_def]
\\ imp_res_tac validRanges_single
\\ imp_res_tac validRangesCmd_single
\\ fs[Once validTypesCmd_def]
(* prove validity of errorbound for floating-point value *)
\\ qspecl_then
[`e`, `E1`, `E2`, `A`, `v'`, `r`,
`FST iv`, `SND iv`, `fVars`, `dVars`, `Gamma`]
impl_subgoal_tac
validErrorbound_sound
>- (
fs[DIFF_DEF, SUBSET_DEF]
\\ rpt strip_tac \\ first_x_assum irule
\\ fs[Once freeVars_def, domain_union]
\\ CCONTR_TAC \\ fs[] \\ rveq \\ fs[]
\\ `n IN domain fVars \/ n IN domain dVars`
by (first_x_assum irule \\ fs[]))
\\ fs[]
\\ imp_res_tac meps_0_deterministic \\ rveq
\\ rename1 `FST iv <= vR_e`
\\ rename1 ‘FloverMapTree_find (getRetExp (Let M64 n e f)) A =
SOME (ivR,errR)’
\\ rename1 `FST iv_e <= vR_e`
\\ rename1 `abs (vR_e - nF) <= err_e`
\\ `abs (vR_e - (fp64_to_real v_e)) <= err_e`
by (first_x_assum irule \\ fs[]
\\ first_x_assum $ irule_at Any)
\\ fs[getRetExp_def]
\\ rename1 `FloverMapTree_find (getRetExp f) A = SOME (iv_f, err_f)`
(* Now construct a new evaluation according to our big-step semantics
using lemma validErrorboundCmd_gives_eval *)
\\ qspecl_then
[ `f`, `A`, `updEnv n vR_e E1`,
`updEnv n (fp64_to_real v_e) E2`,
`outVars`, `fVars`, `insert n () dVars`, `vR`, `FST iv_f`, `SND iv_f`,
`err_f`, `M64`, `Gamma`]
impl_subgoal_tac
validErrorboundCmd_gives_eval
>- (
fs[] \\ rpt conj_tac
>- (
irule approxEnvUpdBound
\\ fs[lookup_NONE_domain, toRExpMap_def])
>- (
irule ssa_equal_set
\\ qexists_tac `insert n () (union fVars dVars)`
\\ conj_tac \\ TRY (fs[] \\ FAIL_TAC "")
\\ rewrite_tac [domain_union, domain_insert]
\\ rewrite_tac [UNION_DEF, INSERT_DEF]
\\ fs[EXTENSION]
\\ rpt strip_tac
\\ metis_tac[])
>- (
fs[DIFF_DEF, domain_insert, SUBSET_DEF]
\\ rpt strip_tac \\ first_x_assum irule
\\ fs[Once freeVars_def]
\\ simp[Once freeVars_def, domain_union]))
\\ fs[optionLift_def]
(* Instantiate IH with newly obtained evaluation, to get the conclusion *)
\\ first_x_assum
(qspecl_then [`updEnv n vR_e E1`,
`updEnv n (fp64_to_real v_e) E2`,
`Gamma`, `vR`, `vF'`, `A`, `fVars`,
`insert n () dVars`, `outVars`]
impl_subgoal_tac)
>- (
simp[Once validErrorboundCmd_def]
\\ fs [Once FPRangeValidatorCmd_def, Once validTypesCmd_def,
Once validRangesCmd_def]
\\ rpt conj_tac
>- (
drule approxEnvUpdBound
\\ rpt $ disch_then drule
\\ fs[domain_lookup, lookup_NONE_domain, toRExpMap_def])
>- (
irule ssa_equal_set
\\ qexists_tac `insert n () (union fVars dVars)`
\\ conj_tac \\ TRY (fs[] \\ FAIL_TAC "")
\\ rewrite_tac [domain_union, domain_insert]
\\ rewrite_tac [UNION_DEF, INSERT_DEF]
\\ fs[EXTENSION]
\\ rpt strip_tac
\\ metis_tac[])
>- first_x_assum MATCH_ACCEPT_TAC
>- (
reverse (sg `m' = M64`)
>- (rveq \\ fs[])
\\ irule bstep_Gamma_det \\ rpt (find_exists_tac \\ fs[]))
>- (
fs[DIFF_DEF, domain_insert, SUBSET_DEF]
\\ rpt strip_tac \\ first_x_assum irule
\\ fs[Once freeVars_def]
\\ simp[Once freeVars_def, domain_union])
>- (rpt strip_tac \\ Cases_on ‘x = n’ \\ gs[]
>- (rveq \\ simp[fp64_to_real_def]
\\ ‘float_is_finite (fp64_to_float v_e)’
by (gs[float_is_finite_def]
\\‘validFloatValue (float_to_real (fp64_to_float v_e)) M64’
suffices_by (gs[validValue_gives_float_value])
\\ irule FPRangeValidator_sound
\\ rpt $ first_x_assum $ irule_at Any
\\ gs[fp64_to_real_def]
\\ fs[Once freeVars_def, domain_union, DIFF_DEF, SUBSET_DEF]
\\ rpt strip_tac \\ first_x_assum irule \\ fs[]
\\ CCONTR_TAC \\ fs[]
\\ rveq \\ fs[]
\\ metis_tac [])
\\ simp[float_to_real_round_robin])
\\ first_x_assum irule \\ first_x_assum $ irule_at Any)
>- (
rpt strip_tac \\ simp[updEnv_def]
\\ rveq \\ fs[]
>- (
irule FPRangeValidator_sound
\\ rpt $ first_x_assum $ irule_at Any \\ conj_tac
\\ fs[Once freeVars_def, domain_union, DIFF_DEF, SUBSET_DEF]
\\ rpt strip_tac \\ first_x_assum irule \\ fs[]
\\ CCONTR_TAC \\ fs[]
\\ rveq \\ fs[]
\\ metis_tac [])
\\ IF_CASES_TAC \\ fs[]
\\ irule FPRangeValidator_sound
\\ rpt $ first_x_assum $ irule_at Any \\ conj_tac
\\ fs[Once freeVars_def, domain_union, DIFF_DEF, SUBSET_DEF])
\\ fs[]
(** DOUBLE ROUNDING HERE.... **)
\\ ‘updFlEnv n v_e (toFlEnv E2) = toFlEnv (updEnv n (fp64_to_real v_e) E2)’
by (gs[updFlEnv_def, toFlEnv_def, FUN_EQ_THM]
\\ strip_tac \\ Cases_on ‘x = n’
\\
\\ gs[real_to_fp64_def, fp64_to_real_def]
\\ irule let_b \\ fs[toRExpMap_def] \\ find_exists_tac
\\ fs[] \\ irule bstep_eq_env
\\ find_exists_tac \\ fs[]
\\ strip_tac \\ fs[toREnv_def, updEnv_def, updFlEnv_def]
\\ IF_CASES_TAC \\ fs[])
QED
*)
val
found_tac
=
TRY
(
last_x_assum
irule
\\
find_exists_tac
\\
fs
[]
\\
FAIL_TAC
""
)
\\
first_x_assum
irule
\\
find_exists_tac
\\
fs
[];
Theorem
IEEE_connection_expr
:
!
(
e
:
real
expr
)
(
A
:
analysisResult
)
(
P
:
precond
)
E1
E2
defVars
fVars
Gamma
.
is64BitEval
e
/\
is64BitEnv
defVars
/\
noDowncast
e
/\
fVars_P_sound
fVars
E1
P
/\
(
domain
(
usedVars
e
))
SUBSET
(
domain
fVars
)
/\
CertificateChecker
e
A
P
defVars
=
SOME
Gamma
/\
(
∀
x
v
.
E2
x
=
SOME
v
⇒
float_to_real
((
real_to_float
dmode
v
):(
52
,
11
)
float
)
=
v
)
∧
approxEnv
E1
(
toRExpMap
Gamma
)
A
fVars
LN
E2
⇒
?iv
err
vR
vF
.
(
*
m
,
currently
=
M64
*
)
FloverMapTree_find
e
A
=
SOME
(
iv
,
err
)
/\
eval_expr
E1
(
toRTMap
(
toRExpMap
Gamma
))
(
toREval
e
)
vR
REAL
/\
eval_expr_float
(
toFlExp
e
)
(
toFlEnv
E2
)
=
SOME
vF
/\
eval_expr
E2
(
toRExpMap
Gamma
)
e
(
fp64_to_real
vF
)
M64
/\
abs
(
vR
-
(
fp64_to_real
vF
))
<=
err
Proof
simp
[
CertificateChecker_def
]
\\
rpt
strip_tac
\\
Cases_on
`getValidMap
defVars
e
FloverMapTree_empty`
\\
fs
[]
\\
rveq
\\
imp_res_tac
getValidMap_top_correct
\\
`validTypes
e
Gamma`
by
(
first_x_assum
irule
\\
fs
[
FloverMapTree_empty_def
,
FloverMapTree_mem_def
,
FloverMapTree_find_def
])
\\
`!
e
m
.
FloverMapTree_find
e
Gamma
=
SOME
m
==>
m
=
M64`
by
(
rpt
strip_tac
\\
irule
getValidMap_preserving
\\
qexistsl_tac
[
`FloverMapTree_empty`
,
`defVars`
,
`e`
,
`e'`
,
`Gamma`
]
\\
rpt
conj_tac
\\
rpt
strip_tac
\\
fs
[
FloverMapTree_empty_def
,
FloverMapTree_find_def
,
is64BitEnv_def
]
\\
first_x_assum
irule
\\
find_exists_tac
\\
fs
[])
\\
drule
validIntervalbounds_sound
\\
rpt
$
disch_then
drule
\\
disch_then
(
qspecl_then
[
`fVars`
,
`E1`
,
`Gamma`
]
destruct
)
\\
fs
[
dVars_range_valid_def
,
fVars_P_sound_def
]
\\
drule
validErrorbound_sound
\\
rpt
$
disch_then
drule
\\
imp_res_tac
validRanges_single
\\
disch_then
(
qspecl_then
[
`vR`
,
`err`
,
`FST
iv`
,
`SND
iv`
]
destruct
)
\\
fs
[]
\\
qspecl_then
[
`e`
,
`E1`
,
`E2`
,
`Gamma`
,
`nF`
,
`A`
,
`fVars`
,
`LN`
]
destruct
eval_expr_gives_IEEE_reverse
>-
(
rpt
conj_tac
\\
fs
[]
>-
(
`FloverMapTree_find
e
Gamma
=
SOME
M64`
by
(
irule
typing_expr_64bit
\\
fs
[
is64BitEnv_def
]
\\
first_x_assum
MATCH_ACCEPT_TAC
)
\\
`m
=
M64`
by
(
irule
validTypes_exec
\\
rpt
(
find_exists_tac
\\
fs
[]))
\\
rveq
\\
fs
[])
\\
fs
[
is64BitEnv_def
]
\\
first_x_assum
MATCH_ACCEPT_TAC
)
\\
rpt
$
first_assum
$
irule_at
Any
QED
(*
* Does not work because of let-bindings **)
(*
Theorem IEEE_connection_cmds:
! (f:word64 cmd) (A:analysisResult) (P:precond) E1 E2 defVars (fVars:num_set)
Gamma.
is64BitBstep (toRCmd f) /\
is64BitEnv defVars /\
noDowncastFun (toRCmd f) /\
fVars_P_sound fVars E1 P /\
(domain (freeVars (toRCmd f))) SUBSET (domain fVars) /\
CertificateCheckerCmd (toRCmd f) A P defVars = SOME Gamma /\
approxEnv E1 (toRExpMap Gamma) A (freeVars (toRCmd f)) LN (toREnv E2) ==>
?iv err vR vF. (* m, currently = M64 *)
FloverMapTree_find (getRetExp (toRCmd f)) A = SOME (iv, err) /\
bstep (toREvalCmd (toRCmd f)) E1 (toRTMap (toRExpMap Gamma)) vR REAL /\
bstep_float f E2 = SOME vF /\
bstep (toRCmd f) (toREnv E2) (toRExpMap Gamma)
(float_to_real (fp64_to_float vF)) M64 /\
abs (vR - (float_to_real (fp64_to_float vF))) <= err
Proof
simp [CertificateCheckerCmd_def]
\\ rpt strip_tac
\\ Cases_on `getValidMapCmd defVars (toRCmd f) FloverMapTree_empty` \\ fs[]
\\ rveq \\ IMP_RES_TAC getValidMapCmd_correct
\\ `validTypesCmd (toRCmd f) Gamma`
by (first_x_assum irule
\\ fs[FloverMapTree_empty_def, FloverMapTree_mem_def, FloverMapTree_find_def])
\\ `! e m. FloverMapTree_find e Gamma = SOME m ==> m = M64`
by (rpt strip_tac \\ irule getValidMapCmd_preserving
\\ qexistsl_tac [`FloverMapTree_empty`, `defVars`, `e`, `toRCmd f`, `Gamma`]
\\ rpt conj_tac \\ rpt strip_tac
\\ fs[FloverMapTree_empty_def, FloverMapTree_find_def , is64BitEnv_def]
\\ first_x_assum irule \\ find_exists_tac \\ fs[])
\\ `?outVars. ssa (toRCmd f) (freeVars (toRCmd f)) outVars`
by (match_mp_tac validSSA_sound \\ fs[])
\\ qspecl_then
[`toRCmd f`, `A`, `E1`, `freeVars (toRCmd f)`, `LN`, `outVars`, `P`, `Gamma`]
destruct validIntervalboundsCmd_sound
\\ fs[dVars_range_valid_def, fVars_P_sound_def]
>- (rpt strip_tac \\ first_x_assum irule \\ fs[SUBSET_DEF])
\\ IMP_RES_TAC validRangesCmd_single
\\ qspecl_then
[`toRCmd f`, `A`, `E1`, `toREnv E2`, `outVars`, `freeVars (toRCmd f)`, `LN`, `vR`, `FST iv_e`,
`SND iv_e`, `err_e`, `M64`, `Gamma`]
destruct validErrorboundCmd_gives_eval
\\ fs[]
\\ rpt (find_exists_tac \\ fs[])
\\ qspecl_then
[`f`, `E1`, `E2`, `toREnv E2`, `Gamma`, `vR`, `vF`, `A`, `freeVars (toRCmd f)`, `LN`, `outVars`]
destruct
bstep_gives_IEEE
>- (fs[is64BitEnv_def]
\\ conj_tac
>- (`FloverMapTree_find (getRetExp (toRCmd f)) Gamma = SOME M64`
by (irule typing_cmd_64bit
\\ fs[is64BitEnv_def] \\ first_x_assum MATCH_ACCEPT_TAC)
\\ `m = M64`
by (drule validTypesCmd_single
\\ disch_then assume_tac \\ fs[]
\\ fs[] \\ rveq \\ fs[]
\\ first_x_assum irule
\\ qexistsl_tac [`toREnv E2`, `Gamma`, `vF`] \\ fs[])
\\ rveq \\ fs[])
\\ first_x_assum MATCH_ACCEPT_TAC)
\\ find_exists_tac \\ fs[]
\\ drule validErrorboundCmd_sound
\\ rpt (disch_then drule)
\\ rename1 `bstep (toRCmd f) (toREnv E2) _ vF2 m2`
\\ disch_then
(qspecl_then
[`outVars`, `vR`, `vF2`, `FST iv_e`, `SND iv_e`, `err_e`, `m2`] destruct)
\\ fs[]
QED
*)
val
_
=
export_theory
();
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment