diff options
38 files changed, 2378 insertions, 364 deletions
@@ -8,6 +8,7 @@ lib/Ordered.vo lib/Ordered.glob lib/Ordered.v.beautified: lib/Ordered.v lib/Coql lib/Iteration.vo lib/Iteration.glob lib/Iteration.v.beautified: lib/Iteration.v lib/Axioms.vo lib/Coqlib.vo lib/Wfsimpl.vo lib/Integers.vo lib/Integers.glob lib/Integers.v.beautified: lib/Integers.v lib/Coqlib.vo lib/Floats.vo lib/Floats.glob lib/Floats.v.beautified: lib/Floats.v lib/Axioms.vo lib/Coqlib.vo lib/Integers.vo flocq/Appli/Fappli_IEEE.vo flocq/Appli/Fappli_IEEE_bits.vo flocq/Core/Fcore.vo flocq/Calc/Fcalc_round.vo flocq/Calc/Fcalc_bracket.vo flocq/Prop/Fprop_Sterbenz.vo +$(ARCH)/Nan.vo $(ARCH)/Nan.glob $(ARCH)/Nan.v.beautified: $(ARCH)/Nan.v flocq/Appli/Fappli_IEEE.vo flocq/Appli/Fappli_IEEE_bits.vo lib/Floats.vo lib/Integers.vo lib/Parmov.vo lib/Parmov.glob lib/Parmov.v.beautified: lib/Parmov.v lib/Axioms.vo lib/Coqlib.vo lib/UnionFind.vo lib/UnionFind.glob lib/UnionFind.v.beautified: lib/UnionFind.v lib/Coqlib.vo lib/Wfsimpl.vo lib/Wfsimpl.glob lib/Wfsimpl.v.beautified: lib/Wfsimpl.v lib/Axioms.vo @@ -107,31 +108,32 @@ cfrontend/Cminorgen.vo cfrontend/Cminorgen.glob cfrontend/Cminorgen.v.beautified cfrontend/Cminorgenproof.vo cfrontend/Cminorgenproof.glob cfrontend/Cminorgenproof.v.beautified: cfrontend/Cminorgenproof.v lib/Coqlib.vo lib/Intv.vo common/Errors.vo lib/Maps.vo common/AST.vo lib/Integers.vo lib/Floats.vo common/Values.vo common/Memory.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo common/Switch.vo cfrontend/Csharpminor.vo backend/Cminor.vo cfrontend/Cminorgen.vo driver/Compiler.vo driver/Compiler.glob driver/Compiler.v.beautified: driver/Compiler.v lib/Coqlib.vo common/Errors.vo common/AST.vo common/Smallstep.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Cstrategy.vo cfrontend/Cexec.vo cfrontend/Clight.vo cfrontend/Csharpminor.vo backend/Cminor.vo backend/CminorSel.vo backend/RTL.vo backend/LTL.vo backend/Linear.vo backend/Mach.vo $(ARCH)/Asm.vo cfrontend/Initializers.vo cfrontend/SimplExpr.vo cfrontend/SimplLocals.vo cfrontend/Cshmgen.vo cfrontend/Cminorgen.vo backend/Selection.vo backend/RTLgen.vo backend/Tailcall.vo backend/Inlining.vo backend/Renumber.vo backend/Constprop.vo backend/CSE.vo backend/Allocation.vo backend/Tunneling.vo backend/Linearize.vo backend/CleanupLabels.vo backend/Stacking.vo $(ARCH)/Asmgen.vo cfrontend/SimplExprproof.vo cfrontend/SimplLocalsproof.vo cfrontend/Cshmgenproof.vo cfrontend/Cminorgenproof.vo backend/Selectionproof.vo backend/RTLgenproof.vo backend/Tailcallproof.vo backend/Inliningproof.vo backend/Renumberproof.vo backend/Constpropproof.vo backend/CSEproof.vo backend/Allocproof.vo backend/Tunnelingproof.vo backend/Linearizeproof.vo backend/CleanupLabelsproof.vo backend/Stackingproof.vo $(ARCH)/Asmgenproof.vo driver/Complements.vo driver/Complements.glob driver/Complements.v.beautified: driver/Complements.v lib/Coqlib.vo common/AST.vo lib/Integers.vo common/Values.vo common/Events.vo common/Globalenvs.vo common/Smallstep.vo common/Behaviors.vo cfrontend/Csyntax.vo cfrontend/Csem.vo cfrontend/Cstrategy.vo cfrontend/Clight.vo backend/Cminor.vo backend/RTL.vo $(ARCH)/Asm.vo driver/Compiler.vo common/Errors.vo -flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_float_prop.glob flocq/Core/Fcore_float_prop.v.beautified: flocq/Core/Fcore_float_prop.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo +flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_Raux.glob flocq/Core/Fcore_Raux.v.beautified: flocq/Core/Fcore_Raux.v flocq/Core/Fcore_Zaux.vo flocq/Core/Fcore_Zaux.vo flocq/Core/Fcore_Zaux.glob flocq/Core/Fcore_Zaux.v.beautified: flocq/Core/Fcore_Zaux.v -flocq/Core/Fcore_rnd_ne.vo flocq/Core/Fcore_rnd_ne.glob flocq/Core/Fcore_rnd_ne.v.beautified: flocq/Core/Fcore_rnd_ne.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_ulp.vo -flocq/Core/Fcore_FTZ.vo flocq/Core/Fcore_FTZ.glob flocq/Core/Fcore_FTZ.v.beautified: flocq/Core/Fcore_FTZ.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_FLX.vo -flocq/Core/Fcore_FLT.vo flocq/Core/Fcore_FLT.glob flocq/Core/Fcore_FLT.v.beautified: flocq/Core/Fcore_FLT.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_FLX.vo flocq/Core/Fcore_FIX.vo flocq/Core/Fcore_rnd_ne.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_defs.glob flocq/Core/Fcore_defs.v.beautified: flocq/Core/Fcore_defs.v flocq/Core/Fcore_Raux.vo -flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_Raux.glob flocq/Core/Fcore_Raux.v.beautified: flocq/Core/Fcore_Raux.v flocq/Core/Fcore_Zaux.vo -flocq/Core/Fcore_ulp.vo flocq/Core/Fcore_ulp.glob flocq/Core/Fcore_ulp.v.beautified: flocq/Core/Fcore_ulp.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_float_prop.vo -flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_rnd.glob flocq/Core/Fcore_rnd.v.beautified: flocq/Core/Fcore_rnd.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo -flocq/Core/Fcore_FLX.vo flocq/Core/Fcore_FLX.glob flocq/Core/Fcore_FLX.v.beautified: flocq/Core/Fcore_FLX.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_FIX.vo flocq/Core/Fcore_rnd_ne.vo -flocq/Core/Fcore_FIX.vo flocq/Core/Fcore_FIX.glob flocq/Core/Fcore_FIX.v.beautified: flocq/Core/Fcore_FIX.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_rnd_ne.vo flocq/Core/Fcore_digits.vo flocq/Core/Fcore_digits.glob flocq/Core/Fcore_digits.v.beautified: flocq/Core/Fcore_digits.v flocq/Core/Fcore_Zaux.vo +flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_float_prop.glob flocq/Core/Fcore_float_prop.v.beautified: flocq/Core/Fcore_float_prop.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo +flocq/Core/Fcore_FIX.vo flocq/Core/Fcore_FIX.glob flocq/Core/Fcore_FIX.v.beautified: flocq/Core/Fcore_FIX.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_rnd_ne.vo +flocq/Core/Fcore_FLT.vo flocq/Core/Fcore_FLT.glob flocq/Core/Fcore_FLT.v.beautified: flocq/Core/Fcore_FLT.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_FLX.vo flocq/Core/Fcore_FIX.vo flocq/Core/Fcore_rnd_ne.vo +flocq/Core/Fcore_FLX.vo flocq/Core/Fcore_FLX.glob flocq/Core/Fcore_FLX.v.beautified: flocq/Core/Fcore_FLX.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_FIX.vo flocq/Core/Fcore_rnd_ne.vo +flocq/Core/Fcore_FTZ.vo flocq/Core/Fcore_FTZ.glob flocq/Core/Fcore_FTZ.v.beautified: flocq/Core/Fcore_FTZ.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_FLX.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_generic_fmt.glob flocq/Core/Fcore_generic_fmt.v.beautified: flocq/Core/Fcore_generic_fmt.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_float_prop.vo +flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_rnd.glob flocq/Core/Fcore_rnd.v.beautified: flocq/Core/Fcore_rnd.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo +flocq/Core/Fcore_rnd_ne.vo flocq/Core/Fcore_rnd_ne.glob flocq/Core/Fcore_rnd_ne.v.beautified: flocq/Core/Fcore_rnd_ne.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_ulp.vo +flocq/Core/Fcore_ulp.vo flocq/Core/Fcore_ulp.glob flocq/Core/Fcore_ulp.v.beautified: flocq/Core/Fcore_ulp.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore.vo flocq/Core/Fcore.glob flocq/Core/Fcore.v.beautified: flocq/Core/Fcore.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_rnd.vo flocq/Core/Fcore_generic_fmt.vo flocq/Core/Fcore_rnd_ne.vo flocq/Core/Fcore_FIX.vo flocq/Core/Fcore_FLX.vo flocq/Core/Fcore_FLT.vo flocq/Core/Fcore_ulp.vo -flocq/Prop/Fprop_Sterbenz.vo flocq/Prop/Fprop_Sterbenz.glob flocq/Prop/Fprop_Sterbenz.v.beautified: flocq/Prop/Fprop_Sterbenz.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_generic_fmt.vo flocq/Calc/Fcalc_ops.vo -flocq/Prop/Fprop_mult_error.vo flocq/Prop/Fprop_mult_error.glob flocq/Prop/Fprop_mult_error.v.beautified: flocq/Prop/Fprop_mult_error.v flocq/Core/Fcore.vo flocq/Calc/Fcalc_ops.vo -flocq/Prop/Fprop_relative.vo flocq/Prop/Fprop_relative.glob flocq/Prop/Fprop_relative.v.beautified: flocq/Prop/Fprop_relative.v flocq/Core/Fcore.vo -flocq/Prop/Fprop_div_sqrt_error.vo flocq/Prop/Fprop_div_sqrt_error.glob flocq/Prop/Fprop_div_sqrt_error.v.beautified: flocq/Prop/Fprop_div_sqrt_error.v flocq/Core/Fcore.vo flocq/Calc/Fcalc_ops.vo flocq/Prop/Fprop_relative.vo -flocq/Prop/Fprop_plus_error.vo flocq/Prop/Fprop_plus_error.glob flocq/Prop/Fprop_plus_error.v.beautified: flocq/Prop/Fprop_plus_error.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_generic_fmt.vo flocq/Calc/Fcalc_ops.vo -flocq/Calc/Fcalc_ops.vo flocq/Calc/Fcalc_ops.glob flocq/Calc/Fcalc_ops.v.beautified: flocq/Calc/Fcalc_ops.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_float_prop.vo flocq/Calc/Fcalc_bracket.vo flocq/Calc/Fcalc_bracket.glob flocq/Calc/Fcalc_bracket.v.beautified: flocq/Calc/Fcalc_bracket.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_float_prop.vo -flocq/Calc/Fcalc_sqrt.vo flocq/Calc/Fcalc_sqrt.glob flocq/Calc/Fcalc_sqrt.v.beautified: flocq/Calc/Fcalc_sqrt.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_digits.vo flocq/Core/Fcore_float_prop.vo flocq/Calc/Fcalc_bracket.vo flocq/Calc/Fcalc_digits.vo +flocq/Calc/Fcalc_digits.vo flocq/Calc/Fcalc_digits.glob flocq/Calc/Fcalc_digits.v.beautified: flocq/Calc/Fcalc_digits.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_digits.vo flocq/Calc/Fcalc_div.vo flocq/Calc/Fcalc_div.glob flocq/Calc/Fcalc_div.v.beautified: flocq/Calc/Fcalc_div.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_digits.vo flocq/Calc/Fcalc_bracket.vo flocq/Calc/Fcalc_digits.vo +flocq/Calc/Fcalc_ops.vo flocq/Calc/Fcalc_ops.glob flocq/Calc/Fcalc_ops.v.beautified: flocq/Calc/Fcalc_ops.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_float_prop.vo flocq/Calc/Fcalc_round.vo flocq/Calc/Fcalc_round.glob flocq/Calc/Fcalc_round.v.beautified: flocq/Calc/Fcalc_round.v flocq/Core/Fcore.vo flocq/Core/Fcore_digits.vo flocq/Calc/Fcalc_bracket.vo flocq/Calc/Fcalc_digits.vo -flocq/Calc/Fcalc_digits.vo flocq/Calc/Fcalc_digits.glob flocq/Calc/Fcalc_digits.v.beautified: flocq/Calc/Fcalc_digits.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_digits.vo -flocq/Appli/Fappli_IEEE_bits.vo flocq/Appli/Fappli_IEEE_bits.glob flocq/Appli/Fappli_IEEE_bits.v.beautified: flocq/Appli/Fappli_IEEE_bits.v flocq/Core/Fcore.vo flocq/Core/Fcore_digits.vo flocq/Calc/Fcalc_digits.vo flocq/Appli/Fappli_IEEE.vo +flocq/Calc/Fcalc_sqrt.vo flocq/Calc/Fcalc_sqrt.glob flocq/Calc/Fcalc_sqrt.v.beautified: flocq/Calc/Fcalc_sqrt.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_digits.vo flocq/Core/Fcore_float_prop.vo flocq/Calc/Fcalc_bracket.vo flocq/Calc/Fcalc_digits.vo +flocq/Prop/Fprop_div_sqrt_error.vo flocq/Prop/Fprop_div_sqrt_error.glob flocq/Prop/Fprop_div_sqrt_error.v.beautified: flocq/Prop/Fprop_div_sqrt_error.v flocq/Core/Fcore.vo flocq/Calc/Fcalc_ops.vo flocq/Prop/Fprop_relative.vo +flocq/Prop/Fprop_mult_error.vo flocq/Prop/Fprop_mult_error.glob flocq/Prop/Fprop_mult_error.v.beautified: flocq/Prop/Fprop_mult_error.v flocq/Core/Fcore.vo flocq/Calc/Fcalc_ops.vo +flocq/Prop/Fprop_plus_error.vo flocq/Prop/Fprop_plus_error.glob flocq/Prop/Fprop_plus_error.v.beautified: flocq/Prop/Fprop_plus_error.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_float_prop.vo flocq/Core/Fcore_generic_fmt.vo flocq/Calc/Fcalc_ops.vo +flocq/Prop/Fprop_relative.vo flocq/Prop/Fprop_relative.glob flocq/Prop/Fprop_relative.v.beautified: flocq/Prop/Fprop_relative.v flocq/Core/Fcore.vo +flocq/Prop/Fprop_Sterbenz.vo flocq/Prop/Fprop_Sterbenz.glob flocq/Prop/Fprop_Sterbenz.v.beautified: flocq/Prop/Fprop_Sterbenz.v flocq/Core/Fcore_Raux.vo flocq/Core/Fcore_defs.vo flocq/Core/Fcore_generic_fmt.vo flocq/Calc/Fcalc_ops.vo +flocq/Appli/Fappli_rnd_odd.vo flocq/Appli/Fappli_rnd_odd.glob flocq/Appli/Fappli_rnd_odd.v.beautified: flocq/Appli/Fappli_rnd_odd.v flocq/Core/Fcore.vo flocq/Calc/Fcalc_ops.vo flocq/Appli/Fappli_IEEE.vo flocq/Appli/Fappli_IEEE.glob flocq/Appli/Fappli_IEEE.v.beautified: flocq/Appli/Fappli_IEEE.v flocq/Core/Fcore.vo flocq/Core/Fcore_digits.vo flocq/Calc/Fcalc_digits.vo flocq/Calc/Fcalc_round.vo flocq/Calc/Fcalc_bracket.vo flocq/Calc/Fcalc_ops.vo flocq/Calc/Fcalc_div.vo flocq/Calc/Fcalc_sqrt.vo flocq/Prop/Fprop_relative.vo +flocq/Appli/Fappli_IEEE_bits.vo flocq/Appli/Fappli_IEEE_bits.glob flocq/Appli/Fappli_IEEE_bits.v.beautified: flocq/Appli/Fappli_IEEE_bits.v flocq/Core/Fcore.vo flocq/Core/Fcore_digits.vo flocq/Calc/Fcalc_digits.vo flocq/Appli/Fappli_IEEE.vo exportclight/Clightdefs.vo exportclight/Clightdefs.glob exportclight/Clightdefs.v.beautified: exportclight/Clightdefs.v lib/Integers.vo lib/Floats.vo common/AST.vo cfrontend/Ctypes.vo cfrontend/Cop.vo cfrontend/Clight.vo @@ -1,6 +1,8 @@ Development trunk: ================== +- More precise modeling of not-a-numbers (NaNs) in floating-point + arithmetic. - Optimize integer divisions by positive constants, turning them into multiply-high and shifts. - Avoid double rounding issues in conversion from 64-bit integers @@ -50,20 +50,22 @@ VPATH=$(DIRS) GPATH=$(DIRS) # Flocq -FLOCQ_CORE=Fcore_float_prop.v Fcore_Zaux.v Fcore_rnd_ne.v Fcore_FTZ.v \ - Fcore_FLT.v Fcore_defs.v Fcore_Raux.v Fcore_ulp.v Fcore_rnd.v Fcore_FLX.v \ - Fcore_FIX.v Fcore_digits.v Fcore_generic_fmt.v Fcore.v -FLOCQ_PROP=Fprop_Sterbenz.v Fprop_mult_error.v Fprop_relative.v \ - Fprop_div_sqrt_error.v Fprop_plus_error.v -FLOCQ_CALC=Fcalc_ops.v Fcalc_bracket.v Fcalc_sqrt.v Fcalc_div.v Fcalc_round.v \ - Fcalc_digits.v -FLOCQ_APPLI=Fappli_IEEE_bits.v Fappli_IEEE.v -FLOCQ=$(FLOCQ_CORE) $(FLOCQ_PROP) $(FLOCQ_CALC) $(FLOCQ_APPLI) + +FLOCQ=\ + Fcore_Raux.v Fcore_Zaux.v Fcore_defs.v Fcore_digits.v \ + Fcore_float_prop.v Fcore_FIX.v Fcore_FLT.v Fcore_FLX.v \ + Fcore_FTZ.v Fcore_generic_fmt.v Fcore_rnd.v Fcore_rnd_ne.v \ + Fcore_ulp.v Fcore.v \ + Fcalc_bracket.v Fcalc_digits.v Fcalc_div.v Fcalc_ops.v \ + Fcalc_round.v Fcalc_sqrt.v \ + Fprop_div_sqrt_error.v Fprop_mult_error.v Fprop_plus_error.v \ + Fprop_relative.v Fprop_Sterbenz.v \ + Fappli_rnd_odd.v Fappli_IEEE.v Fappli_IEEE_bits.v # General-purpose libraries (in lib/) LIB=Axioms.v Coqlib.v Intv.v Maps.v Heaps.v Lattice.v Ordered.v \ - Iteration.v Integers.v Floats.v Parmov.v UnionFind.v Wfsimpl.v \ + Iteration.v Integers.v Floats.v Nan.v Parmov.v UnionFind.v Wfsimpl.v \ Postorder.v FSetAVLplus.v # Parts common to the front-ends and the back-end (in common/) diff --git a/arm/Nan.v b/arm/Nan.v new file mode 100644 index 0000000..d66d6ec --- /dev/null +++ b/arm/Nan.v @@ -0,0 +1,34 @@ +Require Import Fappli_IEEE. +Require Import Fappli_IEEE_bits. +Require Import Floats. +Require Import ZArith. +Require Import Integers. + +(* Needed to break a circular reference after extraction *) +Definition transform_quiet_pl := + Eval unfold Float.transform_quiet_pl in Float.transform_quiet_pl. + +Program Definition default_pl : bool * nan_pl 53 := (false, nat_iter 51 xO xH). + +Definition binop_pl (pl1 pl2:binary64) : bool*nan_pl 53 := + match pl1, pl2 with + | B754_nan s1 pl1, B754_nan s2 pl2 => + if (Pos.testbit (proj1_sig pl1) 51 && (* pl2 is sNan but pl1 is qNan *) + negb (Pos.testbit (proj1_sig pl2) 51))%bool + then (s2, transform_quiet_pl pl2) + else (s1, transform_quiet_pl pl1) + | B754_nan s1 pl1, _ => (s1, transform_quiet_pl pl1) + | _, B754_nan s2 pl2 => (s2, transform_quiet_pl pl2) + | _, _ => default_pl + end. + +Theorem binop_propagate1: Float.binop_propagate1_prop binop_pl. +Proof. + repeat intro. destruct f1, f2; try discriminate; simpl; + destruct Pos.testbit; reflexivity. +Qed. + +Theorem binop_propagate2: Float.binop_propagate2_prop binop_pl. +Proof. + repeat intro. destruct f1, f2, f3; try discriminate; simpl; reflexivity. +Qed. diff --git a/common/Values.v b/common/Values.v index 670f785..b9594fc 100644 --- a/common/Values.v +++ b/common/Values.v @@ -1051,11 +1051,6 @@ Proof. intros; destruct x; simpl; auto. decEq. apply Int.rolm_zero. Qed. -Theorem addf_commut: forall x y, addf x y = addf y x. -Proof. - destruct x; destruct y; simpl; auto. decEq. apply Float.addf_commut. -Qed. - Theorem negate_cmp_bool: forall c x y, cmp_bool (negate_comparison c) x y = option_map negb (cmp_bool c x y). Proof. diff --git a/extraction/extraction.v b/extraction/extraction.v index 6bc0234..ba1ca58 100644 --- a/extraction/extraction.v +++ b/extraction/extraction.v @@ -11,6 +11,7 @@ (* *********************************************************************) Require Wfsimpl. +Require Nan. Require AST. Require Iteration. Require Floats. @@ -30,6 +31,10 @@ Require Import ExtrOcamlString. (* Wfsimpl *) Extraction Inline Wfsimpl.Fix Wfsimpl.Fixm. +(* Floats *) +Extract Constant Floats.Float.binop_pl => + "Nan.binop_pl". + (* AST *) Extract Constant AST.ident_of_string => "fun s -> Camlcoq.intern_string (Camlcoq.camlstring_of_coqstring s)". @@ -129,6 +134,5 @@ Separate Extraction Conventions1.dummy_int_reg Conventions1.dummy_float_reg RTL.instr_defs RTL.instr_uses Machregs.mregs_for_operation Machregs.mregs_for_builtin - Machregs.two_address_op. - - + Machregs.two_address_op + Nan.binop_pl. diff --git a/flocq/Appli/Fappli_IEEE.v b/flocq/Appli/Fappli_IEEE.v index 63b150f..5e9897f 100644 --- a/flocq/Appli/Fappli_IEEE.v +++ b/flocq/Appli/Fappli_IEEE.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -33,7 +33,7 @@ Section AnyRadix. Inductive full_float := | F754_zero : bool -> full_float | F754_infinity : bool -> full_float - | F754_nan : full_float + | F754_nan : bool -> positive -> full_float | F754_finite : bool -> positive -> Z -> full_float. Definition FF2R beta x := @@ -67,16 +67,20 @@ Definition bounded m e := Definition valid_binary x := match x with | F754_finite _ m e => bounded m e + | F754_nan _ pl => (Z_of_nat' (S (digits2_Pnat pl)) <? prec)%Z | _ => true end. (** Basic type used for representing binary FP numbers. Note that there is exactly one such object per FP datum. NaNs do not have any payload. They cannot be distinguished. *) + +Definition nan_pl := {pl | (Z_of_nat' (S (digits2_Pnat pl)) <? prec)%Z = true}. + Inductive binary_float := | B754_zero : bool -> binary_float | B754_infinity : bool -> binary_float - | B754_nan : binary_float + | B754_nan : bool -> nan_pl -> binary_float | B754_finite : bool -> forall (m : positive) (e : Z), bounded m e = true -> binary_float. @@ -85,7 +89,7 @@ Definition FF2B x := | F754_finite s m e => B754_finite s m e | F754_infinity s => fun _ => B754_infinity s | F754_zero s => fun _ => B754_zero s - | F754_nan => fun _ => B754_nan + | F754_nan b pl => fun H => B754_nan b (exist _ pl H) end. Definition B2FF x := @@ -93,7 +97,7 @@ Definition B2FF x := | B754_finite s m e _ => F754_finite s m e | B754_infinity s => F754_infinity s | B754_zero s => F754_zero s - | B754_nan => F754_nan + | B754_nan b (exist pl _) => F754_nan b pl end. Definition radix2 := Build_radix 2 (refl_equal true). @@ -108,30 +112,30 @@ Theorem FF2R_B2FF : forall x, FF2R radix2 (B2FF x) = B2R x. Proof. -now intros [sx|sx| |sx mx ex Hx]. +now intros [sx|sx|sx [plx Hplx]|sx mx ex Hx]. Qed. Theorem B2FF_FF2B : forall x Hx, B2FF (FF2B x Hx) = x. Proof. -now intros [sx|sx| |sx mx ex] Hx. +now intros [sx|sx|sx plx|sx mx ex] Hx. Qed. Theorem valid_binary_B2FF : forall x, valid_binary (B2FF x) = true. Proof. -now intros [sx|sx| |sx mx ex Hx]. +now intros [sx|sx|sx [plx Hplx]|sx mx ex Hx]. Qed. Theorem FF2B_B2FF : forall x H, FF2B (B2FF x) H = x. Proof. -intros [sx|sx| |sx mx ex Hx] H ; try easy. -apply f_equal. -apply eqbool_irrelevance. +intros [sx|sx|sx [plx Hplx]|sx mx ex Hx] H ; try easy. +simpl. apply f_equal, f_equal, eqbool_irrelevance. +apply f_equal, eqbool_irrelevance. Qed. Theorem FF2B_B2FF_valid : @@ -146,7 +150,7 @@ Theorem B2R_FF2B : forall x Hx, B2R (FF2B x Hx) = FF2R radix2 x. Proof. -now intros [sx|sx| |sx mx ex] Hx. +now intros [sx|sx|sx plx|sx mx ex] Hx. Qed. Theorem match_FF2B : @@ -154,17 +158,17 @@ Theorem match_FF2B : match FF2B x Hx return T with | B754_zero sx => fz sx | B754_infinity sx => fi sx - | B754_nan => fn + | B754_nan b (exist p _) => fn b p | B754_finite sx mx ex _ => ff sx mx ex end = match x with | F754_zero sx => fz sx | F754_infinity sx => fi sx - | F754_nan => fn + | F754_nan b p => fn b p | F754_finite sx mx ex => ff sx mx ex end. Proof. -now intros T fz fi fn ff [sx|sx| |sx mx ex] Hx. +now intros T fz fi fn ff [sx|sx|sx plx|sx mx ex] Hx. Qed. Theorem canonic_canonic_mantissa : @@ -189,19 +193,28 @@ Theorem generic_format_B2R : forall x, generic_format radix2 fexp (B2R x). Proof. -intros [sx|sx| |sx mx ex Hx] ; try apply generic_format_0. +intros [sx|sx|sx plx|sx mx ex Hx] ; try apply generic_format_0. simpl. apply generic_format_canonic. apply canonic_canonic_mantissa. now destruct (andb_prop _ _ Hx) as (H, _). Qed. +Theorem FLT_format_B2R : + forall x, + FLT_format radix2 emin prec (B2R x). +Proof with auto with typeclass_instances. +intros x. +apply FLT_format_generic... +apply generic_format_B2R. +Qed. + Theorem B2FF_inj : forall x y : binary_float, B2FF x = B2FF y -> x = y. Proof. -intros [sx|sx| |sx mx ex Hx] [sy|sy| |sy my ey Hy] ; try easy. +intros [sx|sx|sx [plx Hplx]|sx mx ex Hx] [sy|sy|sy [ply Hply]|sy my ey Hy] ; try easy. (* *) intros H. now inversion H. @@ -212,11 +225,18 @@ now inversion H. intros H. inversion H. clear H. +revert Hplx. +rewrite H2. +intros Hx. +apply f_equal, f_equal, eqbool_irrelevance. +(* *) +intros H. +inversion H. +clear H. revert Hx. rewrite H2, H3. intros Hx. -apply f_equal. -apply eqbool_irrelevance. +apply f_equal, eqbool_irrelevance. Qed. Definition is_finite_strict f := @@ -265,6 +285,29 @@ apply f_equal. apply eqbool_irrelevance. Qed. +Definition Bsign x := + match x with + | B754_nan s _ => s + | B754_zero s => s + | B754_infinity s => s + | B754_finite s _ _ _ => s + end. + +Definition sign_FF x := + match x with + | F754_nan s _ => s + | F754_zero s => s + | F754_infinity s => s + | F754_finite s _ _ => s + end. + +Theorem Bsign_FF2B : + forall x H, + Bsign (FF2B x H) = sign_FF x. +Proof. +now intros [sx|sx|sx plx|sx mx ex] H. +Qed. + Definition is_finite f := match f with | B754_finite _ _ _ _ => true @@ -290,42 +333,93 @@ Theorem is_finite_FF_B2FF : forall x, is_finite_FF (B2FF x) = is_finite x. Proof. +now intros [| |? []|]. +Qed. + +Theorem B2R_Bsign_inj: + forall x y : binary_float, + is_finite x = true -> + is_finite y = true -> + B2R x = B2R y -> + Bsign x = Bsign y -> + x = y. +Proof. +intros. destruct x, y; try (apply B2R_inj; now eauto). +- simpl in H2. congruence. +- symmetry in H1. apply Rmult_integral in H1. + destruct H1. apply eq_Z2R with (n:=0%Z) in H1. destruct b0; discriminate H1. + simpl in H1. pose proof (bpow_gt_0 radix2 e). + rewrite H1 in H3. apply Rlt_irrefl in H3. destruct H3. +- apply Rmult_integral in H1. + destruct H1. apply eq_Z2R with (n:=0%Z) in H1. destruct b; discriminate H1. + simpl in H1. pose proof (bpow_gt_0 radix2 e). + rewrite H1 in H3. apply Rlt_irrefl in H3. destruct H3. +Qed. + +Definition is_nan f := + match f with + | B754_nan _ _ => true + | _ => false + end. + +Definition is_nan_FF f := + match f with + | F754_nan _ _ => true + | _ => false + end. + +Theorem is_nan_FF2B : + forall x Hx, + is_nan (FF2B x Hx) = is_nan_FF x. +Proof. now intros [| | |]. Qed. -Definition Bopp x := +Theorem is_nan_FF_B2FF : + forall x, + is_nan_FF (B2FF x) = is_nan x. +Proof. +now intros [| |? []|]. +Qed. + +Definition Bopp opp_nan x := match x with - | B754_nan => x + | B754_nan sx plx => + let '(sres, plres) := opp_nan sx plx in B754_nan sres plres | B754_infinity sx => B754_infinity (negb sx) | B754_finite sx mx ex Hx => B754_finite (negb sx) mx ex Hx | B754_zero sx => B754_zero (negb sx) end. Theorem Bopp_involutive : - forall x, Bopp (Bopp x) = x. + forall opp_nan x, + is_nan x = false -> + Bopp opp_nan (Bopp opp_nan x) = x. Proof. -now intros [sx|sx| |sx mx ex Hx] ; simpl ; try rewrite Bool.negb_involutive. +now intros opp_nan [sx|sx|sx plx|sx mx ex Hx] ; simpl ; try rewrite Bool.negb_involutive. Qed. Theorem B2R_Bopp : - forall x, - B2R (Bopp x) = (- B2R x)%R. + forall opp_nan x, + B2R (Bopp opp_nan x) = (- B2R x)%R. Proof. -intros [sx|sx| |sx mx ex Hx] ; apply sym_eq ; try apply Ropp_0. +intros opp_nan [sx|sx|sx plx|sx mx ex Hx]; apply sym_eq ; try apply Ropp_0. +simpl. destruct opp_nan. apply Ropp_0. simpl. rewrite <- F2R_opp. now case sx. Qed. - -Theorem is_finite_Bopp: forall x, - is_finite (Bopp x) = is_finite x. +Theorem is_finite_Bopp : + forall opp_nan x, + is_finite (Bopp opp_nan x) = is_finite x. Proof. -now intros [| | |]. +intros opp_nan [| | |] ; try easy. +intros s pl. +simpl. +now case opp_nan. Qed. - - Theorem bounded_lt_emax : forall mx ex, bounded mx ex = true -> @@ -361,7 +455,7 @@ Theorem abs_B2R_lt_emax : forall x, (Rabs (B2R x) < bpow radix2 emax)%R. Proof. -intros [sx|sx| |sx mx ex Hx] ; simpl ; try ( rewrite Rabs_R0 ; apply bpow_gt_0 ). +intros [sx|sx|sx plx|sx mx ex Hx] ; simpl ; try ( rewrite Rabs_R0 ; apply bpow_gt_0 ). rewrite <- F2R_Zabs, abs_cond_Zopp. now apply bounded_lt_emax. Qed. @@ -638,7 +732,7 @@ Definition binary_round_aux mode sx mx ex lx := match shr_m mrs'' with | Z0 => F754_zero sx | Zpos m => if Zle_bool e'' (emax - prec) then F754_finite sx m e'' else binary_overflow mode sx - | _ => F754_nan (* dummy *) + | _ => F754_nan false xH (* dummy *) end. Theorem binary_round_aux_correct : @@ -649,7 +743,7 @@ Theorem binary_round_aux_correct : valid_binary z = true /\ if Rlt_bool (Rabs (round radix2 fexp (round_mode mode) x)) (bpow radix2 emax) then FF2R radix2 z = round radix2 fexp (round_mode mode) x /\ - is_finite_FF z = true + is_finite_FF z = true /\ sign_FF z = Rlt_bool x 0 else z = binary_overflow mode (Rlt_bool x 0). Proof with auto with typeclass_instances. @@ -818,29 +912,6 @@ exact inbetween_int_UP_sign. exact inbetween_int_NA_sign. Qed. -Definition Bsign x := - match x with - | B754_nan => false - | B754_zero s => s - | B754_infinity s => s - | B754_finite s _ _ _ => s - end. - -Definition sign_FF x := - match x with - | F754_nan => false - | F754_zero s => s - | F754_infinity s => s - | F754_finite s _ _ => s - end. - -Theorem Bsign_FF2B : - forall x H, - Bsign (FF2B x H) = sign_FF x. -Proof. -now intros [sx|sx| |sx mx ex] H. -Qed. - (** Multiplication *) Lemma Bmult_correct_aux : @@ -851,7 +922,7 @@ Lemma Bmult_correct_aux : valid_binary z = true /\ if Rlt_bool (Rabs (round radix2 fexp (round_mode m) (x * y))) (bpow radix2 emax) then FF2R radix2 z = round radix2 fexp (round_mode m) (x * y) /\ - is_finite_FF z = true + is_finite_FF z = true /\ sign_FF z = xorb sx sy else z = binary_overflow m (xorb sx sy). Proof. @@ -896,15 +967,15 @@ apply Rlt_bool_false. now apply F2R_ge_0_compat. Qed. -Definition Bmult m x y := +Definition Bmult mult_nan m x y := + let f pl := B754_nan (fst pl) (snd pl) in match x, y with - | B754_nan, _ => x - | _, B754_nan => y + | B754_nan _ _, _ | _, B754_nan _ _ => f (mult_nan x y) | B754_infinity sx, B754_infinity sy => B754_infinity (xorb sx sy) | B754_infinity sx, B754_finite sy _ _ _ => B754_infinity (xorb sx sy) | B754_finite sx _ _ _, B754_infinity sy => B754_infinity (xorb sx sy) - | B754_infinity _, B754_zero _ => B754_nan - | B754_zero _, B754_infinity _ => B754_nan + | B754_infinity _, B754_zero _ => f (mult_nan x y) + | B754_zero _, B754_infinity _ => f (mult_nan x y) | B754_finite sx _ _ _, B754_zero sy => B754_zero (xorb sx sy) | B754_zero sx, B754_finite sy _ _ _ => B754_zero (xorb sx sy) | B754_zero sx, B754_zero sy => B754_zero (xorb sx sy) @@ -913,36 +984,40 @@ Definition Bmult m x y := end. Theorem Bmult_correct : - forall m x y, + forall mult_nan m x y, if Rlt_bool (Rabs (round radix2 fexp (round_mode m) (B2R x * B2R y))) (bpow radix2 emax) then - B2R (Bmult m x y) = round radix2 fexp (round_mode m) (B2R x * B2R y) /\ - is_finite (Bmult m x y) = andb (is_finite x) (is_finite y) + B2R (Bmult mult_nan m x y) = round radix2 fexp (round_mode m) (B2R x * B2R y) /\ + is_finite (Bmult mult_nan m x y) = andb (is_finite x) (is_finite y) /\ + (is_nan (Bmult mult_nan m x y) = false -> + Bsign (Bmult mult_nan m x y) = xorb (Bsign x) (Bsign y)) else - B2FF (Bmult m x y) = binary_overflow m (xorb (Bsign x) (Bsign y)). + B2FF (Bmult mult_nan m x y) = binary_overflow m (xorb (Bsign x) (Bsign y)). Proof. -intros m [sx|sx| |sx mx ex Hx] [sy|sy| |sy my ey Hy] ; - try ( rewrite ?Rmult_0_r, ?Rmult_0_l, round_0, Rabs_R0, Rlt_bool_true ; [ split ; apply refl_equal | apply bpow_gt_0 | auto with typeclass_instances ] ). +intros mult_nan m [sx|sx|sx plx|sx mx ex Hx] [sy|sy|sy ply|sy my ey Hy] ; + try ( rewrite ?Rmult_0_r, ?Rmult_0_l, round_0, Rabs_R0, Rlt_bool_true ; [ now repeat constructor | apply bpow_gt_0 | now auto with typeclass_instances ] ). simpl. case Bmult_correct_aux. intros H1. case Rlt_bool. -intros (H2, H3). +intros (H2, (H3, H4)). split. now rewrite B2R_FF2B. +split. now rewrite is_finite_FF2B. +rewrite Bsign_FF2B. auto. intros H2. now rewrite B2FF_FF2B. Qed. -Definition Bmult_FF m x y := +Definition Bmult_FF mult_nan m x y := + let f pl := F754_nan (fst pl) (snd pl) in match x, y with - | F754_nan, _ => x - | _, F754_nan => y + | F754_nan _ _, _ | _, F754_nan _ _ => f (mult_nan x y) | F754_infinity sx, F754_infinity sy => F754_infinity (xorb sx sy) | F754_infinity sx, F754_finite sy _ _ => F754_infinity (xorb sx sy) | F754_finite sx _ _, F754_infinity sy => F754_infinity (xorb sx sy) - | F754_infinity _, F754_zero _ => F754_nan - | F754_zero _, F754_infinity _ => F754_nan + | F754_infinity _, F754_zero _ => f (mult_nan x y) + | F754_zero _, F754_infinity _ => f (mult_nan x y) | F754_finite sx _ _, F754_zero sy => F754_zero (xorb sx sy) | F754_zero sx, F754_finite sy _ _ => F754_zero (xorb sx sy) | F754_zero sx, F754_zero sy => F754_zero (xorb sx sy) @@ -951,14 +1026,20 @@ Definition Bmult_FF m x y := end. Theorem B2FF_Bmult : + forall mult_nan mult_nan_ff, forall m x y, - B2FF (Bmult m x y) = Bmult_FF m (B2FF x) (B2FF y). + mult_nan_ff (B2FF x) (B2FF y) = (let '(sr, exist plr _) := mult_nan x y in (sr, plr)) -> + B2FF (Bmult mult_nan m x y) = Bmult_FF mult_nan_ff m (B2FF x) (B2FF y). Proof. -intros m [sx|sx| |sx mx ex Hx] [sy|sy| |sy my ey Hy] ; try easy. +intros mult_nan mult_nan_ff m x y Hmult_nan. +unfold Bmult_FF. rewrite Hmult_nan. +destruct x as [sx|sx|sx [plx Hplx]|sx mx ex Hx], y as [sy|sy|sy [ply Hply]|sy my ey Hy] ; + simpl; try match goal with |- context [mult_nan ?x ?y] => + destruct (mult_nan x y) as [? []] end; + try easy. apply B2FF_FF2B. Qed. - Definition shl_align mx ex ex' := match (ex' - ex)%Z with | Zneg d => (shift_pos d mx, ex') @@ -1049,7 +1130,8 @@ Theorem binary_round_correct : let x := F2R (Float radix2 (cond_Zopp sx (Zpos mx)) ex) in if Rlt_bool (Rabs (round radix2 fexp (round_mode m) x)) (bpow radix2 emax) then FF2R radix2 z = round radix2 fexp (round_mode m) x /\ - is_finite_FF z = true + is_finite_FF z = true /\ + sign_FF z = sx else z = binary_overflow m sx. Proof. @@ -1084,22 +1166,35 @@ Theorem binary_normalize_correct : forall m mx ex szero, if Rlt_bool (Rabs (round radix2 fexp (round_mode m) (F2R (Float radix2 mx ex)))) (bpow radix2 emax) then B2R (binary_normalize m mx ex szero) = round radix2 fexp (round_mode m) (F2R (Float radix2 mx ex)) /\ - is_finite (binary_normalize m mx ex szero) = true + is_finite (binary_normalize m mx ex szero) = true /\ + Bsign (binary_normalize m mx ex szero) = + match Rcompare (F2R (Float radix2 mx ex)) 0 with + | Eq => szero + | Lt => true + | Gt => false + end else B2FF (binary_normalize m mx ex szero) = binary_overflow m (Rlt_bool (F2R (Float radix2 mx ex)) 0). Proof with auto with typeclass_instances. intros m mx ez szero. destruct mx as [|mz|mz] ; simpl. rewrite F2R_0, round_0, Rabs_R0, Rlt_bool_true... +split... split... +rewrite Rcompare_Eq... apply bpow_gt_0. (* . mz > 0 *) generalize (binary_round_correct m false mz ez). simpl. case Rlt_bool_spec. -intros _ (Vz, (Rz, Rz')). +intros _ (Vz, (Rz, (Rz', Rz''))). split. now rewrite B2R_FF2B. +split. now rewrite is_finite_FF2B. +rewrite Bsign_FF2B, Rz''. +rewrite Rcompare_Gt... +apply F2R_gt_0_compat. +simpl. zify; omega. intros Hz' (Vz, Rz). rewrite B2FF_FF2B, Rz. apply f_equal. @@ -1110,10 +1205,15 @@ now apply F2R_ge_0_compat. generalize (binary_round_correct m true mz ez). simpl. case Rlt_bool_spec. -intros _ (Vz, (Rz, Rz')). +intros _ (Vz, (Rz, (Rz', Rz''))). split. now rewrite B2R_FF2B. +split. now rewrite is_finite_FF2B. +rewrite Bsign_FF2B, Rz''. +rewrite Rcompare_Lt... +apply F2R_lt_0_compat. +simpl. zify; omega. intros Hz' (Vz, Rz). rewrite B2FF_FF2B, Rz. apply f_equal. @@ -1123,12 +1223,12 @@ now apply F2R_lt_0_compat. Qed. (** Addition *) -Definition Bplus m x y := +Definition Bplus plus_nan m x y := + let f pl := B754_nan (fst pl) (snd pl) in match x, y with - | B754_nan, _ => x - | _, B754_nan => y + | B754_nan _ _, _ | _, B754_nan _ _ => f (plus_nan x y) | B754_infinity sx, B754_infinity sy => - if Bool.eqb sx sy then x else B754_nan + if Bool.eqb sx sy then x else f (plus_nan x y) | B754_infinity _, _ => x | _, B754_infinity _ => y | B754_zero sx, B754_zero sy => @@ -1143,28 +1243,47 @@ Definition Bplus m x y := end. Theorem Bplus_correct : - forall m x y, + forall plus_nan m x y, is_finite x = true -> is_finite y = true -> if Rlt_bool (Rabs (round radix2 fexp (round_mode m) (B2R x + B2R y))) (bpow radix2 emax) then - B2R (Bplus m x y) = round radix2 fexp (round_mode m) (B2R x + B2R y) /\ - is_finite (Bplus m x y) = true + B2R (Bplus plus_nan m x y) = round radix2 fexp (round_mode m) (B2R x + B2R y) /\ + is_finite (Bplus plus_nan m x y) = true /\ + Bsign (Bplus plus_nan m x y) = + match Rcompare (B2R x + B2R y) 0 with + | Eq => match m with mode_DN => orb (Bsign x) (Bsign y) + | _ => andb (Bsign x) (Bsign y) end + | Lt => true + | Gt => false + end else - (B2FF (Bplus m x y) = binary_overflow m (Bsign x) /\ Bsign x = Bsign y). + (B2FF (Bplus plus_nan m x y) = binary_overflow m (Bsign x) /\ Bsign x = Bsign y). Proof with auto with typeclass_instances. -intros m [sx|sx| |sx mx ex Hx] [sy|sy| |sy my ey Hy] Fx Fy ; try easy. +intros plus_nan m [sx|sx| |sx mx ex Hx] [sy|sy| |sy my ey Hy] Fx Fy ; try easy. (* *) rewrite Rplus_0_r, round_0, Rabs_R0, Rlt_bool_true... simpl. -case (Bool.eqb sx sy) ; try easy. -now case m. +rewrite Rcompare_Eq by auto. +destruct sx, sy; try easy; now case m. apply bpow_gt_0. (* *) rewrite Rplus_0_l, round_generic, Rlt_bool_true... +split... split... +simpl. unfold F2R. +erewrite <- Rmult_0_l, Rcompare_mult_r. +rewrite Rcompare_Z2R with (y:=0%Z). +destruct sy... +apply bpow_gt_0. apply abs_B2R_lt_emax. apply generic_format_B2R. (* *) rewrite Rplus_0_r, round_generic, Rlt_bool_true... +split... split... +simpl. unfold F2R. +erewrite <- Rmult_0_l, Rcompare_mult_r. +rewrite Rcompare_Z2R with (y:=0%Z). +destruct sx... +apply bpow_gt_0. apply abs_B2R_lt_emax. apply generic_format_B2R. (* *) @@ -1264,7 +1383,19 @@ now apply F2R_le_0_compat. (* . *) generalize (binary_normalize_correct m mz ez szero). case Rlt_bool_spec. -easy. +split; try easy. split; try easy. +destruct (Rcompare_spec (F2R (beta:=radix2) {| Fnum := mz; Fexp := ez |}) 0); try easy. +rewrite H1 in Hp. +apply Rplus_opp_r_uniq in Hp. +rewrite <- F2R_Zopp in Hp. +eapply canonic_unicity in Hp. +inversion Hp. destruct sy, sx, m; try discriminate H3; easy. +apply canonic_canonic_mantissa. +apply Bool.andb_true_iff in Hy. easy. +replace (-cond_Zopp sx (Z.pos mx))%Z with (cond_Zopp (negb sx) (Z.pos mx)) + by (destruct sx; auto). +apply canonic_canonic_mantissa. +apply Bool.andb_true_iff in Hx. easy. intros Hz' Vz. specialize (Sz Hz'). split. @@ -1273,26 +1404,32 @@ now apply f_equal. apply Sz. Qed. -Definition Bminus m x y := Bplus m x (Bopp y). +Definition Bminus minus_nan m x y := Bplus minus_nan m x (Bopp pair y). Theorem Bminus_correct : - forall m x y, + forall minus_nan m x y, is_finite x = true -> is_finite y = true -> if Rlt_bool (Rabs (round radix2 fexp (round_mode m) (B2R x - B2R y))) (bpow radix2 emax) then - B2R (Bminus m x y) = round radix2 fexp (round_mode m) (B2R x - B2R y) /\ - is_finite (Bminus m x y) = true + B2R (Bminus minus_nan m x y) = round radix2 fexp (round_mode m) (B2R x - B2R y) /\ + is_finite (Bminus minus_nan m x y) = true /\ + Bsign (Bminus minus_nan m x y) = + match Rcompare (B2R x - B2R y) 0 with + | Eq => match m with mode_DN => orb (Bsign x) (negb (Bsign y)) + | _ => andb (Bsign x) (negb (Bsign y)) end + | Lt => true + | Gt => false + end else - (B2FF (Bminus m x y) = binary_overflow m (Bsign x) /\ Bsign x = negb (Bsign y)). + (B2FF (Bminus minus_nan m x y) = binary_overflow m (Bsign x) /\ Bsign x = negb (Bsign y)). Proof with auto with typeclass_instances. -intros m x y Fx Fy. -replace (negb (Bsign y)) with (Bsign (Bopp y)). +intros m minus_nan x y Fx Fy. +replace (negb (Bsign y)) with (Bsign (Bopp pair y)). unfold Rminus. -rewrite <- B2R_Bopp. +erewrite <- B2R_Bopp. apply Bplus_correct. exact Fx. -now rewrite is_finite_Bopp. -now destruct y as [ | | | ]. +rewrite is_finite_Bopp. auto. now destruct y as [ | | | ]. Qed. (** Division *) @@ -1316,12 +1453,12 @@ Lemma Bdiv_correct_aux : let '(mz, ez, lz) := Fdiv_core_binary (Zpos mx) ex (Zpos my) ey in match mz with | Zpos mz => binary_round_aux m (xorb sx sy) mz ez lz - | _ => F754_nan (* dummy *) + | _ => F754_nan false xH (* dummy *) end in valid_binary z = true /\ if Rlt_bool (Rabs (round radix2 fexp (round_mode m) (x / y))) (bpow radix2 emax) then FF2R radix2 z = round radix2 fexp (round_mode m) (x / y) /\ - is_finite_FF z = true + is_finite_FF z = true /\ sign_FF z = xorb sx sy else z = binary_overflow m (xorb sx sy). Proof. @@ -1406,45 +1543,49 @@ apply Rinv_0_lt_compat. now apply F2R_gt_0_compat. Qed. -Definition Bdiv m x y := +Definition Bdiv div_nan m x y := + let f pl := B754_nan (fst pl) (snd pl) in match x, y with - | B754_nan, _ => x - | _, B754_nan => y - | B754_infinity sx, B754_infinity sy => B754_nan + | B754_nan _ _, _ | _, B754_nan _ _ => f (div_nan x y) + | B754_infinity sx, B754_infinity sy => f (div_nan x y) | B754_infinity sx, B754_finite sy _ _ _ => B754_infinity (xorb sx sy) | B754_finite sx _ _ _, B754_infinity sy => B754_zero (xorb sx sy) | B754_infinity sx, B754_zero sy => B754_infinity (xorb sx sy) | B754_zero sx, B754_infinity sy => B754_zero (xorb sx sy) | B754_finite sx _ _ _, B754_zero sy => B754_infinity (xorb sx sy) | B754_zero sx, B754_finite sy _ _ _ => B754_zero (xorb sx sy) - | B754_zero sx, B754_zero sy => B754_nan + | B754_zero sx, B754_zero sy => f (div_nan x y) | B754_finite sx mx ex _, B754_finite sy my ey _ => FF2B _ (proj1 (Bdiv_correct_aux m sx mx ex sy my ey)) end. Theorem Bdiv_correct : - forall m x y, + forall div_nan m x y, B2R y <> R0 -> if Rlt_bool (Rabs (round radix2 fexp (round_mode m) (B2R x / B2R y))) (bpow radix2 emax) then - B2R (Bdiv m x y) = round radix2 fexp (round_mode m) (B2R x / B2R y) /\ - is_finite (Bdiv m x y) = is_finite x + B2R (Bdiv div_nan m x y) = round radix2 fexp (round_mode m) (B2R x / B2R y) /\ + is_finite (Bdiv div_nan m x y) = is_finite x /\ + (is_nan (Bdiv div_nan m x y) = false -> + Bsign (Bdiv div_nan m x y) = xorb (Bsign x) (Bsign y)) else - B2FF (Bdiv m x y) = binary_overflow m (xorb (Bsign x) (Bsign y)). + B2FF (Bdiv div_nan m x y) = binary_overflow m (xorb (Bsign x) (Bsign y)). Proof. -intros m x [sy|sy| |sy my ey Hy] Zy ; try now elim Zy. +intros div_nan m x [sy|sy|sy ply|sy my ey Hy] Zy ; try now elim Zy. revert x. unfold Rdiv. -intros [sx|sx| |sx mx ex Hx] ; - try ( rewrite Rmult_0_l, round_0, Rabs_R0, Rlt_bool_true ; [ split ; apply refl_equal | apply bpow_gt_0 | auto with typeclass_instances ] ). +intros [sx|sx|sx plx|sx mx ex Hx] ; + try ( rewrite Rmult_0_l, round_0, Rabs_R0, Rlt_bool_true ; [ now repeat constructor | apply bpow_gt_0 | auto with typeclass_instances ] ). simpl. case Bdiv_correct_aux. intros H1. unfold Rdiv. case Rlt_bool. -intros (H2, H3). +intros (H2, (H3, H4)). split. now rewrite B2R_FF2B. +split. now rewrite is_finite_FF2B. +rewrite Bsign_FF2B. congruence. intros H2. now rewrite B2FF_FF2B. Qed. @@ -1473,11 +1614,11 @@ Lemma Bsqrt_correct_aux : let '(mz, ez, lz) := Fsqrt_core_binary (Zpos mx) ex in match mz with | Zpos mz => binary_round_aux m false mz ez lz - | _ => F754_nan (* dummy *) + | _ => F754_nan false xH (* dummy *) end in valid_binary z = true /\ FF2R radix2 z = round radix2 fexp (round_mode m) (sqrt x) /\ - is_finite_FF z = true. + is_finite_FF z = true /\ sign_FF z = false. Proof with auto with typeclass_instances. intros m mx ex Hx. replace (Fsqrt_core_binary (Zpos mx) ex) with (Fsqrt_core radix2 prec (Zpos mx) ex). @@ -1578,28 +1719,30 @@ now case mz. apply sqrt_ge_0. Qed. -Definition Bsqrt m x := +Definition Bsqrt sqrt_nan m x := + let f pl := B754_nan (fst pl) (snd pl) in match x with - | B754_nan => x + | B754_nan sx plx => f (sqrt_nan x) | B754_infinity false => x - | B754_infinity true => B754_nan - | B754_finite true _ _ _ => B754_nan + | B754_infinity true => f (sqrt_nan x) + | B754_finite true _ _ _ => f (sqrt_nan x) | B754_zero _ => x | B754_finite sx mx ex Hx => FF2B _ (proj1 (Bsqrt_correct_aux m mx ex Hx)) end. Theorem Bsqrt_correct : - forall m x, - B2R (Bsqrt m x) = round radix2 fexp (round_mode m) (sqrt (B2R x)) /\ - is_finite (Bsqrt m x) = match x with B754_zero _ => true | B754_finite false _ _ _ => true | _ => false end. + forall sqrt_nan m x, + B2R (Bsqrt sqrt_nan m x) = round radix2 fexp (round_mode m) (sqrt (B2R x)) /\ + is_finite (Bsqrt sqrt_nan m x) = match x with B754_zero _ => true | B754_finite false _ _ _ => true | _ => false end /\ + (is_nan (Bsqrt sqrt_nan m x) = false -> Bsign (Bsqrt sqrt_nan m x) = Bsign x). Proof. -intros m [sx|[|]| |sx mx ex Hx] ; try ( now simpl ; rewrite sqrt_0, round_0 ; auto with typeclass_instances ). +intros sqrt_nan m [sx|[|]| |sx mx ex Hx] ; try ( now simpl ; rewrite sqrt_0, round_0 ; intuition auto with typeclass_instances ). simpl. case Bsqrt_correct_aux. -intros H1 (H2, H3). +intros H1 (H2, (H3, H4)). case sx. -refine (conj _ (refl_equal false)). +refine (conj _ (conj (refl_equal false) _)). apply sym_eq. unfold sqrt. case Rcase_abs. @@ -1609,9 +1752,12 @@ auto with typeclass_instances. intros H. elim Rge_not_lt with (1 := H). now apply F2R_lt_0_compat. +easy. split. now rewrite B2R_FF2B. +split. now rewrite is_finite_FF2B. +intro. rewrite Bsign_FF2B. auto. Qed. End Binary. diff --git a/flocq/Appli/Fappli_IEEE_bits.v b/flocq/Appli/Fappli_IEEE_bits.v index 06ed21e..a41fba9 100644 --- a/flocq/Appli/Fappli_IEEE_bits.v +++ b/flocq/Appli/Fappli_IEEE_bits.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2011 Sylvie Boldo +Copyright (C) 2011-2013 Sylvie Boldo #<br /># -Copyright (C) 2011 Guillaume Melquiond +Copyright (C) 2011-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -172,7 +172,7 @@ Definition bits_of_binary_float (x : binary_float) := match x with | B754_zero sx => join_bits sx 0 0 | B754_infinity sx => join_bits sx 0 (Zpower 2 ew - 1) - | B754_nan => join_bits false (Zpower 2 mw - 1) (Zpower 2 ew - 1) + | B754_nan sx (exist plx _) => join_bits sx (Zpos plx) (Zpower 2 ew - 1) | B754_finite sx mx ex _ => if Zle_bool (Zpower 2 mw) (Zpos mx) then join_bits sx (Zpos mx - Zpower 2 mw) (ex - emin + 1) @@ -184,7 +184,7 @@ Definition split_bits_of_binary_float (x : binary_float) := match x with | B754_zero sx => (sx, 0, 0)%Z | B754_infinity sx => (sx, 0, Zpower 2 ew - 1)%Z - | B754_nan => (false, Zpower 2 mw - 1, Zpower 2 ew - 1)%Z + | B754_nan sx (exist plx _) => (sx, Zpos plx, Zpower 2 ew - 1)%Z | B754_finite sx mx ex _ => if Zle_bool (Zpower 2 mw) (Zpos mx) then (sx, Zpos mx - Zpower 2 mw, ex - emin + 1)%Z @@ -196,8 +196,16 @@ Theorem split_bits_of_binary_float_correct : forall x, split_bits (bits_of_binary_float x) = split_bits_of_binary_float x. Proof. -intros [sx|sx| |sx mx ex Hx] ; +intros [sx|sx|sx [plx Hplx]|sx mx ex Hx] ; try ( simpl ; apply split_join_bits ; split ; try apply Zle_refl ; try apply Zlt_pred ; trivial ; omega ). +simpl. apply split_join_bits; split; try (zify; omega). +destruct (digits2_Pnat_correct plx). +rewrite Zpower_nat_Z in H0. +eapply Zlt_le_trans. apply H0. +change 2%Z with (radix_val radix2). apply Zpower_le. +rewrite Z.ltb_lt in Hplx. +unfold prec in *. zify; omega. +(* *) unfold bits_of_binary_float, split_bits_of_binary_float. assert (Hf: (emin <= ex /\ Zdigits radix2 (Zpos mx) <= prec)%Z). destruct (andb_prop _ _ Hx) as (Hx', _). @@ -246,14 +254,18 @@ Definition binary_float_of_bits_aux x := match mx with | Z0 => F754_zero sx | Zpos px => F754_finite sx px emin - | Zneg _ => F754_nan (* dummy *) + | Zneg _ => F754_nan false xH (* dummy *) end else if Zeq_bool ex (Zpower 2 ew - 1) then - if Zeq_bool mx 0 then F754_infinity sx else F754_nan + match mx with + | Z0 => F754_infinity sx + | Zpos plx => F754_nan sx plx + | Zneg _ => F754_nan false xH (* dummy *) + end else match (mx + Zpower 2 mw)%Z with | Zpos px => F754_finite sx px (ex + emin - 1) - | _ => F754_nan (* dummy *) + | _ => F754_nan false xH (* dummy *) end. Lemma binary_float_of_bits_aux_correct : @@ -292,9 +304,20 @@ cut (0 < emax)%Z. clear -H Hew ; omega. apply (Zpower_gt_0 radix2). clear -Hew ; omega. apply bpow_gt_0. +simpl. intros. rewrite Z.ltb_lt. unfold prec. zify; omega. case Zeq_bool_spec ; intros He2. -now case Zeq_bool. +case_eq (x mod 2 ^ mw)%Z; try easy. +(* nan *) +intros plx Eqplx. apply Z.ltb_lt. +rewrite Z_of_nat_S_digits2_Pnat. +assert (forall a b, a <= b -> a < b+1)%Z by (intros; omega). apply H. clear H. +apply Zdigits_le_Zpower. simpl. +rewrite <- Eqplx. edestruct Z_mod_lt; eauto. +change 2%Z with (radix_val radix2). +apply Z.lt_gt, Zpower_gt_0. omega. +simpl. intros. rewrite Z.ltb_lt. unfold prec. zify; omega. case_eq (x mod 2^mw + 2^mw)%Z ; try easy. +simpl. intros. rewrite Z.ltb_lt. unfold prec. zify; omega. (* normal *) intros px Hm. assert (prec = Zdigits radix2 (Zpos px)). @@ -365,6 +388,7 @@ apply Zlt_gt. apply (Zpower_gt_0 radix2). now apply Zlt_le_weak. apply bpow_gt_0. +simpl. intros. rewrite Z.ltb_lt. unfold prec. zify; omega. Qed. Definition binary_float_of_bits x := @@ -380,7 +404,7 @@ unfold binary_float_of_bits. rewrite B2FF_FF2B. unfold binary_float_of_bits_aux. rewrite split_bits_of_binary_float_correct. -destruct x as [sx|sx| |sx mx ex Bx]. +destruct x as [sx|sx|sx [plx Hplx]|sx mx ex Bx]. apply refl_equal. (* *) simpl. @@ -391,12 +415,7 @@ now apply (Zpower_gt_1 radix2). (* *) simpl. rewrite Zeq_bool_false. -rewrite Zeq_bool_true. -rewrite Zeq_bool_false. -apply refl_equal. -cut (1 < 2^mw)%Z. clear ; omega. -now apply (Zpower_gt_1 radix2). -apply refl_equal. +rewrite Zeq_bool_true; auto. cut (1 < 2^ew)%Z. clear ; omega. now apply (Zpower_gt_1 radix2). (* *) @@ -442,7 +461,6 @@ Qed. Theorem bits_of_binary_float_of_bits : forall x, (0 <= x < 2^(mw+ew+1))%Z -> - binary_float_of_bits x <> B754_nan prec emax -> bits_of_binary_float (binary_float_of_bits x) = x. Proof. intros x Hx. @@ -462,28 +480,28 @@ now apply Zlt_gt. case Zeq_bool_spec ; intros He1. (* subnormal *) case_eq mx. -intros Hm Jx _ _. +intros Hm Jx _. now rewrite He1 in Jx. -intros px Hm Jx _ _. +intros px Hm Jx _. rewrite Zle_bool_false. now rewrite <- He1. now rewrite <- Hm. -intros px Hm _ _ _. +intros px Hm _ _. apply False_ind. apply Zle_not_lt with (1 := proj1 Bm). now rewrite Hm. case Zeq_bool_spec ; intros He2. (* infinity/nan *) -case Zeq_bool_spec ; intros Hm. -now rewrite Hm, He2. -intros _ Cx Nx. -now elim Nx. +case_eq mx; intros Hm. +now rewrite He2. +now rewrite He2. +intros. zify; omega. (* normal *) case_eq (mx + 2 ^ mw)%Z. intros Hm. apply False_ind. clear -Bm Hm ; omega. -intros p Hm Jx Cx _. +intros p Hm Jx Cx. rewrite <- Hm. rewrite Zle_bool_true. now ring_simplify (mx + 2^mw - 2^mw)%Z (ex + emin - 1 - emin + 1)%Z. diff --git a/flocq/Appli/Fappli_rnd_odd.v b/flocq/Appli/Fappli_rnd_odd.v new file mode 100644 index 0000000..b4a2c52 --- /dev/null +++ b/flocq/Appli/Fappli_rnd_odd.v @@ -0,0 +1,979 @@ +(** +This file is part of the Flocq formalization of floating-point +arithmetic in Coq: http://flocq.gforge.inria.fr/ + +Copyright (C) 2010-2013 Sylvie Boldo +#<br /># +Copyright (C) 2010-2013 Guillaume Melquiond + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 3 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +COPYING file for more details. +*) + +(** * Rounding to odd and its properties, including the equivalence + between rnd_NE and double rounding with rnd_odd and then rnd_NE *) + + +Require Import Fcore. +Require Import Fcalc_ops. + +Definition Zrnd_odd x := match Req_EM_T x (Z2R (Zfloor x)) with + | left _ => Zfloor x + | right _ => match (Zeven (Zfloor x)) with + | true => Zceil x + | false => Zfloor x + end + end. + + + +Global Instance valid_rnd_odd : Valid_rnd Zrnd_odd. +Proof. +split. +(* . *) +intros x y Hxy. +assert (Zfloor x <= Zrnd_odd y)%Z. +(* .. *) +apply Zle_trans with (Zfloor y). +now apply Zfloor_le. +unfold Zrnd_odd; destruct (Req_EM_T y (Z2R (Zfloor y))). +now apply Zle_refl. +case (Zeven (Zfloor y)). +apply le_Z2R. +apply Rle_trans with y. +apply Zfloor_lb. +apply Zceil_ub. +now apply Zle_refl. +unfold Zrnd_odd at 1. +(* . *) +destruct (Req_EM_T x (Z2R (Zfloor x))) as [Hx|Hx]. +(* .. *) +apply H. +(* .. *) +case_eq (Zeven (Zfloor x)); intros Hx2. +2: apply H. +unfold Zrnd_odd; destruct (Req_EM_T y (Z2R (Zfloor y))) as [Hy|Hy]. +apply Zceil_glb. +now rewrite <- Hy. +case_eq (Zeven (Zfloor y)); intros Hy2. +now apply Zceil_le. +apply Zceil_glb. +assert (H0:(Zfloor x <= Zfloor y)%Z) by now apply Zfloor_le. +case (Zle_lt_or_eq _ _ H0); intros H1. +apply Rle_trans with (1:=Zceil_ub _). +rewrite Zceil_floor_neq. +apply Z2R_le; omega. +now apply sym_not_eq. +contradict Hy2. +rewrite <- H1, Hx2; discriminate. +(* . *) +intros n; unfold Zrnd_odd. +rewrite Zfloor_Z2R, Zceil_Z2R. +destruct (Req_EM_T (Z2R n) (Z2R n)); trivial. +case (Zeven n); trivial. +Qed. + + + +Lemma Zrnd_odd_Zodd: forall x, x <> (Z2R (Zfloor x)) -> + (Zeven (Zrnd_odd x)) = false. +Proof. +intros x Hx; unfold Zrnd_odd. +destruct (Req_EM_T x (Z2R (Zfloor x))) as [H|H]. +now contradict H. +case_eq (Zeven (Zfloor x)). +(* difficult case *) +intros H'. +rewrite Zceil_floor_neq. +rewrite Zeven_plus, H'. +reflexivity. +now apply sym_not_eq. +trivial. +Qed. + + + + +Section Fcore_rnd_odd. + +Variable beta : radix. + +Notation bpow e := (bpow beta e). + +Variable fexp : Z -> Z. + +Context { valid_exp : Valid_exp fexp }. +Context { exists_NE_ : Exists_NE beta fexp }. + +Notation format := (generic_format beta fexp). +Notation canonic := (canonic beta fexp). +Notation cexp := (canonic_exp beta fexp). + + +Definition Rnd_odd_pt (x f : R) := + format f /\ ((f = x)%R \/ + ((Rnd_DN_pt format x f \/ Rnd_UP_pt format x f) /\ + exists g : float beta, f = F2R g /\ canonic g /\ Zeven (Fnum g) = false)). + +Definition Rnd_odd (rnd : R -> R) := + forall x : R, Rnd_odd_pt x (rnd x). + + +Theorem Rnd_odd_pt_sym : forall x f : R, + Rnd_odd_pt (-x) (-f) -> Rnd_odd_pt x f. +Proof with auto with typeclass_instances. +intros x f (H1,H2). +split. +replace f with (-(-f))%R by ring. +now apply generic_format_opp. +destruct H2. +left. +replace f with (-(-f))%R by ring. +rewrite H; ring. +right. +destruct H as (H2,(g,(Hg1,(Hg2,Hg3)))). +split. +destruct H2. +right. +replace f with (-(-f))%R by ring. +replace x with (-(-x))%R by ring. +apply Rnd_DN_UP_pt_sym... +apply generic_format_opp. +left. +replace f with (-(-f))%R by ring. +replace x with (-(-x))%R by ring. +apply Rnd_UP_DN_pt_sym... +apply generic_format_opp. +exists (Float beta (-Fnum g) (Fexp g)). +split. +rewrite F2R_Zopp. +replace f with (-(-f))%R by ring. +rewrite Hg1; reflexivity. +split. +now apply canonic_opp. +simpl. +now rewrite Zeven_opp. +Qed. + + +Theorem round_odd_opp : + forall x, + (round beta fexp Zrnd_odd (-x) = (- round beta fexp Zrnd_odd x))%R. +Proof. +intros x; unfold round. +rewrite <- F2R_Zopp. +unfold F2R; simpl. +apply f_equal2; apply f_equal. +rewrite scaled_mantissa_opp. +generalize (scaled_mantissa beta fexp x); intros r. +unfold Zrnd_odd. +case (Req_EM_T (- r) (Z2R (Zfloor (- r)))). +case (Req_EM_T r (Z2R (Zfloor r))). +intros Y1 Y2. +apply eq_Z2R. +now rewrite Z2R_opp, <- Y1, <-Y2. +intros Y1 Y2. +absurd (r=Z2R (Zfloor r)); trivial. +pattern r at 2; replace r with (-(-r))%R by ring. +rewrite Y2, <- Z2R_opp. +rewrite Zfloor_Z2R. +rewrite Z2R_opp, <- Y2. +ring. +case (Req_EM_T r (Z2R (Zfloor r))). +intros Y1 Y2. +absurd (-r=Z2R (Zfloor (-r)))%R; trivial. +pattern r at 2; rewrite Y1. +rewrite <- Z2R_opp, Zfloor_Z2R. +now rewrite Z2R_opp, <- Y1. +intros Y1 Y2. +unfold Zceil; rewrite Ropp_involutive. +replace (Zeven (Zfloor (- r))) with (negb (Zeven (Zfloor r))). +case (Zeven (Zfloor r)); simpl; ring. +apply trans_eq with (Zeven (Zceil r)). +rewrite Zceil_floor_neq. +rewrite Zeven_plus. +simpl; reflexivity. +now apply sym_not_eq. +rewrite <- (Zeven_opp (Zfloor (- r))). +reflexivity. +apply canonic_exp_opp. +Qed. + + + +Theorem round_odd_pt : + forall x, + Rnd_odd_pt x (round beta fexp Zrnd_odd x). +Proof with auto with typeclass_instances. +cut (forall x : R, (0 < x)%R -> Rnd_odd_pt x (round beta fexp Zrnd_odd x)). +intros H x; case (Rle_or_lt 0 x). +intros H1; destruct H1. +now apply H. +rewrite <- H0. +rewrite round_0... +split. +apply generic_format_0. +now left. +intros Hx; apply Rnd_odd_pt_sym. +rewrite <- round_odd_opp. +apply H. +auto with real. +(* *) +intros x Hxp. +generalize (generic_format_round beta fexp Zrnd_odd x). +set (o:=round beta fexp Zrnd_odd x). +intros Ho. +split. +assumption. +(* *) +case (Req_dec o x); intros Hx. +now left. +right. +assert (o=round beta fexp Zfloor x \/ o=round beta fexp Zceil x). +unfold o, round, F2R;simpl. +case (Zrnd_DN_or_UP Zrnd_odd (scaled_mantissa beta fexp x))... +intros H; rewrite H; now left. +intros H; rewrite H; now right. +split. +destruct H; rewrite H. +left; apply round_DN_pt... +right; apply round_UP_pt... +(* *) +unfold o, Zrnd_odd, round. +case (Req_EM_T (scaled_mantissa beta fexp x) + (Z2R (Zfloor (scaled_mantissa beta fexp x)))). +intros T. +absurd (o=x); trivial. +apply round_generic... +unfold generic_format, F2R; simpl. +rewrite <- (scaled_mantissa_mult_bpow beta fexp) at 1. +apply f_equal2; trivial; rewrite T at 1. +apply f_equal, sym_eq, Ztrunc_floor. +apply Rmult_le_pos. +now left. +apply bpow_ge_0. +intros L. +case_eq (Zeven (Zfloor (scaled_mantissa beta fexp x))). +(* . *) +generalize (generic_format_round beta fexp Zceil x). +unfold generic_format. +set (f:=round beta fexp Zceil x). +set (ef := canonic_exp beta fexp f). +set (mf := Ztrunc (scaled_mantissa beta fexp f)). +exists (Float beta mf ef). +unfold Fcore_generic_fmt.canonic. +rewrite <- H0. +repeat split; try assumption. +apply trans_eq with (negb (Zeven (Zfloor (scaled_mantissa beta fexp x)))). +2: rewrite H1; reflexivity. +apply trans_eq with (negb (Zeven (Fnum + (Float beta (Zfloor (scaled_mantissa beta fexp x)) (cexp x))))). +2: reflexivity. +case (Rle_lt_or_eq_dec 0 (round beta fexp Zfloor x)). +rewrite <- round_0 with beta fexp Zfloor... +apply round_le... +now left. +intros Y. +generalize (DN_UP_parity_generic beta fexp)... +unfold DN_UP_parity_prop. +intros T; apply T with x; clear T. +unfold generic_format. +rewrite <- (scaled_mantissa_mult_bpow beta fexp x) at 1. +unfold F2R; simpl. +apply Rmult_neq_compat_r. +apply Rgt_not_eq, bpow_gt_0. +rewrite Ztrunc_floor. +assumption. +apply Rmult_le_pos. +now left. +apply bpow_ge_0. +unfold Fcore_generic_fmt.canonic. +simpl. +apply sym_eq, canonic_exp_DN... +unfold Fcore_generic_fmt.canonic. +rewrite <- H0; reflexivity. +reflexivity. +apply trans_eq with (round beta fexp Ztrunc (round beta fexp Zceil x)). +reflexivity. +apply round_generic... +intros Y. +replace (Fnum {| Fnum := Zfloor (scaled_mantissa beta fexp x); Fexp := cexp x |}) + with (Fnum (Float beta 0 (fexp (ln_beta beta 0)))). +generalize (DN_UP_parity_generic beta fexp)... +unfold DN_UP_parity_prop. +intros T; apply T with x; clear T. +unfold generic_format. +rewrite <- (scaled_mantissa_mult_bpow beta fexp x) at 1. +unfold F2R; simpl. +apply Rmult_neq_compat_r. +apply Rgt_not_eq, bpow_gt_0. +rewrite Ztrunc_floor. +assumption. +apply Rmult_le_pos. +now left. +apply bpow_ge_0. +apply canonic_0. +unfold Fcore_generic_fmt.canonic. +rewrite <- H0; reflexivity. +rewrite <- Y; unfold F2R; simpl; ring. +apply trans_eq with (round beta fexp Ztrunc (round beta fexp Zceil x)). +reflexivity. +apply round_generic... +simpl. +apply eq_Z2R, Rmult_eq_reg_r with (bpow (cexp x)). +unfold round, F2R in Y; simpl in Y; rewrite <- Y. +simpl; ring. +apply Rgt_not_eq, bpow_gt_0. +(* . *) +intros Y. +case (Rle_lt_or_eq_dec 0 (round beta fexp Zfloor x)). +rewrite <- round_0 with beta fexp Zfloor... +apply round_le... +now left. +intros Hrx. +set (ef := canonic_exp beta fexp x). +set (mf := Zfloor (scaled_mantissa beta fexp x)). +exists (Float beta mf ef). +unfold Fcore_generic_fmt.canonic. +repeat split; try assumption. +simpl. +apply trans_eq with (cexp (round beta fexp Zfloor x )). +apply sym_eq, canonic_exp_DN... +reflexivity. +intros Hrx; contradict Y. +replace (Zfloor (scaled_mantissa beta fexp x)) with 0%Z. +simpl; discriminate. +apply eq_Z2R, Rmult_eq_reg_r with (bpow (cexp x)). +unfold round, F2R in Hrx; simpl in Hrx; rewrite <- Hrx. +simpl; ring. +apply Rgt_not_eq, bpow_gt_0. +Qed. + +End Fcore_rnd_odd. + +Section Odd_prop_aux. + +Variable beta : radix. +Hypothesis Even_beta: Zeven (radix_val beta)=true. + +Notation bpow e := (bpow beta e). + +Variable fexp : Z -> Z. +Variable fexpe : Z -> Z. + +Context { valid_exp : Valid_exp fexp }. +Context { exists_NE_ : Exists_NE beta fexp }. (* for underflow reason *) +Context { valid_expe : Valid_exp fexpe }. +Context { exists_NE_e : Exists_NE beta fexpe }. (* for defining rounding to odd *) + +Hypothesis fexpe_fexp: forall e, (fexpe e <= fexp e -2)%Z. + + +Lemma generic_format_fexpe_fexp: forall x, + generic_format beta fexp x -> generic_format beta fexpe x. +Proof. +intros x Hx. +apply generic_inclusion_ln_beta with fexp; trivial; intros Hx2. +generalize (fexpe_fexp (ln_beta beta x)). +omega. +Qed. + + + +Lemma exists_even_fexp_lt: forall (c:Z->Z), forall (x:R), + (exists f:float beta, F2R f = x /\ (c (ln_beta beta x) < Fexp f)%Z) -> + exists f:float beta, F2R f =x /\ canonic beta c f /\ Zeven (Fnum f) = true. +Proof with auto with typeclass_instances. +intros c x (g,(Hg1,Hg2)). +exists (Float beta + (Fnum g*Z.pow (radix_val beta) (Fexp g - c (ln_beta beta x))) + (c (ln_beta beta x))). +assert (F2R (Float beta + (Fnum g*Z.pow (radix_val beta) (Fexp g - c (ln_beta beta x))) + (c (ln_beta beta x))) = x). +unfold F2R; simpl. +rewrite Z2R_mult, Z2R_Zpower. +rewrite Rmult_assoc, <- bpow_plus. +rewrite <- Hg1; unfold F2R. +apply f_equal, f_equal. +ring. +omega. +split; trivial. +split. +unfold canonic, canonic_exp. +now rewrite H. +simpl. +rewrite Zeven_mult. +rewrite Zeven_Zpower. +rewrite Even_beta. +apply Bool.orb_true_intro. +now right. +omega. +Qed. + + +Variable choice:Z->bool. +Variable x:R. + + +Variable d u: float beta. +Hypothesis Hd: Rnd_DN_pt (generic_format beta fexp) x (F2R d). +Hypothesis Cd: canonic beta fexp d. +Hypothesis Hu: Rnd_UP_pt (generic_format beta fexp) x (F2R u). +Hypothesis Cu: canonic beta fexp u. + +Hypothesis xPos: (0 < x)%R. + + +Let m:= ((F2R d+F2R u)/2)%R. + + +Lemma d_eq: F2R d= round beta fexp Zfloor x. +Proof with auto with typeclass_instances. +apply Rnd_DN_pt_unicity with (generic_format beta fexp) x... +apply round_DN_pt... +Qed. + + +Lemma u_eq: F2R u= round beta fexp Zceil x. +Proof with auto with typeclass_instances. +apply Rnd_UP_pt_unicity with (generic_format beta fexp) x... +apply round_UP_pt... +Qed. + + +Lemma d_ge_0: (0 <= F2R d)%R. +Proof with auto with typeclass_instances. +rewrite d_eq; apply round_ge_generic... +apply generic_format_0. +now left. +Qed. + + + +Lemma ln_beta_d: (0< F2R d)%R -> + (ln_beta beta (F2R d) = ln_beta beta x :>Z). +Proof with auto with typeclass_instances. +intros Y. +rewrite d_eq; apply ln_beta_round_DN... +now rewrite <- d_eq. +Qed. + + +Lemma Fexp_d: (0 < F2R d)%R -> Fexp d =fexp (ln_beta beta x). +Proof with auto with typeclass_instances. +intros Y. +now rewrite Cd, <- ln_beta_d. +Qed. + + + +Lemma format_bpow_x: (0 < F2R d)%R + -> generic_format beta fexp (bpow (ln_beta beta x)). +Proof with auto with typeclass_instances. +intros Y. +apply generic_format_bpow. +apply valid_exp. +rewrite <- Fexp_d; trivial. +apply Zlt_le_trans with (ln_beta beta (F2R d))%Z. +rewrite Cd; apply ln_beta_generic_gt... +now apply Rgt_not_eq. +apply Hd. +apply ln_beta_le; trivial. +apply Hd. +Qed. + + +Lemma format_bpow_d: (0 < F2R d)%R -> + generic_format beta fexp (bpow (ln_beta beta (F2R d))). +Proof with auto with typeclass_instances. +intros Y; apply generic_format_bpow. +apply valid_exp. +apply ln_beta_generic_gt... +now apply Rgt_not_eq. +now apply generic_format_canonic. +Qed. + + +Lemma d_le_m: (F2R d <= m)%R. +apply Rmult_le_reg_l with 2%R. +auto with real. +apply Rplus_le_reg_l with (-F2R d)%R. +apply Rle_trans with (F2R d). +right; ring. +apply Rle_trans with (F2R u). +apply Rle_trans with x. +apply Hd. +apply Hu. +right; unfold m; field. +Qed. + +Lemma m_le_u: (m <= F2R u)%R. +apply Rmult_le_reg_l with 2%R. +auto with real. +apply Rplus_le_reg_l with (-F2R u)%R. +apply Rle_trans with (F2R d). +right; unfold m; field. +apply Rle_trans with (F2R u). +apply Rle_trans with x. +apply Hd. +apply Hu. +right; ring. +Qed. + +Lemma ln_beta_m: (0 < F2R d)%R -> (ln_beta beta m =ln_beta beta (F2R d) :>Z). +Proof with auto with typeclass_instances. +intros dPos; apply ln_beta_unique_pos. +split. +apply Rle_trans with (F2R d). +destruct (ln_beta beta (F2R d)) as (e,He). +simpl. +rewrite Rabs_right in He. +apply He. +now apply Rgt_not_eq. +apply Rle_ge; now left. +apply d_le_m. +case m_le_u; intros H. +apply Rlt_le_trans with (1:=H). +rewrite u_eq. +apply round_le_generic... +apply generic_format_bpow. +apply valid_exp. +apply ln_beta_generic_gt... +now apply Rgt_not_eq. +now apply generic_format_canonic. +case (Rle_or_lt x (bpow (ln_beta beta (F2R d)))); trivial; intros Z. +absurd ((bpow (ln_beta beta (F2R d)) <= (F2R d)))%R. +apply Rlt_not_le. +destruct (ln_beta beta (F2R d)) as (e,He). +simpl in *; rewrite Rabs_right in He. +apply He. +now apply Rgt_not_eq. +apply Rle_ge; now left. +apply Rle_trans with (round beta fexp Zfloor x). +2: right; apply sym_eq, d_eq. +apply round_ge_generic... +apply generic_format_bpow. +apply valid_exp. +apply ln_beta_generic_gt... +now apply Rgt_not_eq. +now apply generic_format_canonic. +now left. +replace m with (F2R d). +destruct (ln_beta beta (F2R d)) as (e,He). +simpl in *; rewrite Rabs_right in He. +apply He. +now apply Rgt_not_eq. +apply Rle_ge; now left. +assert (F2R d = F2R u). +apply Rmult_eq_reg_l with (/2)%R. +apply Rplus_eq_reg_l with (/2*F2R u)%R. +apply trans_eq with m. +unfold m, Rdiv; ring. +rewrite H; field. +auto with real. +apply Rgt_not_eq, Rlt_gt; auto with real. +unfold m; rewrite <- H0; field. +Qed. + + +Lemma ln_beta_m_0: (0 = F2R d)%R + -> (ln_beta beta m =ln_beta beta (F2R u)-1:>Z)%Z. +Proof with auto with typeclass_instances. +intros Y. +apply ln_beta_unique_pos. +unfold m; rewrite <- Y, Rplus_0_l. +rewrite u_eq. +destruct (ln_beta beta x) as (e,He). +rewrite Rabs_right in He. +rewrite round_UP_small_pos with (ex:=e). +rewrite ln_beta_bpow. +ring_simplify (fexp e + 1 - 1)%Z. +split. +unfold Zminus; rewrite bpow_plus. +unfold Rdiv; apply Rmult_le_compat_l. +apply bpow_ge_0. +simpl; unfold Z.pow_pos; simpl. +rewrite Zmult_1_r; apply Rinv_le. +auto with real. +apply (Z2R_le 2). +specialize (radix_gt_1 beta). +omega. +apply Rlt_le_trans with (bpow (fexp e)*1)%R. +2: right; ring. +unfold Rdiv; apply Rmult_lt_compat_l. +apply bpow_gt_0. +rewrite <- Rinv_1 at 3. +apply Rinv_lt; auto with real. +now apply He, Rgt_not_eq. +apply exp_small_round_0_pos with beta (Zfloor) x... +now apply He, Rgt_not_eq. +now rewrite <- d_eq, Y. +now left. +Qed. + + + + + +Lemma u'_eq: (0 < F2R d)%R -> exists f:float beta, F2R f = F2R u /\ (Fexp f = Fexp d)%Z. +Proof with auto with typeclass_instances. +intros Y. +rewrite u_eq; unfold round. +eexists; repeat split. +simpl; now rewrite Fexp_d. +Qed. + + + + +Lemma m_eq: (0 < F2R d)%R -> exists f:float beta, + F2R f = m /\ (Fexp f = fexp (ln_beta beta x) -1)%Z. +Proof with auto with typeclass_instances. +intros Y. +specialize (Zeven_ex (radix_val beta)); rewrite Even_beta. +intros (b, Hb); rewrite Zplus_0_r in Hb. +destruct u'_eq as (u', (Hu'1,Hu'2)); trivial. +exists (Fmult beta (Float beta b (-1)) (Fplus beta d u'))%R. +split. +rewrite F2R_mult, F2R_plus, Hu'1. +unfold m; rewrite Rmult_comm. +unfold Rdiv; apply f_equal. +unfold F2R; simpl; unfold Z.pow_pos; simpl. +rewrite Zmult_1_r, Hb, Z2R_mult. +simpl; field. +apply Rgt_not_eq, Rmult_lt_reg_l with (Z2R 2). +simpl; auto with real. +rewrite Rmult_0_r, <-Z2R_mult, <-Hb. +apply radix_pos. +apply trans_eq with (-1+Fexp (Fplus beta d u'))%Z. +unfold Fmult. +destruct (Fplus beta d u'); reflexivity. +rewrite Zplus_comm; unfold Zminus; apply f_equal2. +2: reflexivity. +rewrite Fexp_Fplus. +rewrite Z.min_l. +now rewrite Fexp_d. +rewrite Hu'2; omega. +Qed. + +Lemma m_eq_0: (0 = F2R d)%R -> exists f:float beta, + F2R f = m /\ (Fexp f = fexp (ln_beta beta (F2R u)) -1)%Z. +Proof with auto with typeclass_instances. +intros Y. +specialize (Zeven_ex (radix_val beta)); rewrite Even_beta. +intros (b, Hb); rewrite Zplus_0_r in Hb. +exists (Fmult beta (Float beta b (-1)) u)%R. +split. +rewrite F2R_mult; unfold m; rewrite <- Y, Rplus_0_l. +rewrite Rmult_comm. +unfold Rdiv; apply f_equal. +unfold F2R; simpl; unfold Z.pow_pos; simpl. +rewrite Zmult_1_r, Hb, Z2R_mult. +simpl; field. +apply Rgt_not_eq, Rmult_lt_reg_l with (Z2R 2). +simpl; auto with real. +rewrite Rmult_0_r, <-Z2R_mult, <-Hb. +apply radix_pos. +apply trans_eq with (-1+Fexp u)%Z. +unfold Fmult. +destruct u; reflexivity. +rewrite Zplus_comm, Cu; unfold Zminus; now apply f_equal2. +Qed. + +Lemma fexp_m_eq_0: (0 = F2R d)%R -> + (fexp (ln_beta beta (F2R u)-1) < fexp (ln_beta beta (F2R u))+1)%Z. +Proof with auto with typeclass_instances. +intros Y. +assert ((fexp (ln_beta beta (F2R u) - 1) <= fexp (ln_beta beta (F2R u))))%Z. +2: omega. +destruct (ln_beta beta x) as (e,He). +rewrite Rabs_right in He. +2: now left. +assert (e <= fexp e)%Z. +apply exp_small_round_0_pos with beta (Zfloor) x... +now apply He, Rgt_not_eq. +now rewrite <- d_eq, Y. +rewrite u_eq, round_UP_small_pos with (ex:=e); trivial. +2: now apply He, Rgt_not_eq. +rewrite ln_beta_bpow. +ring_simplify (fexp e + 1 - 1)%Z. +replace (fexp (fexp e)) with (fexp e). +case exists_NE_; intros V. +contradict V; rewrite Even_beta; discriminate. +rewrite (proj2 (V e)); omega. +apply sym_eq, valid_exp; omega. +Qed. + +Lemma Fm: generic_format beta fexpe m. +case (d_ge_0); intros Y. +(* *) +destruct m_eq as (g,(Hg1,Hg2)); trivial. +apply generic_format_F2R' with g. +now apply sym_eq. +intros H; unfold canonic_exp; rewrite Hg2. +rewrite ln_beta_m; trivial. +rewrite <- Fexp_d; trivial. +rewrite Cd. +unfold canonic_exp. +generalize (fexpe_fexp (ln_beta beta (F2R d))). +omega. +(* *) +destruct m_eq_0 as (g,(Hg1,Hg2)); trivial. +apply generic_format_F2R' with g. +assumption. +intros H; unfold canonic_exp; rewrite Hg2. +rewrite ln_beta_m_0; try assumption. +apply Zle_trans with (1:=fexpe_fexp _). +assert (fexp (ln_beta beta (F2R u)-1) < fexp (ln_beta beta (F2R u))+1)%Z;[idtac|omega]. +now apply fexp_m_eq_0. +Qed. + + + +Lemma Zm: + exists g : float beta, F2R g = m /\ canonic beta fexpe g /\ Zeven (Fnum g) = true. +Proof with auto with typeclass_instances. +case (d_ge_0); intros Y. +(* *) +destruct m_eq as (g,(Hg1,Hg2)); trivial. +apply exists_even_fexp_lt. +exists g; split; trivial. +rewrite Hg2. +rewrite ln_beta_m; trivial. +rewrite <- Fexp_d; trivial. +rewrite Cd. +unfold canonic_exp. +generalize (fexpe_fexp (ln_beta beta (F2R d))). +omega. +(* *) +destruct m_eq_0 as (g,(Hg1,Hg2)); trivial. +apply exists_even_fexp_lt. +exists g; split; trivial. +rewrite Hg2. +rewrite ln_beta_m_0; trivial. +apply Zle_lt_trans with (1:=fexpe_fexp _). +assert (fexp (ln_beta beta (F2R u)-1) < fexp (ln_beta beta (F2R u))+1)%Z;[idtac|omega]. +now apply fexp_m_eq_0. +Qed. + + +Lemma DN_odd_d_aux: forall z, (F2R d<= z< F2R u)%R -> + Rnd_DN_pt (generic_format beta fexp) z (F2R d). +Proof with auto with typeclass_instances. +intros z Hz1. +replace (F2R d) with (round beta fexp Zfloor z). +apply round_DN_pt... +case (Rnd_DN_UP_pt_split _ _ _ _ Hd Hu (round beta fexp Zfloor z)). +apply generic_format_round... +intros Y; apply Rle_antisym; trivial. +apply round_DN_pt... +apply Hd. +apply Hz1. +intros Y; absurd (z < z)%R. +auto with real. +apply Rlt_le_trans with (1:=proj2 Hz1), Rle_trans with (1:=Y). +apply round_DN_pt... +Qed. + +Lemma UP_odd_d_aux: forall z, (F2R d< z <= F2R u)%R -> + Rnd_UP_pt (generic_format beta fexp) z (F2R u). +Proof with auto with typeclass_instances. +intros z Hz1. +replace (F2R u) with (round beta fexp Zceil z). +apply round_UP_pt... +case (Rnd_DN_UP_pt_split _ _ _ _ Hd Hu (round beta fexp Zceil z)). +apply generic_format_round... +intros Y; absurd (z < z)%R. +auto with real. +apply Rle_lt_trans with (2:=proj1 Hz1), Rle_trans with (2:=Y). +apply round_UP_pt... +intros Y; apply Rle_antisym; trivial. +apply round_UP_pt... +apply Hu. +apply Hz1. +Qed. + + +Theorem round_odd_prop_pos: + round beta fexp (Znearest choice) (round beta fexpe Zrnd_odd x) = + round beta fexp (Znearest choice) x. +Proof with auto with typeclass_instances. +set (o:=round beta fexpe Zrnd_odd x). +case (generic_format_EM beta fexp x); intros Hx. +replace o with x; trivial. +unfold o; apply sym_eq, round_generic... +now apply generic_format_fexpe_fexp. +assert (K1:(F2R d <= o)%R). +apply round_ge_generic... +apply generic_format_fexpe_fexp, Hd. +apply Hd. +assert (K2:(o <= F2R u)%R). +apply round_le_generic... +apply generic_format_fexpe_fexp, Hu. +apply Hu. +assert (P:(x <> m -> o=m -> (forall P:Prop, P))). +intros Y1 Y2. +assert (H:(Rnd_odd_pt beta fexpe x o)). +apply round_odd_pt... +destruct H as (_,H); destruct H. +absurd (x=m)%R; try trivial. +now rewrite <- Y2, H. +destruct H as (_,(k,(Hk1,(Hk2,Hk3)))). +destruct Zm as (k',(Hk'1,(Hk'2,Hk'3))). +absurd (true=false). +discriminate. +rewrite <- Hk3, <- Hk'3. +apply f_equal, f_equal. +apply canonic_unicity with fexpe... +now rewrite Hk'1, <- Y2. +assert (generic_format beta fexp o -> (forall P:Prop, P)). +intros Y. +assert (H:(Rnd_odd_pt beta fexpe x o)). +apply round_odd_pt... +destruct H as (_,H); destruct H. +absurd (generic_format beta fexp x); trivial. +now rewrite <- H. +destruct H as (_,(k,(Hk1,(Hk2,Hk3)))). +destruct (exists_even_fexp_lt fexpe o) as (k',(Hk'1,(Hk'2,Hk'3))). +eexists; split. +apply sym_eq, Y. +simpl; unfold canonic_exp. +apply Zle_lt_trans with (1:=fexpe_fexp _). +omega. +absurd (true=false). +discriminate. +rewrite <- Hk3, <- Hk'3. +apply f_equal, f_equal. +apply canonic_unicity with fexpe... +now rewrite Hk'1, <- Hk1. +case K1; clear K1; intros K1. +2: apply H; rewrite <- K1; apply Hd. +case K2; clear K2; intros K2. +2: apply H; rewrite K2; apply Hu. +case (Rle_or_lt x m); intros Y;[destruct Y|idtac]. +(* . *) +apply trans_eq with (F2R d). +apply round_N_DN_betw with (F2R u)... +apply DN_odd_d_aux; split; try left; assumption. +apply UP_odd_d_aux; split; try left; assumption. +split. +apply round_ge_generic... +apply generic_format_fexpe_fexp, Hd. +apply Hd. +assert (o <= (F2R d + F2R u) / 2)%R. +apply round_le_generic... +apply Fm. +now left. +destruct H1; trivial. +apply P. +now apply Rlt_not_eq. +trivial. +apply sym_eq, round_N_DN_betw with (F2R u)... +split. +apply Hd. +exact H0. +(* . *) +replace o with x. +reflexivity. +apply sym_eq, round_generic... +rewrite H0; apply Fm. +(* . *) +apply trans_eq with (F2R u). +apply round_N_UP_betw with (F2R d)... +apply DN_odd_d_aux; split; try left; assumption. +apply UP_odd_d_aux; split; try left; assumption. +split. +assert ((F2R d + F2R u) / 2 <= o)%R. +apply round_ge_generic... +apply Fm. +now left. +destruct H0; trivial. +apply P. +now apply Rgt_not_eq. +rewrite <- H0; trivial. +apply round_le_generic... +apply generic_format_fexpe_fexp, Hu. +apply Hu. +apply sym_eq, round_N_UP_betw with (F2R d)... +split. +exact Y. +apply Hu. +Qed. + + +End Odd_prop_aux. + +Section Odd_prop. + +Variable beta : radix. +Hypothesis Even_beta: Zeven (radix_val beta)=true. + +Variable fexp : Z -> Z. +Variable fexpe : Z -> Z. +Variable choice:Z->bool. + +Context { valid_exp : Valid_exp fexp }. +Context { exists_NE_ : Exists_NE beta fexp }. (* for underflow reason *) +Context { valid_expe : Valid_exp fexpe }. +Context { exists_NE_e : Exists_NE beta fexpe }. (* for defining rounding to odd *) + +Hypothesis fexpe_fexp: forall e, (fexpe e <= fexp e -2)%Z. + + +Theorem canonizer: forall f, generic_format beta fexp f + -> exists g : float beta, f = F2R g /\ canonic beta fexp g. +Proof with auto with typeclass_instances. +intros f Hf. +exists (Float beta (Ztrunc (scaled_mantissa beta fexp f)) (canonic_exp beta fexp f)). +assert (L:(f = F2R (Float beta (Ztrunc (scaled_mantissa beta fexp f)) (canonic_exp beta fexp f)))). +apply trans_eq with (round beta fexp Ztrunc f). +apply sym_eq, round_generic... +reflexivity. +split; trivial. +unfold canonic; rewrite <- L. +reflexivity. +Qed. + + + + +Theorem round_odd_prop: forall x, + round beta fexp (Znearest choice) (round beta fexpe Zrnd_odd x) = + round beta fexp (Znearest choice) x. +Proof with auto with typeclass_instances. +intros x. +case (total_order_T x 0); intros H; [case H; clear H; intros H | idtac]. +rewrite <- (Ropp_involutive x). +rewrite round_odd_opp. +rewrite 2!round_N_opp. +apply f_equal. +destruct (canonizer (round beta fexp Zfloor (-x))) as (d,(Hd1,Hd2)). +apply generic_format_round... +destruct (canonizer (round beta fexp Zceil (-x))) as (u,(Hu1,Hu2)). +apply generic_format_round... +apply round_odd_prop_pos with d u... +rewrite <- Hd1; apply round_DN_pt... +rewrite <- Hu1; apply round_UP_pt... +auto with real. +(* . *) +rewrite H; repeat rewrite round_0... +(* . *) +destruct (canonizer (round beta fexp Zfloor x)) as (d,(Hd1,Hd2)). +apply generic_format_round... +destruct (canonizer (round beta fexp Zceil x)) as (u,(Hu1,Hu2)). +apply generic_format_round... +apply round_odd_prop_pos with d u... +rewrite <- Hd1; apply round_DN_pt... +rewrite <- Hu1; apply round_UP_pt... +Qed. + + +End Odd_prop. diff --git a/flocq/Calc/Fcalc_bracket.v b/flocq/Calc/Fcalc_bracket.v index dd4bd97..90a8588 100644 --- a/flocq/Calc/Fcalc_bracket.v +++ b/flocq/Calc/Fcalc_bracket.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Calc/Fcalc_digits.v b/flocq/Calc/Fcalc_digits.v index 6210bac..4f76cc2 100644 --- a/flocq/Calc/Fcalc_digits.v +++ b/flocq/Calc/Fcalc_digits.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Calc/Fcalc_div.v b/flocq/Calc/Fcalc_div.v index 6594e55..c8f1f9f 100644 --- a/flocq/Calc/Fcalc_div.v +++ b/flocq/Calc/Fcalc_div.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Calc/Fcalc_ops.v b/flocq/Calc/Fcalc_ops.v index 15bb211..7ece683 100644 --- a/flocq/Calc/Fcalc_ops.v +++ b/flocq/Calc/Fcalc_ops.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Calc/Fcalc_round.v b/flocq/Calc/Fcalc_round.v index 3d31aea..a1bcb84 100644 --- a/flocq/Calc/Fcalc_round.v +++ b/flocq/Calc/Fcalc_round.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Calc/Fcalc_sqrt.v b/flocq/Calc/Fcalc_sqrt.v index e6fe74b..2ed3234 100644 --- a/flocq/Calc/Fcalc_sqrt.v +++ b/flocq/Calc/Fcalc_sqrt.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore.v b/flocq/Core/Fcore.v index 23ebb39..2a5a5f0 100644 --- a/flocq/Core/Fcore.v +++ b/flocq/Core/Fcore.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore_FIX.v b/flocq/Core/Fcore_FIX.v index f185ddf..a3b8d4d 100644 --- a/flocq/Core/Fcore_FIX.v +++ b/flocq/Core/Fcore_FIX.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore_FLT.v b/flocq/Core/Fcore_FLT.v index 4ad4797..c057b6c 100644 --- a/flocq/Core/Fcore_FLT.v +++ b/flocq/Core/Fcore_FLT.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore_FLX.v b/flocq/Core/Fcore_FLX.v index 62ecb6f..800540f 100644 --- a/flocq/Core/Fcore_FLX.v +++ b/flocq/Core/Fcore_FLX.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore_FTZ.v b/flocq/Core/Fcore_FTZ.v index 5356c11..5f3e533 100644 --- a/flocq/Core/Fcore_FTZ.v +++ b/flocq/Core/Fcore_FTZ.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore_Raux.v b/flocq/Core/Fcore_Raux.v index 748e36e..d811019 100644 --- a/flocq/Core/Fcore_Raux.v +++ b/flocq/Core/Fcore_Raux.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -121,6 +121,18 @@ rewrite <- 3!(Rmult_comm r). apply Rmult_minus_distr_l. Qed. +Lemma Rmult_neq_reg_r: forall r1 r2 r3:R, (r2 * r1 <> r3 * r1)%R -> r2 <> r3. +intros r1 r2 r3 H1 H2. +apply H1; rewrite H2; ring. +Qed. + +Lemma Rmult_neq_compat_r: forall r1 r2 r3:R, (r1 <> 0)%R -> (r2 <> r3)%R + -> (r2 *r1 <> r3*r1)%R. +intros r1 r2 r3 H H1 H2. +now apply H1, Rmult_eq_reg_r with r1. +Qed. + + Theorem Rmult_min_distr_r : forall r r1 r2 : R, (0 <= r)%R -> diff --git a/flocq/Core/Fcore_Zaux.v b/flocq/Core/Fcore_Zaux.v index af0d837..7ba28ca 100644 --- a/flocq/Core/Fcore_Zaux.v +++ b/flocq/Core/Fcore_Zaux.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2011 Sylvie Boldo +Copyright (C) 2011-2013 Sylvie Boldo #<br /># -Copyright (C) 2011 Guillaume Melquiond +Copyright (C) 2011-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore_defs.v b/flocq/Core/Fcore_defs.v index fda3a85..ad8cf4f 100644 --- a/flocq/Core/Fcore_defs.v +++ b/flocq/Core/Fcore_defs.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore_digits.v b/flocq/Core/Fcore_digits.v index 2ae076e..02c7a0e 100644 --- a/flocq/Core/Fcore_digits.v +++ b/flocq/Core/Fcore_digits.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2011 Sylvie Boldo +Copyright (C) 2011-2013 Sylvie Boldo #<br /># -Copyright (C) 2011 Guillaume Melquiond +Copyright (C) 2011-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore_float_prop.v b/flocq/Core/Fcore_float_prop.v index 746f7a6..e1535bc 100644 --- a/flocq/Core/Fcore_float_prop.v +++ b/flocq/Core/Fcore_float_prop.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore_generic_fmt.v b/flocq/Core/Fcore_generic_fmt.v index b1db47c..b04cf3d 100644 --- a/flocq/Core/Fcore_generic_fmt.v +++ b/flocq/Core/Fcore_generic_fmt.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -165,6 +165,22 @@ now rewrite Ztrunc_Z2R. now apply Zle_left. Qed. +Lemma generic_format_F2R': forall (x:R) (f:float beta), + F2R f = x -> ((x <> 0)%R -> + (canonic_exp x <= Fexp f)%Z) -> + generic_format x. +Proof. +intros x f H1 H2. +rewrite <- H1; destruct f as (m,e). +apply generic_format_F2R. +simpl in *; intros H3. +rewrite H1; apply H2. +intros Y; apply H3. +apply F2R_eq_0_reg with beta e. +now rewrite H1. +Qed. + + Theorem canonic_opp : forall m e, canonic (Float beta m e) -> @@ -175,6 +191,26 @@ unfold canonic. now rewrite F2R_Zopp, canonic_exp_opp. Qed. +Theorem canonic_abs : + forall m e, + canonic (Float beta m e) -> + canonic (Float beta (Zabs m) e). +Proof. +intros m e H. +unfold canonic. +now rewrite F2R_Zabs, canonic_exp_abs. +Qed. + +Theorem canonic_0: canonic (Float beta 0 (fexp (ln_beta beta 0%R))). +Proof. +unfold canonic; simpl; unfold canonic_exp. +replace (F2R {| Fnum := 0; Fexp := fexp (ln_beta beta 0) |}) with 0%R. +reflexivity. +unfold F2R; simpl; ring. +Qed. + + + Theorem canonic_unicity : forall f1 f2, canonic f1 -> @@ -756,6 +792,24 @@ refine (let H := _ in conj (proj1 H) (Rlt_le _ _ (proj2 H))). now apply mantissa_small_pos. Qed. + +Theorem exp_small_round_0_pos : + forall x ex, + (bpow (ex - 1) <= x < bpow ex)%R -> + round x =R0 -> (ex <= fexp ex)%Z . +Proof. +intros x ex H H1. +case (Zle_or_lt ex (fexp ex)); trivial; intros V. +contradict H1. +apply Rgt_not_eq. +apply Rlt_le_trans with (bpow (ex-1)). +apply bpow_gt_0. +apply (round_bounded_large_pos); assumption. +Qed. + + + + Theorem generic_format_round_pos : forall x, (0 < x)%R -> @@ -1014,6 +1068,24 @@ intros rnd' Hr x. apply round_bounded_large_pos... Qed. +Theorem exp_small_round_0 : + forall rnd {Hr : Valid_rnd rnd} x ex, + (bpow (ex - 1) <= Rabs x < bpow ex)%R -> + round rnd x =R0 -> (ex <= fexp ex)%Z . +Proof. +intros rnd Hr x ex H1 H2. +generalize Rabs_R0. +rewrite <- H2 at 1. +apply (round_abs_abs' (fun t rt => forall (ex : Z), +(bpow (ex - 1) <= t < bpow ex)%R -> +rt = 0%R -> (ex <= fexp ex)%Z)); trivial. +clear; intros rnd Hr x Hx. +now apply exp_small_round_0_pos. +Qed. + + + + Section monotone_abs. Variable rnd : R -> Z. @@ -1283,6 +1355,33 @@ rewrite <- mantissa_DN_small_pos with (1 := Hx) (2 := He). now rewrite <- canonic_exp_fexp_pos with (1 := Hx). Qed. + +Theorem round_DN_UP_lt : + forall x, ~ generic_format x -> + (round Zfloor x < x < round Zceil x)%R. +Proof with auto with typeclass_instances. +intros x Fx. +assert (Hx:(round Zfloor x <= x <= round Zceil x)%R). +split. +apply round_DN_pt. +apply round_UP_pt. +split. + destruct Hx as [Hx _]. + apply Rnot_le_lt; intro Hle. + assert (x = round Zfloor x) by now apply Rle_antisym. + rewrite H in Fx. + contradict Fx. + apply generic_format_round... +destruct Hx as [_ Hx]. +apply Rnot_le_lt; intro Hle. +assert (x = round Zceil x) by now apply Rle_antisym. +rewrite H in Fx. +contradict Fx. +apply generic_format_round... +Qed. + + + Theorem round_UP_small_pos : forall x ex, (bpow (ex - 1) <= x < bpow ex)%R -> diff --git a/flocq/Core/Fcore_rnd.v b/flocq/Core/Fcore_rnd.v index 6b4d807..94c9420 100644 --- a/flocq/Core/Fcore_rnd.v +++ b/flocq/Core/Fcore_rnd.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Core/Fcore_rnd_ne.v b/flocq/Core/Fcore_rnd_ne.v index 0b0776e..6829c0c 100644 --- a/flocq/Core/Fcore_rnd_ne.v +++ b/flocq/Core/Fcore_rnd_ne.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -499,6 +499,25 @@ rewrite Zeven_plus. now rewrite eqb_sym. Qed. +Lemma round_NE_abs: + forall x : R, + round beta fexp ZnearestE (Rabs x) = Rabs (round beta fexp ZnearestE x). +Proof with auto with typeclass_instances. +intros x. +apply sym_eq. +unfold Rabs at 2. +destruct (Rcase_abs x) as [Hx|Hx]. +rewrite round_NE_opp. +apply Rabs_left1. +rewrite <- (round_0 beta fexp ZnearestE). +apply round_le... +now apply Rlt_le. +apply Rabs_pos_eq. +rewrite <- (round_0 beta fexp ZnearestE). +apply round_le... +now apply Rge_le. +Qed. + Theorem round_NE_pt : forall x, Rnd_NE_pt x (round beta fexp ZnearestE x). diff --git a/flocq/Core/Fcore_ulp.v b/flocq/Core/Fcore_ulp.v index 492fac6..07ef3ec 100644 --- a/flocq/Core/Fcore_ulp.v +++ b/flocq/Core/Fcore_ulp.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -1139,4 +1139,278 @@ apply le_pred_lt_aux ; try easy. now split. Qed. + +Theorem pred_succ : forall { monotone_exp : Monotone_exp fexp }, + forall x, F x -> (0 < x)%R -> pred (x + ulp x)=x. +Proof. +intros L x Fx Hx. +assert (x <= pred (x + ulp x))%R. +apply le_pred_lt. +assumption. +now apply generic_format_succ. +replace 0%R with (0+0)%R by ring; apply Rplus_lt_compat; try apply Hx. +apply bpow_gt_0. +apply Rplus_lt_reg_r with (-x)%R; ring_simplify. +apply bpow_gt_0. +apply Rle_antisym; trivial. +apply Rplus_le_reg_r with (ulp (pred (x + ulp x))). +rewrite pred_plus_ulp. +apply Rplus_le_compat_l. +now apply ulp_le. +replace 0%R with (0+0)%R by ring; apply Rplus_lt_compat; try apply Hx. +apply bpow_gt_0. +now apply generic_format_succ. +apply Rgt_not_eq. +now apply Rlt_le_trans with x. +Qed. + + +Theorem lt_UP_le_DN : + forall x y, F y -> + (y < round beta fexp Zceil x -> y <= round beta fexp Zfloor x)%R. +Proof with auto with typeclass_instances. +intros x y Fy Hlt. +apply round_DN_pt... +apply Rnot_lt_le. +contradict Hlt. +apply RIneq.Rle_not_lt. +apply round_UP_pt... +now apply Rlt_le. +Qed. + +Theorem pred_UP_le_DN : + forall x, (0 < round beta fexp Zceil x)%R -> + (pred (round beta fexp Zceil x) <= round beta fexp Zfloor x)%R. +Proof with auto with typeclass_instances. +intros x Pxu. +destruct (generic_format_EM beta fexp x) as [Fx|Fx]. +rewrite !round_generic... +now apply Rlt_le; apply pred_lt_id. +assert (let u := round beta fexp Zceil x in pred u < u)%R as Hup. + now apply pred_lt_id. +apply lt_UP_le_DN... +apply generic_format_pred... +now apply round_UP_pt. +Qed. + +Theorem pred_UP_eq_DN : + forall x, (0 < round beta fexp Zceil x)%R -> ~ F x -> + (pred (round beta fexp Zceil x) = round beta fexp Zfloor x)%R. +Proof with auto with typeclass_instances. +intros x Px Fx. +apply Rle_antisym. +now apply pred_UP_le_DN. +apply le_pred_lt; try apply generic_format_round... +pose proof round_DN_UP_lt _ _ _ Fx as HE. +now apply Rlt_trans with (1 := proj1 HE) (2 := proj2 HE). +Qed. + + + + + +(** Properties of rounding to nearest and ulp *) + +Theorem rnd_N_le_half_an_ulp: forall choice u v, + F u -> (0 < u)%R -> (v < u + (ulp u)/2)%R + -> (round beta fexp (Znearest choice) v <= u)%R. +Proof with auto with typeclass_instances. +intros choice u v Fu Hu H. +(* . *) +assert (0 < ulp u / 2)%R. +unfold Rdiv; apply Rmult_lt_0_compat. +unfold ulp; apply bpow_gt_0. +auto with real. +(* . *) +assert (ulp u / 2 < ulp u)%R. +apply Rlt_le_trans with (ulp u *1)%R;[idtac|right; ring]. +unfold Rdiv; apply Rmult_lt_compat_l. +apply bpow_gt_0. +apply Rmult_lt_reg_l with 2%R. +auto with real. +apply Rle_lt_trans with 1%R. +right; field. +rewrite Rmult_1_r; auto with real. +(* *) +apply Rnd_N_pt_monotone with F v (u + ulp u / 2)%R... +apply round_N_pt... +apply Rnd_DN_pt_N with (u+ulp u)%R. +pattern u at 3; replace u with (round beta fexp Zfloor (u + ulp u / 2)). +apply round_DN_pt... +apply round_DN_succ; try assumption. +split; try left; assumption. +replace (u+ulp u)%R with (round beta fexp Zceil (u + ulp u / 2)). +apply round_UP_pt... +apply round_UP_succ; try assumption... +split; try left; assumption. +right; field. +Qed. + + +Theorem rnd_N_ge_half_an_ulp_pred: forall choice u v, + F u -> (0 < pred u)%R -> (u - (ulp (pred u))/2 < v)%R + -> (u <= round beta fexp (Znearest choice) v)%R. +Proof with auto with typeclass_instances. +intros choice u v Fu Hu H. +(* . *) +assert (0 < u)%R. +apply Rlt_trans with (1:= Hu). +apply pred_lt_id. +assert (0 < ulp (pred u) / 2)%R. +unfold Rdiv; apply Rmult_lt_0_compat. +unfold ulp; apply bpow_gt_0. +auto with real. +assert (ulp (pred u) / 2 < ulp (pred u))%R. +apply Rlt_le_trans with (ulp (pred u) *1)%R;[idtac|right; ring]. +unfold Rdiv; apply Rmult_lt_compat_l. +apply bpow_gt_0. +apply Rmult_lt_reg_l with 2%R. +auto with real. +apply Rle_lt_trans with 1%R. +right; field. +rewrite Rmult_1_r; auto with real. +(* *) +apply Rnd_N_pt_monotone with F (u - ulp (pred u) / 2)%R v... +2: apply round_N_pt... +apply Rnd_UP_pt_N with (pred u). +pattern (pred u) at 2; replace (pred u) with (round beta fexp Zfloor (u - ulp (pred u) / 2)). +apply round_DN_pt... +replace (u - ulp (pred u) / 2)%R with (pred u + ulp (pred u) / 2)%R. +apply round_DN_succ; try assumption. +apply generic_format_pred; assumption. +split; [left|idtac]; assumption. +pattern u at 3; rewrite <- (pred_plus_ulp u); try assumption. +field. +now apply Rgt_not_eq. +pattern u at 3; replace u with (round beta fexp Zceil (u - ulp (pred u) / 2)). +apply round_UP_pt... +replace (u - ulp (pred u) / 2)%R with (pred u + ulp (pred u) / 2)%R. +apply trans_eq with (pred u +ulp(pred u))%R. +apply round_UP_succ; try assumption... +apply generic_format_pred; assumption. +split; [idtac|left]; assumption. +apply pred_plus_ulp; try assumption. +now apply Rgt_not_eq. +pattern u at 3; rewrite <- (pred_plus_ulp u); try assumption. +field. +now apply Rgt_not_eq. +pattern u at 4; rewrite <- (pred_plus_ulp u); try assumption. +right; field. +now apply Rgt_not_eq. +Qed. + + +Theorem rnd_N_ge_half_an_ulp: forall choice u v, + F u -> (0 < u)%R -> (u <> bpow (ln_beta beta u - 1))%R + -> (u - (ulp u)/2 < v)%R + -> (u <= round beta fexp (Znearest choice) v)%R. +Proof with auto with typeclass_instances. +intros choice u v Fu Hupos Hu H. +(* *) +assert (bpow (ln_beta beta u-1) <= pred u)%R. +apply le_pred_lt; try assumption. +apply generic_format_bpow. +assert (canonic_exp beta fexp u < ln_beta beta u)%Z. +apply ln_beta_generic_gt; try assumption. +now apply Rgt_not_eq. +unfold canonic_exp in H0. +ring_simplify (ln_beta beta u - 1 + 1)%Z. +omega. +destruct ln_beta as (e,He); simpl in *. +assert (bpow (e - 1) <= Rabs u)%R. +apply He. +now apply Rgt_not_eq. +rewrite Rabs_right in H0. +case H0; auto. +intros T; contradict T. +now apply sym_not_eq. +apply Rle_ge; now left. +assert (Hu2:(ulp (pred u) = ulp u)). +unfold ulp, canonic_exp. +apply f_equal; apply f_equal. +apply ln_beta_unique. +rewrite Rabs_right. +split. +assumption. +apply Rlt_trans with (1:=pred_lt_id _). +destruct ln_beta as (e,He); simpl in *. +rewrite Rabs_right in He. +apply He. +now apply Rgt_not_eq. +apply Rle_ge; now left. +apply Rle_ge, pred_ge_0; assumption. +apply rnd_N_ge_half_an_ulp_pred; try assumption. +apply Rlt_le_trans with (2:=H0). +apply bpow_gt_0. +rewrite Hu2; assumption. +Qed. + + +Lemma round_N_DN_betw: forall choice x d u, + Rnd_DN_pt (generic_format beta fexp) x d -> + Rnd_UP_pt (generic_format beta fexp) x u -> + (d<=x<(d+u)/2)%R -> + round beta fexp (Znearest choice) x = d. +Proof with auto with typeclass_instances. +intros choice x d u Hd Hu H. +apply Rnd_N_pt_unicity with (generic_format beta fexp) x d u; try assumption. +intros Y. +absurd (x < (d+u)/2)%R; try apply H. +apply Rle_not_lt; right. +apply Rplus_eq_reg_r with (-x)%R. +apply trans_eq with (- (x-d)/2 + (u-x)/2)%R. +field. +rewrite Y; field. +apply round_N_pt... +apply Rnd_DN_UP_pt_N with d u... +apply Hd. +right; apply trans_eq with (-(d-x))%R;[idtac|ring]. +apply Rabs_left1. +apply Rplus_le_reg_l with x; ring_simplify. +apply H. +rewrite Rabs_left1. +apply Rplus_le_reg_l with (d+x)%R. +apply Rmult_le_reg_l with (/2)%R. +auto with real. +apply Rle_trans with x. +right; field. +apply Rle_trans with ((d+u)/2)%R. +now left. +right; field. +apply Rplus_le_reg_l with x; ring_simplify. +apply H. +Qed. + + +Lemma round_N_UP_betw: forall choice x d u, + Rnd_DN_pt (generic_format beta fexp) x d -> + Rnd_UP_pt (generic_format beta fexp) x u -> + ((d+u)/2 < x <= u)%R -> + round beta fexp (Znearest choice) x = u. +Proof with auto with typeclass_instances. +intros choice x d u Hd Hu H. +rewrite <- (Ropp_involutive (round beta fexp (Znearest choice) x )), + <- (Ropp_involutive u) . +apply f_equal. +rewrite <- (Ropp_involutive x) . +rewrite round_N_opp, Ropp_involutive. +apply round_N_DN_betw with (-d)%R. +replace u with (round beta fexp Zceil x). +rewrite <- round_DN_opp. +apply round_DN_pt... +apply Rnd_UP_pt_unicity with (generic_format beta fexp) x... +apply round_UP_pt... +replace d with (round beta fexp Zfloor x). +rewrite <- round_UP_opp. +apply round_UP_pt... +apply Rnd_DN_pt_unicity with (generic_format beta fexp) x... +apply round_DN_pt... +split. +apply Ropp_le_contravar, H. +apply Rlt_le_trans with (-((d + u) / 2))%R. +apply Ropp_lt_contravar, H. +unfold Rdiv; right; ring. +Qed. + + End Fcore_ulp. diff --git a/flocq/Flocq_version.v b/flocq/Flocq_version.v index 662d83a..b375857 100644 --- a/flocq/Flocq_version.v +++ b/flocq/Flocq_version.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2011 Sylvie Boldo +Copyright (C) 2011-2013 Sylvie Boldo #<br /># -Copyright (C) 2011 Guillaume Melquiond +Copyright (C) 2011-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -28,4 +28,4 @@ Definition Flocq_version := Eval vm_compute in | String h t => parse t major (minor + N_of_ascii h - N_of_ascii "0"%char)%N | Empty_string => (major * 100 + minor)%N end in - parse "2.1.0"%string N0 N0. + parse "2.2.0"%string N0 N0. diff --git a/flocq/Prop/Fprop_Sterbenz.v b/flocq/Prop/Fprop_Sterbenz.v index 7d2c2e7..7260d2e 100644 --- a/flocq/Prop/Fprop_Sterbenz.v +++ b/flocq/Prop/Fprop_Sterbenz.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Prop/Fprop_div_sqrt_error.v b/flocq/Prop/Fprop_div_sqrt_error.v index 84a0694..ec00ca4 100644 --- a/flocq/Prop/Fprop_div_sqrt_error.v +++ b/flocq/Prop/Fprop_div_sqrt_error.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Prop/Fprop_mult_error.v b/flocq/Prop/Fprop_mult_error.v index e3e094c..e84e80b 100644 --- a/flocq/Prop/Fprop_mult_error.v +++ b/flocq/Prop/Fprop_mult_error.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Prop/Fprop_plus_error.v b/flocq/Prop/Fprop_plus_error.v index d9dee7c..ddae698 100644 --- a/flocq/Prop/Fprop_plus_error.v +++ b/flocq/Prop/Fprop_plus_error.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public diff --git a/flocq/Prop/Fprop_relative.v b/flocq/Prop/Fprop_relative.v index 8df7336..a8cc1ff 100644 --- a/flocq/Prop/Fprop_relative.v +++ b/flocq/Prop/Fprop_relative.v @@ -2,9 +2,9 @@ This file is part of the Flocq formalization of floating-point arithmetic in Coq: http://flocq.gforge.inria.fr/ -Copyright (C) 2010-2011 Sylvie Boldo +Copyright (C) 2010-2013 Sylvie Boldo #<br /># -Copyright (C) 2010-2011 Guillaume Melquiond +Copyright (C) 2010-2013 Guillaume Melquiond This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -35,9 +35,9 @@ Section relative_error_conversion. Variable rnd : R -> Z. Context { valid_rnd : Valid_rnd rnd }. -Lemma relative_error_lt_conversion : +Lemma relative_error_lt_conversion' : forall x b, (0 < b)%R -> - (Rabs (round beta fexp rnd x - x) < b * Rabs x)%R -> + (x <> 0 -> Rabs (round beta fexp rnd x - x) < b * Rabs x)%R -> exists eps, (Rabs eps < b)%R /\ round beta fexp rnd x = (x * (1 + eps))%R. Proof with auto with typeclass_instances. @@ -50,6 +50,7 @@ now rewrite Rabs_R0. rewrite Hx0, Rmult_0_l. apply round_0... (* *) +specialize (Hxb Hx0). exists ((round beta fexp rnd x - x) / x)%R. split. 2: now field. unfold Rdiv. @@ -61,6 +62,19 @@ rewrite Rinv_l with (1 := Hx0). now rewrite Rabs_R1, Rmult_1_r. Qed. +(* TODO: remove *) +Lemma relative_error_lt_conversion : + forall x b, (0 < b)%R -> + (Rabs (round beta fexp rnd x - x) < b * Rabs x)%R -> + exists eps, + (Rabs eps < b)%R /\ round beta fexp rnd x = (x * (1 + eps))%R. +Proof. +intros x b Hb0 Hxb. +apply relative_error_lt_conversion'. +exact Hb0. +now intros _. +Qed. + Lemma relative_error_le_conversion : forall x b, (0 <= b)%R -> (Rabs (round beta fexp rnd x - x) <= b * Rabs x)%R -> @@ -154,18 +168,28 @@ rewrite F2R_0, F2R_Zabs. now apply Rabs_pos_lt. Qed. -Theorem relative_error_F2R_emin_ex : +Theorem relative_error_F2R_emin_ex' : forall m, let x := F2R (Float beta m emin) in - (x <> 0)%R -> exists eps, (Rabs eps < bpow (-p + 1))%R /\ round beta fexp rnd x = (x * (1 + eps))%R. Proof with auto with typeclass_instances. -intros m x Hx. -apply relative_error_lt_conversion... +intros m x. +apply relative_error_lt_conversion'... apply bpow_gt_0. now apply relative_error_F2R_emin. Qed. +(* TODO: remove *) +Theorem relative_error_F2R_emin_ex : + forall m, let x := F2R (Float beta m emin) in + (x <> 0)%R -> + exists eps, + (Rabs eps < bpow (-p + 1))%R /\ round beta fexp rnd x = (x * (1 + eps))%R. +Proof with auto with typeclass_instances. +intros m x _. +apply relative_error_F2R_emin_ex'. +Qed. + Theorem relative_error_round : (0 < p)%Z -> forall x, @@ -404,6 +428,7 @@ Qed. Variable rnd : R -> Z. Context { valid_rnd : Valid_rnd rnd }. +(* TODO: remove *) Theorem relative_error_FLT_F2R_emin : forall m, let x := F2R (Float beta m (emin + prec - 1)) in (x <> 0)%R -> @@ -424,14 +449,49 @@ apply relative_error with (emin + prec - 1)%Z... apply relative_error_FLT_aux. Qed. +Theorem relative_error_FLT_F2R_emin' : + forall m, let x := F2R (Float beta m emin) in + (x <> 0)%R -> + (Rabs (round beta (FLT_exp emin prec) rnd x - x) < bpow (-prec + 1) * Rabs x)%R. +Proof with auto with typeclass_instances. +intros m x Zx. +destruct (Rlt_or_le (Rabs x) (bpow (emin + prec - 1))) as [Hx|Hx]. +rewrite round_generic... +unfold Rminus. +rewrite Rplus_opp_r, Rabs_R0. +apply Rmult_lt_0_compat. +apply bpow_gt_0. +now apply Rabs_pos_lt. +apply generic_format_FLT_FIX... +apply Rlt_le. +apply Rlt_le_trans with (1 := Hx). +apply bpow_le. +apply Zle_pred. +apply generic_format_FIX. +now exists (Float beta m emin). +now apply relative_error_FLT. +Qed. + +Theorem relative_error_FLT_F2R_emin_ex' : + forall m, let x := F2R (Float beta m emin) in + exists eps, + (Rabs eps < bpow (-prec + 1))%R /\ round beta (FLT_exp emin prec) rnd x = (x * (1 + eps))%R. +Proof with auto with typeclass_instances. +intros m x. +apply relative_error_lt_conversion'... +apply bpow_gt_0. +now apply relative_error_FLT_F2R_emin'. +Qed. + +(* TODO: remove *) Theorem relative_error_FLT_F2R_emin_ex : forall m, let x := F2R (Float beta m (emin + prec - 1)) in (x <> 0)%R -> exists eps, (Rabs eps < bpow (-prec + 1))%R /\ round beta (FLT_exp emin prec) rnd x = (x * (1 + eps))%R. Proof with auto with typeclass_instances. -intros m x Hx. -apply relative_error_lt_conversion... +intros m x _. +apply relative_error_lt_conversion'... apply bpow_gt_0. now apply relative_error_FLT_F2R_emin. Qed. @@ -488,6 +548,32 @@ apply relative_error_N_round with (emin + prec - 1)%Z... apply relative_error_FLT_aux. Qed. +Theorem relative_error_N_FLT_F2R_emin' : + forall m, let x := F2R (Float beta m emin) in + (Rabs (round beta (FLT_exp emin prec) (Znearest choice) x - x) <= /2 * bpow (-prec + 1) * Rabs x)%R. +Proof with auto with typeclass_instances. +intros m x. +destruct (Rlt_or_le (Rabs x) (bpow (emin + prec - 1))) as [Hx|Hx]. +rewrite round_generic... +unfold Rminus. +rewrite Rplus_opp_r, Rabs_R0. +apply Rmult_le_pos. +apply Rmult_le_pos. +apply Rlt_le. +apply (RinvN_pos 1). +apply bpow_ge_0. +apply Rabs_pos. +apply generic_format_FLT_FIX... +apply Rlt_le. +apply Rlt_le_trans with (1 := Hx). +apply bpow_le. +apply Zle_pred. +apply generic_format_FIX. +now exists (Float beta m emin). +now apply relative_error_N_FLT. +Qed. + +(* TODO: remove *) Theorem relative_error_N_FLT_F2R_emin : forall m, let x := F2R (Float beta m (emin + prec - 1)) in (Rabs (round beta (FLT_exp emin prec) (Znearest choice) x - x) <= /2 * bpow (-prec + 1) * Rabs x)%R. @@ -497,6 +583,21 @@ apply relative_error_N_F2R_emin... apply relative_error_FLT_aux. Qed. +Theorem relative_error_N_FLT_F2R_emin_ex' : + forall m, let x := F2R (Float beta m emin) in + exists eps, + (Rabs eps <= /2 * bpow (-prec + 1))%R /\ round beta (FLT_exp emin prec) (Znearest choice) x = (x * (1 + eps))%R. +Proof with auto with typeclass_instances. +intros m x. +apply relative_error_le_conversion... +apply Rmult_le_pos. +apply Rlt_le. +apply (RinvN_pos 1). +apply bpow_ge_0. +now apply relative_error_N_FLT_F2R_emin'. +Qed. + +(* TODO: remove *) Theorem relative_error_N_FLT_F2R_emin_ex : forall m, let x := F2R (Float beta m (emin + prec - 1)) in exists eps, @@ -512,6 +613,33 @@ apply bpow_gt_0. now apply relative_error_N_FLT_F2R_emin. Qed. +Theorem relative_error_N_FLT_round_F2R_emin' : + forall m, let x := F2R (Float beta m emin) in + (Rabs (round beta (FLT_exp emin prec) (Znearest choice) x - x) <= /2 * bpow (-prec + 1) * Rabs (round beta (FLT_exp emin prec) (Znearest choice) x))%R. +Proof with auto with typeclass_instances. +intros m x. +destruct (Rlt_or_le (Rabs x) (bpow (emin + prec - 1))) as [Hx|Hx]. +rewrite round_generic... +unfold Rminus. +rewrite Rplus_opp_r, Rabs_R0. +apply Rmult_le_pos. +apply Rmult_le_pos. +apply Rlt_le. +apply (RinvN_pos 1). +apply bpow_ge_0. +apply Rabs_pos. +apply generic_format_FLT_FIX... +apply Rlt_le. +apply Rlt_le_trans with (1 := Hx). +apply bpow_le. +apply Zle_pred. +apply generic_format_FIX. +now exists (Float beta m emin). +apply relative_error_N_round with (emin := (emin + prec - 1)%Z)... +apply relative_error_FLT_aux. +Qed. + +(* TODO: remove *) Theorem relative_error_N_FLT_round_F2R_emin : forall m, let x := F2R (Float beta m (emin + prec - 1)) in (Rabs (round beta (FLT_exp emin prec) (Znearest choice) x - x) <= /2 * bpow (-prec + 1) * Rabs (round beta (FLT_exp emin prec) (Znearest choice) x))%R. @@ -606,18 +734,28 @@ apply He. Qed. (** 1+#ε# property in any rounding in FLX *) -Theorem relative_error_FLX_ex : +Theorem relative_error_FLX_ex' : forall x, - (x <> 0)%R -> exists eps, (Rabs eps < bpow (-prec + 1))%R /\ round beta (FLX_exp prec) rnd x = (x * (1 + eps))%R. Proof with auto with typeclass_instances. -intros x Hx. -apply relative_error_lt_conversion... +intros x. +apply relative_error_lt_conversion'... apply bpow_gt_0. now apply relative_error_FLX. Qed. +(* TODO: remove *) +Theorem relative_error_FLX_ex : + forall x, + (x <> 0)%R -> + exists eps, + (Rabs eps < bpow (-prec + 1))%R /\ round beta (FLX_exp prec) rnd x = (x * (1 + eps))%R. +Proof with auto with typeclass_instances. +intros x _. +apply relative_error_FLX_ex'. +Qed. + Theorem relative_error_FLX_round : forall x, (x <> 0)%R -> diff --git a/ia32/Nan.v b/ia32/Nan.v new file mode 100644 index 0000000..dadf0ca --- /dev/null +++ b/ia32/Nan.v @@ -0,0 +1,28 @@ +Require Import Fappli_IEEE. +Require Import Fappli_IEEE_bits. +Require Import Floats. +Require Import ZArith. +Require Import Integers. + +(* Needed to break a circular reference after extraction *) +Definition transform_quiet_pl := + Eval unfold Float.transform_quiet_pl in Float.transform_quiet_pl. + +Program Definition default_pl : bool * nan_pl 53 := (true, nat_iter 51 xO xH). + +Definition binop_pl (pl1 pl2:binary64) : bool*nan_pl 53 := + match pl1, pl2 with + | B754_nan s1 pl1, _ => (s1, transform_quiet_pl pl1) + | _, B754_nan s2 pl2 => (s2, transform_quiet_pl pl2) + | _, _ => default_pl + end. + +Theorem binop_propagate1: Float.binop_propagate1_prop binop_pl. +Proof. + repeat intro. destruct f1, f2; try discriminate; simpl; reflexivity. +Qed. + +Theorem binop_propagate2: Float.binop_propagate2_prop binop_pl. +Proof. + repeat intro. destruct f1, f2, f3; try discriminate; simpl; reflexivity. +Qed. diff --git a/lib/Floats.v b/lib/Floats.v index 94c19d2..0151cf0 100644 --- a/lib/Floats.v +++ b/lib/Floats.v @@ -38,20 +38,69 @@ Definition zero: float := B754_zero _ _ false. (**r the float [+0.0] *) Definition eq_dec: forall (f1 f2: float), {f1 = f2} + {f1 <> f2}. Proof. Ltac try_not_eq := try solve [right; congruence]. - destruct f1, f2; + destruct f1 as [| |? []|], f2 as [| |? []|]; try destruct b; try destruct b0; - try solve [left; auto]; try_not_eq; + try solve [left; auto]; try_not_eq. + destruct (positive_eq_dec x x0); try_not_eq; + subst; left; f_equal; f_equal; apply proof_irr. + destruct (positive_eq_dec x x0); try_not_eq; + subst; left; f_equal; f_equal; apply proof_irr. + destruct (positive_eq_dec m m0); try_not_eq; + destruct (Z_eq_dec e e1); try solve [right; intro H; inv H; congruence]; + subst; left; rewrite (proof_irr e0 e2); auto. destruct (positive_eq_dec m m0); try_not_eq; destruct (Z_eq_dec e e1); try solve [right; intro H; inv H; congruence]; subst; left; rewrite (proof_irr e0 e2); auto. Defined. +(* Transform a Nan payload to a quiet Nan payload. + This is not part of the IEEE754 standard, but shared between all + architectures of Compcert. *) +Program Definition transform_quiet_pl (pl:nan_pl 53) : nan_pl 53 := + Pos.lor pl (nat_iter 51 xO xH). +Next Obligation. + destruct pl. + simpl. rewrite Z.ltb_lt in *. + assert (forall x, S (Fcore_digits.digits2_Pnat x) = Pos.to_nat (Pos.size x)). + { induction x0; simpl; auto; rewrite IHx0; zify; omega. } + fold (Z.of_nat (S (Fcore_digits.digits2_Pnat (Pos.lor x 2251799813685248)))). + rewrite H, positive_nat_Z, Psize_log_inf, <- Zlog2_log_inf in *. clear H. + change (Z.pos (Pos.lor x 2251799813685248)) with (Z.lor (Z.pos x) 2251799813685248%Z). + rewrite Z.log2_lor by (zify; omega). + apply Z.max_case. auto. simpl. omega. +Qed. + +Lemma nan_payload_fequal: + forall prec p1 e1 p2 e2, p1 = p2 -> (exist _ p1 e1:nan_pl prec) = exist _ p2 e2. +Proof. + simpl; intros; subst. f_equal. apply Fcore_Zaux.eqbool_irrelevance. +Qed. + +Lemma lor_idempotent: + forall x y, Pos.lor (Pos.lor x y) y = Pos.lor x y. +Proof. + induction x; destruct y; simpl; f_equal; auto; + induction y; simpl; f_equal; auto. +Qed. + +Lemma transform_quiet_pl_idempotent: + forall pl, transform_quiet_pl (transform_quiet_pl pl) = transform_quiet_pl pl. +Proof. + intros []; simpl; intros. apply nan_payload_fequal. + simpl. apply lor_idempotent. +Qed. + (** Arithmetic operations *) -Definition neg: float -> float := b64_opp. (**r opposite (change sign) *) +(* The Nan payload operations for neg and abs is not part of the IEEE754 + standard, but shared between all architectures of Compcert. *) +Definition neg_pl (s:bool) (pl:nan_pl 53) := (negb s, pl). +Definition abs_pl (s:bool) (pl:nan_pl 53) := (false, pl). + +Definition neg: float -> float := b64_opp neg_pl. (**r opposite (change sign) *) Definition abs (x: float): float := (**r absolute value (set sign to [+]) *) match x with - | B754_nan => x + | B754_nan s pl => let '(s, pl) := abs_pl s pl in B754_nan _ _ s pl | B754_infinity _ => B754_infinity _ _ false | B754_finite _ m e H => B754_finite _ _ false m e H | B754_zero _ => B754_zero _ _ false @@ -71,9 +120,30 @@ Definition binary_normalize32_correct (m e:Z) (s:bool) := binary_normalize_correct 24 128 eq_refl eq_refl mode_NE m e s. Global Opaque binary_normalize32_correct. +(* The Nan payload operations for single <-> double conversions are not part of + the IEEE754 standard, but shared between all architectures of Compcert. *) +Definition floatofbinary32_pl (s:bool) (pl:nan_pl 24) : (bool * nan_pl 53). + refine (s, transform_quiet_pl (exist _ (Pos.shiftl_nat (proj1_sig pl) 29) _)). + abstract ( + destruct pl; unfold proj1_sig, Pos.shiftl_nat, nat_iter, Fcore_digits.digits2_Pnat; + fold (Fcore_digits.digits2_Pnat x); + rewrite Z.ltb_lt in *; + zify; omega). +Defined. + +Definition binary32offloat_pl (s:bool) (pl:nan_pl 53) : (bool * nan_pl 24). + refine (s, exist _ (Pos.shiftr_nat (proj1_sig (transform_quiet_pl pl)) 29) _). + abstract ( + destruct (transform_quiet_pl pl); unfold proj1_sig, Pos.shiftr_nat, nat_iter; + rewrite Z.ltb_lt in *; + assert (forall x, Fcore_digits.digits2_Pnat (Pos.div2 x) = + (Fcore_digits.digits2_Pnat x - 1)%nat) by (destruct x0; simpl; zify; omega); + rewrite !H, <- !NPeano.Nat.sub_add_distr; zify; omega). +Defined. + Definition floatofbinary32 (f: binary32) : float := (**r single precision embedding in double precision *) match f with - | B754_nan => B754_nan _ _ + | B754_nan s pl => let '(s, pl) := floatofbinary32_pl s pl in B754_nan _ _ s pl | B754_infinity s => B754_infinity _ _ s | B754_zero s => B754_zero _ _ s | B754_finite s m e _ => @@ -82,7 +152,7 @@ Definition floatofbinary32 (f: binary32) : float := (**r single precision embedd Definition binary32offloat (f: float) : binary32 := (**r conversion to single precision *) match f with - | B754_nan => B754_nan _ _ + | B754_nan s pl => let '(s, pl) := binary32offloat_pl s pl in B754_nan _ _ s pl | B754_infinity s => B754_infinity _ _ s | B754_zero s => B754_zero _ _ s | B754_finite s m e _ => @@ -190,15 +260,33 @@ Definition singleoflong (n:int64): float := (**r conversion from signed 64-bit i Definition singleoflongu (n:int64): float:= (**r conversion from unsigned 64-bit int to single-precision float *) floatofbinary32 (binary_normalize32 (Int64.unsigned n) 0 false). -Definition add: float -> float -> float := b64_plus mode_NE. (**r addition *) -Definition sub: float -> float -> float := b64_minus mode_NE. (**r subtraction *) -Definition mul: float -> float -> float := b64_mult mode_NE. (**r multiplication *) -Definition div: float -> float -> float := b64_div mode_NE. (**r division *) +Parameter binop_pl: binary64 -> binary64 -> bool*nan_pl 53. + +Definition binop_propagate1_prop binop_pl := + forall f1 f2:float, is_nan _ _ f1 = true -> is_nan _ _ f2 = false -> + binop_pl f1 f1 = (binop_pl f1 f2 : bool*nan_pl 53). + + +(* Proved in Nan.v for different architectures *) +Hypothesis binop_propagate1: binop_propagate1_prop binop_pl. + +Definition binop_propagate2_prop binop_pl := + forall f1 f2 f3:float, is_nan _ _ f1 = true -> + is_nan _ _ f2 = false -> is_nan _ _ f3 = false -> + binop_pl f1 f2 = (binop_pl f1 f3 : bool*nan_pl 53). + +(* Proved in Nan.v for different architectures *) +Hypothesis binop_propagate2: binop_propagate2_prop binop_pl. + +Definition add: float -> float -> float := b64_plus binop_pl mode_NE. (**r addition *) +Definition sub: float -> float -> float := b64_minus binop_pl mode_NE. (**r subtraction *) +Definition mul: float -> float -> float := b64_mult binop_pl mode_NE. (**r multiplication *) +Definition div: float -> float -> float := b64_div binop_pl mode_NE. (**r division *) Definition order_float (f1 f2:float): option Datatypes.comparison := match f1, f2 with - | B754_nan,_ | _,B754_nan => None - | B754_infinity true, B754_infinity true + | B754_nan _ _,_ | _,B754_nan _ _ => None + | B754_infinity true, B754_infinity true | B754_infinity false, B754_infinity false => Some Eq | B754_infinity true, _ => Some Lt | B754_infinity false, _ => Some Gt @@ -229,7 +317,7 @@ Definition order_float (f1 f2:float): option Datatypes.comparison := end. Definition cmp (c:comparison) (f1 f2:float) : bool := (**r comparison *) - match c with + match c with | Ceq => match order_float f1 f2 with Some Eq => true | _ => false end | Cne => @@ -242,7 +330,7 @@ Definition cmp (c:comparison) (f1 f2:float) : bool := (**r comparison *) match order_float f1 f2 with Some Gt => true | _ => false end | Cge => match order_float f1 f2 with Some(Gt|Eq) => true | _ => false end - end. + end. (** Conversions between floats and their concrete in-memory representation as a sequence of 64 bits (double precision) or 32 bits (single precision). *) @@ -264,29 +352,17 @@ Ltac compute_this val := let x := fresh in set val as x in *; vm_compute in x; subst x. Ltac smart_omega := - simpl radix_val in *; simpl Zpower in *; + simpl radix_val in *; simpl Zpower in *; compute_this Int.modulus; compute_this Int.half_modulus; compute_this Int.max_unsigned; compute_this Int.min_signed; compute_this Int.max_signed; compute_this Int64.modulus; compute_this Int64.half_modulus; compute_this Int64.max_unsigned; compute_this (Zpower_pos 2 1024); compute_this (Zpower_pos 2 53); compute_this (Zpower_pos 2 52); - omega. - -Theorem addf_commut: forall f1 f2, add f1 f2 = add f2 f1. -Proof. - intros. - destruct f1, f2; simpl; try reflexivity; try (destruct b, b0; reflexivity). - rewrite Zplus_comm; rewrite Zmin_comm; reflexivity. -Qed. - -Theorem subf_addf_opp: forall f1 f2, sub f1 f2 = add f1 (neg f2). -Proof. - destruct f1, f2; reflexivity. -Qed. + zify; omega. Lemma floatofbinary32_exact : - forall f, is_finite_strict _ _ f = true -> + forall f, is_finite_strict _ _ f = true -> is_finite_strict _ _ (floatofbinary32 f) = true /\ B2R _ _ f = B2R _ _ (floatofbinary32 f). Proof. destruct f as [ | | |s m e]; try discriminate; intro. @@ -305,10 +381,12 @@ Proof. now apply bpow_lt. Qed. -Lemma binary32offloatofbinary32 : - forall f, binary32offloat (floatofbinary32 f) = f. +Lemma binary32offloatofbinary32_num : + forall f, is_nan _ _ f = false -> + binary32offloat (floatofbinary32 f) = f. Proof. - intro; pose proof (floatofbinary32_exact f); destruct f as [ | | |s m e]; try reflexivity. + intros f Hnan; pose proof (floatofbinary32_exact f); destruct f as [ | | |s m e]; try reflexivity. + discriminate. specialize (H eq_refl); destruct H. destruct (floatofbinary32 (B754_finite 24 128 s m e e0)) as [ | | |s1 m1 e1]; try discriminate. unfold binary32offloat. @@ -324,22 +402,76 @@ Proof. now apply generic_format_B2R. Qed. +Lemma floatofbinary32offloatofbinary32_pl: + forall s pl, + prod_rect (fun _ => _) floatofbinary32_pl (prod_rect (fun _ => _) binary32offloat_pl (floatofbinary32_pl s pl)) = floatofbinary32_pl s pl. +Proof. + destruct pl. unfold binary32offloat_pl, floatofbinary32_pl. + unfold transform_quiet_pl, proj1_sig. simpl. + f_equal. apply nan_payload_fequal. + unfold Pos.shiftr_nat. simpl. + rewrite !lor_idempotent. reflexivity. +Qed. + +Lemma floatofbinary32offloatofbinary32 : + forall f, floatofbinary32 (binary32offloat (floatofbinary32 f)) = floatofbinary32 f. +Proof. + destruct f; try (rewrite binary32offloatofbinary32_num; tauto). + unfold floatofbinary32, binary32offloat. + rewrite <- floatofbinary32offloatofbinary32_pl at 2. + reflexivity. +Qed. + +Lemma binary32offloatofbinary32offloat_pl: + forall s pl, + prod_rect (fun _ => _) binary32offloat_pl (prod_rect (fun _ => _) floatofbinary32_pl (binary32offloat_pl s pl)) = binary32offloat_pl s pl. +Proof. + destruct pl. unfold binary32offloat_pl, floatofbinary32_pl. unfold prod_rect. + f_equal. apply nan_payload_fequal. + rewrite transform_quiet_pl_idempotent. + unfold transform_quiet_pl, proj1_sig. + change 51 with (29+22). + clear - x. revert x. unfold Pos.shiftr_nat, Pos.shiftl_nat. + induction (29)%nat. intro. simpl. apply lor_idempotent. + intro. + rewrite !nat_iter_succ_r with (f:=Pos.div2). + destruct x; simpl; try apply IHn. + clear IHn. induction n. reflexivity. + rewrite !nat_iter_succ_r with (f:=Pos.div2). auto. +Qed. + +Lemma binary32offloatofbinary32offloat : + forall f, binary32offloat (floatofbinary32 (binary32offloat f)) = binary32offloat f. +Proof. + destruct f; try (rewrite binary32offloatofbinary32_num; simpl; tauto). + unfold floatofbinary32, binary32offloat. + rewrite <- binary32offloatofbinary32offloat_pl at 2. + reflexivity. + rewrite binary32offloatofbinary32_num; simpl. auto. + unfold binary_normalize32. + pose proof (binary_normalize32_correct (cond_Zopp b (Z.pos m)) e b). + destruct binary_normalize; auto. simpl in H. + destruct Rlt_bool in H. intuition. + unfold binary_overflow in H. destruct n. + destruct overflow_to_inf in H; discriminate. +Qed. + Theorem singleoffloat_idem: forall f, singleoffloat (singleoffloat f) = singleoffloat f. Proof. - intros; unfold singleoffloat; rewrite binary32offloatofbinary32; reflexivity. + intros; unfold singleoffloat; rewrite binary32offloatofbinary32offloat; reflexivity. Qed. Theorem singleoflong_idem: forall n, singleoffloat (singleoflong n) = singleoflong n. Proof. - intros; unfold singleoffloat, singleoflong; rewrite binary32offloatofbinary32; reflexivity. + intros; unfold singleoffloat, singleoflong. rewrite floatofbinary32offloatofbinary32; reflexivity. Qed. Theorem singleoflongu_idem: forall n, singleoffloat (singleoflongu n) = singleoflongu n. Proof. - intros; unfold singleoffloat, singleoflongu; rewrite binary32offloatofbinary32; reflexivity. + intros; unfold singleoffloat, singleoflongu. rewrite floatofbinary32offloatofbinary32; reflexivity. Qed. Definition is_single (f: float) : Prop := exists s, f = floatofbinary32 s. @@ -353,8 +485,8 @@ Qed. Theorem singleoffloat_of_single: forall f, is_single f -> singleoffloat f = f. Proof. - intros. destruct H as [s EQ]. subst f. unfold singleoffloat. - rewrite binary32offloatofbinary32; reflexivity. + intros. destruct H as [s EQ]. subst f. unfold singleoffloat. + apply floatofbinary32offloatofbinary32. Qed. Theorem is_single_dec: forall f, {is_single f} + {~is_single f}. @@ -402,9 +534,9 @@ Proof. replace 0%R with (0*bpow radix2 e0)%R by ring; apply Rmult_lt_compat_r; [apply bpow_gt_0; reflexivity|now apply (Z2R_lt _ 0)]. apply Rmult_gt_0_compat; [apply (Z2R_lt 0); reflexivity|now apply bpow_gt_0]. - destruct b, b0; try (now apply_Rcompare; apply H5); inversion H3; + destruct b, b0; try (now apply_Rcompare; apply H5); inversion H3; try (apply_Rcompare; apply H4; rewrite H, H1 in H7; assumption); - try (apply_Rcompare; do 2 rewrite Z2R_opp, Ropp_mult_distr_l_reverse; + try (apply_Rcompare; do 2 rewrite Z2R_opp, Ropp_mult_distr_l_reverse; apply Ropp_lt_contravar; apply H4; rewrite H, H1 in H7; assumption); rewrite H7, Rcompare_mult_r, Rcompare_Z2R by (apply bpow_gt_0); reflexivity. Qed. @@ -472,7 +604,16 @@ Proof. destruct f. simpl; try destruct b; vm_compute; split; congruence. simpl; try destruct b; vm_compute; split; congruence. - simpl; vm_compute; split; congruence. + destruct n as [p Hp]. + simpl. rewrite Z.ltb_lt in Hp. + apply Zlt_succ_le with (m:=52) in Hp. + apply Zpower_le with (r:=radix2) in Hp. + edestruct Fcore_digits.digits2_Pnat_correct. + rewrite Zpower_nat_Z in H0. + eapply Z.lt_le_trans in Hp; eauto. + unfold join_bits; destruct b. + compute_this ((2 ^ 11 + 2047) * 2 ^ 52). smart_omega. + compute_this ((0 + 2047) * 2 ^ 52). smart_omega. unfold bits_of_binary_float, join_bits. destruct (andb_prop _ _ e0); apply Zle_bool_imp_le in H0; apply Zeq_bool_eq in H; unfold FLT_exp in H. match goal with [H:Zmax ?x ?y = e|-_] => pose proof (Zle_max_l x y); pose proof (Zle_max_r x y) end. @@ -494,7 +635,17 @@ Proof. destruct (binary32offloat f). simpl; try destruct b; vm_compute; split; congruence. simpl; try destruct b; vm_compute; split; congruence. - simpl; vm_compute; split; congruence. + destruct n as [p Hp]. + simpl. rewrite Z.ltb_lt in Hp. + apply Zlt_succ_le with (m:=23) in Hp. + apply Zpower_le with (r:=radix2) in Hp. + edestruct Fcore_digits.digits2_Pnat_correct. + rewrite Zpower_nat_Z in H0. + eapply Z.lt_le_trans in Hp; eauto. + compute_this (radix2^23). + unfold join_bits; destruct b. + compute_this ((2 ^ 8 + 255) * 2 ^ 23). smart_omega. + compute_this ((0 + 255) * 2 ^ 23). smart_omega. unfold bits_of_binary_float, join_bits. destruct (andb_prop _ _ e0); apply Zle_bool_imp_le in H0; apply Zeq_bool_eq in H. unfold FLT_exp in H. @@ -512,13 +663,13 @@ Qed. Theorem bits_of_singleoffloat: forall f, bits_of_single (singleoffloat f) = bits_of_single f. Proof. - intro; unfold singleoffloat, bits_of_single; rewrite binary32offloatofbinary32; reflexivity. + intro; unfold singleoffloat, bits_of_single; rewrite binary32offloatofbinary32offloat; reflexivity. Qed. Theorem singleoffloat_of_bits: forall b, singleoffloat (single_of_bits b) = single_of_bits b. Proof. - intro; unfold singleoffloat, single_of_bits; rewrite binary32offloatofbinary32; reflexivity. + intro; unfold singleoffloat, single_of_bits; rewrite floatofbinary32offloatofbinary32; reflexivity. Qed. Theorem single_of_bits_is_single: @@ -539,7 +690,7 @@ Lemma round_exact: round radix2 (FLT_exp (3 - 1024 - 53) 53) (round_mode mode_NE) (Z2R n) = Z2R n. Proof. - intros; rewrite round_generic; [reflexivity|now apply valid_rnd_round_mode|]. + intros; rewrite round_generic; [reflexivity|now apply valid_rnd_round_mode|]. apply generic_format_FLT; exists (Float radix2 n 0). unfold F2R, Fnum, Fexp, bpow; rewrite Rmult_1_r; intuition. pose proof (Zabs_spec n); now smart_omega. @@ -551,7 +702,7 @@ Lemma binary_normalize64_exact: is_finite _ _ (binary_normalize64 n 0 false) = true. Proof. intros; pose proof (binary_normalize64_correct n 0 false). - unfold F2R, Fnum, Fexp, bpow in H0; rewrite Rmult_1_r, round_exact, Rlt_bool_true in H0; try assumption. + unfold F2R, Fnum, Fexp, bpow in H0; rewrite Rmult_1_r, round_exact, Rlt_bool_true in H0; try now intuition. rewrite <- Z2R_abs; apply Z2R_lt; pose proof (Zabs_spec n); now smart_omega. Qed. @@ -560,7 +711,7 @@ Theorem floatofintu_floatofint_1: Int.ltu x ox8000_0000 = true -> floatofintu x = floatofint x. Proof. - unfold floatofintu, floatofint, Int.signed, Int.ltu; intro. + unfold floatofintu, floatofint, Int.signed, Int.ltu; intro. change (Int.unsigned ox8000_0000) with Int.half_modulus. destruct (zlt (Int.unsigned x) Int.half_modulus); now intuition. Qed. @@ -571,19 +722,19 @@ Theorem floatofintu_floatofint_2: floatofintu x = add (floatofint (Int.sub x ox8000_0000)) (floatofintu ox8000_0000). Proof. - unfold floatofintu, floatofint, Int.signed, Int.ltu, Int.sub; intros. + unfold floatofintu, floatofint, Int.signed, Int.ltu, Int.sub; intros. pose proof (Int.unsigned_range x). compute_this (Int.unsigned ox8000_0000). destruct (zlt (Int.unsigned x) 2147483648); try discriminate. rewrite Int.unsigned_repr by smart_omega. destruct (zlt ((Int.unsigned x) - 2147483648) Int.half_modulus). - unfold add, b64_plus. - match goal with [|- _ = Bplus _ _ _ _ _ ?x ?y] => - pose proof (Bplus_correct 53 1024 eq_refl eq_refl mode_NE x y) end. + unfold add, b64_plus. + match goal with [|- _ = Bplus _ _ _ _ _ _ ?x ?y] => + pose proof (Bplus_correct 53 1024 eq_refl eq_refl binop_pl mode_NE x y) end. do 2 rewrite (fun x H => proj1 (binary_normalize64_exact x H)) in H1 by smart_omega. do 2 rewrite (fun x H => proj2 (binary_normalize64_exact x H)) in H1 by smart_omega. - rewrite <- Z2R_plus, round_exact in H1 by smart_omega. - rewrite Rlt_bool_true in H1; + rewrite <- Z2R_plus, round_exact in H1 by smart_omega. + rewrite Rlt_bool_true in H1; replace (Int.unsigned x - 2147483648 + 2147483648) with (Int.unsigned x) in * by ring. apply B2R_inj. destruct (binary_normalize64_exact (Int.unsigned x)); [now smart_omega|]. @@ -616,7 +767,7 @@ Proof. now apply valid_rnd_round_mode. apply generic_format_FIX. exists (Float radix2 (cond_Zopp b (Zpos m)) 0). split; reflexivity. split; [reflexivity|]. - rewrite round_generic, Z2R_mult, Z2R_Zpower_pos, <- bpow_powerRZ; + rewrite round_generic, Z2R_mult, Z2R_Zpower_pos, <- bpow_powerRZ; [reflexivity|now apply valid_rnd_round_mode|apply generic_format_F2R; discriminate]. rewrite (inbetween_float_ZR_sign _ _ _ ((Zpos m) / Zpower_pos radix2 p) (new_location (Zpower_pos radix2 p) (Zpos m mod Zpower_pos radix2 p) loc_Exact)). @@ -685,7 +836,7 @@ Theorem intuoffloat_correct: end. Proof. intro; pose proof (Zoffloat_correct f); unfold intuoffloat; destruct (Zoffloat f). - pose proof (Zle_bool_spec 0 z); pose proof (Zle_bool_spec z Int.max_unsigned). + pose proof (Zle_bool_spec 0 z); pose proof (Zle_bool_spec z Int.max_unsigned). compute_this Int.max_unsigned; destruct H. inversion H0. inversion H1. rewrite <- (Int.unsigned_repr z) in H2 by smart_omega; split; assumption. @@ -713,14 +864,14 @@ Proof. simpl B2R; change 0%R with (Z2R 0); change (-1)%R with (Z2R (-1)); split; apply Z2R_lt; reflexivity. pose proof (Int.unsigned_range i). unfold round, scaled_mantissa, B2R, F2R, Fnum, Fexp in H0 |- *; simpl bpow in H0; do 2 rewrite Rmult_1_r in H0; - apply eq_Z2R in H0. + apply eq_Z2R in H0. split; apply Rnot_le_lt; intro. rewrite Ztrunc_ceil in H0; [apply Zceil_le in H3; change (-1)%R with (Z2R (-1)) in H3; rewrite Zceil_Z2R in H3; omega|]. eapply Rle_trans; [now apply H3|apply (Z2R_le (-1) 0); discriminate]. rewrite Ztrunc_floor in H0; [apply Zfloor_le in H3; rewrite Zfloor_Z2R in H3; now smart_omega|]. eapply Rle_trans; [|now apply H3]; apply (Z2R_le 0); discriminate. -Qed. +Qed. Theorem intuoffloat_intoffloat_1: forall x n, @@ -738,7 +889,7 @@ Proof. destruct H4; [rewrite H2 in H4; discriminate|]. apply intuoffloat_interval in H0; exfalso; destruct H0, H4. eapply Rlt_le_trans in H0; [|now apply H4]; apply (lt_Z2R (-1)) in H0; discriminate. - apply Rcompare_Lt_inv in H1; eapply Rle_lt_trans in H1; [|now apply H4]. + apply Rcompare_Lt_inv in H1; eapply Rle_lt_trans in H1; [|now apply H4]. unfold floatofintu in H1; rewrite (fun x H => proj1 (binary_normalize64_exact x H)) in H1; [apply lt_Z2R in H1; discriminate|split; reflexivity]. Qed. @@ -769,16 +920,16 @@ Proof. [rewrite H in H2; simpl B2R in H2; apply (eq_Z2R 0) in H2; discriminate|reflexivity]. reflexivity. rewrite H in H2; apply Rcompare_Gt_inv in H2; pose proof (intuoffloat_interval _ _ H1). - unfold sub, b64_minus. - exploit (Bminus_correct 53 1024 eq_refl eq_refl mode_NE x (floatofintu ox8000_0000)); [assumption|reflexivity|]; intro. + unfold sub, b64_minus. + exploit (Bminus_correct 53 1024 eq_refl eq_refl binop_pl mode_NE x (floatofintu ox8000_0000)); [assumption|reflexivity|]; intro. rewrite H, round_generic in H6. - match goal with [H6:if Rlt_bool ?x ?y then _ else _|-_] => + match goal with [H6:if Rlt_bool ?x ?y then _ else _|-_] => pose proof (Rlt_bool_spec x y); destruct (Rlt_bool x y) end. - destruct H6. + destruct H6 as [? []]. match goal with [|- _ ?y = _] => pose proof (intoffloat_correct y); destruct (intoffloat y) end. - destruct H9. + destruct H10. f_equal; rewrite <- (Int.repr_signed i); unfold Int.sub; f_equal; apply eq_Z2R. - rewrite Z2R_minus, H10, H4. + rewrite Z2R_minus, H11, H4. unfold round, scaled_mantissa, F2R, Fexp, Fnum, round_mode; simpl bpow; repeat rewrite Rmult_1_r; rewrite <- Z2R_minus; f_equal. rewrite (Ztrunc_floor (B2R _ _ x)), <- Zfloor_minus, <- Ztrunc_floor; @@ -786,11 +937,11 @@ Proof. left; eapply Rlt_trans; [|now apply H2]; apply (Z2R_lt 0); reflexivity. try (change (0 ?= 53) with Lt in H6,H8). (* for Coq 8.4 *) try (change (53 ?= 1024) with Lt in H6,H8). (* for Coq 8.4 *) - exfalso; simpl Zcompare in H6, H8; rewrite H6, H8 in H9. - destruct H9 as [|[]]; [discriminate|..]. - eapply Rle_trans in H9; [|apply Rle_0_minus; left; assumption]; apply (le_Z2R 0) in H9; apply H9; reflexivity. - eapply Rle_lt_trans in H9; [|apply Rplus_lt_compat_r; now apply (proj2 H5)]. - rewrite <- Z2R_opp, <- Z2R_plus in H9; apply lt_Z2R in H9; discriminate. + exfalso; simpl Zcompare in H6, H8; rewrite H6, H8 in H10. + destruct H10 as [|[]]; [discriminate|..]. + eapply Rle_trans in H10; [|apply Rle_0_minus; left; assumption]; apply (le_Z2R 0) in H10; apply H10; reflexivity. + eapply Rle_lt_trans in H10; [|apply Rplus_lt_compat_r; now apply (proj2 H5)]. + rewrite <- Z2R_opp, <- Z2R_plus in H10; apply lt_Z2R in H10; discriminate. exfalso; inversion H7; rewrite Rabs_right in H8. eapply Rle_lt_trans in H8. apply Rle_not_lt in H8; [assumption|apply (bpow_le _ 31); discriminate]. change (bpow radix2 31) with (Z2R(Zsucc Int.max_unsigned - Int.unsigned ox8000_0000)); rewrite Z2R_minus. @@ -816,22 +967,22 @@ Lemma split_bits_or: Proof. intros. transitivity (split_bits 52 11 (join_bits 52 11 false (Int.unsigned x) 1075)). - - f_equal. rewrite Int64.ofwords_add'. reflexivity. - - apply split_join_bits. + - f_equal. rewrite Int64.ofwords_add'. reflexivity. + - apply split_join_bits. compute; auto. - generalize (Int.unsigned_range x). - compute_this Int.modulus; compute_this (2^52); omega. + generalize (Int.unsigned_range x). + compute_this Int.modulus; compute_this (2^52); omega. compute_this (2^11); omega. Qed. Lemma from_words_value: forall x, - B2R _ _ (from_words ox4330_0000 x) = + B2R _ _ (from_words ox4330_0000 x) = (bpow radix2 52 + Z2R (Int.unsigned x))%R /\ is_finite _ _ (from_words ox4330_0000 x) = true. Proof. - intros; unfold from_words, double_of_bits, b64_of_bits, binary_float_of_bits. - rewrite B2R_FF2B; unfold is_finite; rewrite match_FF2B; + intros; unfold from_words, double_of_bits, b64_of_bits, binary_float_of_bits. + rewrite B2R_FF2B. rewrite is_finite_FF2B. unfold binary_float_of_bits_aux; rewrite split_bits_or; simpl; pose proof (Int.unsigned_range x). destruct (Int.unsigned x + Zpower_pos 2 52) eqn:?. exfalso; now smart_omega. @@ -848,37 +999,37 @@ Theorem floatofintu_from_words: sub (from_words ox4330_0000 x) (from_words ox4330_0000 Int.zero). Proof. intros; destruct (Int.eq_dec x Int.zero); [subst; vm_compute; reflexivity|]. - assert (Int.unsigned x <> 0). + assert (Int.unsigned x <> 0). intro; destruct n; rewrite <- (Int.repr_unsigned x), H; reflexivity. pose proof (Int.unsigned_range x). pose proof (binary_normalize64_exact (Int.unsigned x)). destruct H1; [smart_omega|]. unfold floatofintu, sub, b64_minus. - match goal with [|- _ = Bminus _ _ _ _ _ ?x ?y] => - pose proof (Bminus_correct 53 1024 eq_refl eq_refl mode_NE x y) end. + match goal with [|- _ = Bminus _ _ _ _ _ _ ?x ?y] => + pose proof (Bminus_correct 53 1024 eq_refl eq_refl binop_pl mode_NE x y) end. apply (fun f x y => f x y) in H3; try apply (fun x => proj2 (from_words_value x)). do 2 rewrite (fun x => proj1 (from_words_value x)) in H3. rewrite Int.unsigned_zero in H3. replace (bpow radix2 52 + Z2R (Int.unsigned x) - (bpow radix2 52 + Z2R 0))%R with (Z2R (Int.unsigned x)) in H3 by (simpl; ring). rewrite round_exact in H3 by smart_omega. - match goal with [H3:if Rlt_bool ?x ?y then _ else _ |- _] => - pose proof (Rlt_bool_spec x y); destruct (Rlt_bool x y) end; destruct H3. + match goal with [H3:if Rlt_bool ?x ?y then _ else _ |- _] => + pose proof (Rlt_bool_spec x y); destruct (Rlt_bool x y) end; destruct H3 as [? []]. try (change (53 ?= 1024) with Lt in H3,H5). (* for Coq 8.4 *) simpl Zcompare in *; apply B2R_inj; try match goal with [H':B2R _ _ ?f = _ , H'':is_finite _ _ ?f = true |- is_finite_strict _ _ ?f = true] => destruct f; [ simpl in H'; change 0%R with (Z2R 0) in H'; apply eq_Z2R in H'; now destruct (H (eq_sym H')) | discriminate H'' | discriminate H'' | reflexivity - ] + ] end. rewrite H3; assumption. - inversion H4; change (bpow radix2 1024) with (Z2R (radix2 ^ 1024)) in H6; rewrite <- Z2R_abs in H6. - apply le_Z2R in H6; pose proof (Zabs_spec (Int.unsigned x)); + inversion H4; change (bpow radix2 1024) with (Z2R (radix2 ^ 1024)) in H5; rewrite <- Z2R_abs in H5. + apply le_Z2R in H5; pose proof (Zabs_spec (Int.unsigned x)); exfalso; now smart_omega. Qed. Lemma ox8000_0000_signed_unsigned: - forall x, + forall x, Int.unsigned (Int.add x ox8000_0000) = Int.signed x + Int.half_modulus. Proof. intro; unfold Int.signed, Int.add; pose proof (Int.unsigned_range x). @@ -902,16 +1053,16 @@ Local Transparent Int.repr Int64.repr. pose proof (Int.signed_range x). pose proof (binary_normalize64_exact (Int.signed x)); destruct H1; [now smart_omega|]. unfold floatofint, sub, b64_minus. - match goal with [|- _ = Bminus _ _ _ _ _ ?x ?y] => - pose proof (Bminus_correct 53 1024 eq_refl eq_refl mode_NE x y) end. + match goal with [|- _ = Bminus _ _ _ _ _ _ ?x ?y] => + pose proof (Bminus_correct 53 1024 eq_refl eq_refl binop_pl mode_NE x y) end. apply (fun f x y => f x y) in H3; try apply (fun x => proj2 (from_words_value x)). do 2 rewrite (fun x => proj1 (from_words_value x)) in H3. replace (bpow radix2 52 + Z2R (Int.unsigned (Int.add x ox8000_0000)) - (bpow radix2 52 + Z2R (Int.unsigned ox8000_0000)))%R with (Z2R (Int.signed x)) in H3 by (rewrite ox8000_0000_signed_unsigned; rewrite Z2R_plus; simpl; ring). rewrite round_exact in H3 by smart_omega. - match goal with [H3:if Rlt_bool ?x ?y then _ else _ |- _] => - pose proof (Rlt_bool_spec x y); destruct (Rlt_bool x y) end; destruct H3. + match goal with [H3:if Rlt_bool ?x ?y then _ else _ |- _] => + pose proof (Rlt_bool_spec x y); destruct (Rlt_bool x y) end; destruct H3 as [? []]. try (change (0 ?= 53) with Lt in H3,H5). (* for Coq 8.4 *) try (change (53 ?= 1024) with Lt in H3,H5). (* for Coq 8.4 *) simpl Zcompare in *; apply B2R_inj; @@ -919,11 +1070,11 @@ Local Transparent Int.repr Int64.repr. destruct f; [ simpl in H'; change 0%R with (Z2R 0) in H'; apply eq_Z2R in H'; now destruct (H (eq_sym H')) | discriminate H'' | discriminate H'' | reflexivity - ] + ] end. rewrite H3; assumption. - inversion H4; unfold bpow in H6; rewrite <- Z2R_abs in H6; - apply le_Z2R in H6; pose proof (Zabs_spec (Int.signed x)); exfalso; now smart_omega. + inversion H4; unfold bpow in H5; rewrite <- Z2R_abs in H5; + apply le_Z2R in H5; pose proof (Zabs_spec (Int.signed x)); exfalso; now smart_omega. Qed. (** Conversions from 32-bit integers to single-precision floats can @@ -936,10 +1087,10 @@ Lemma is_finite_strict_ge_1: (1 <= Rabs (B2R _ _ f))%R -> is_finite_strict _ _ f = true. Proof. - intros. destruct f; auto. simpl in H0. + intros. destruct f; auto. simpl in H0. change 0%R with (Z2R 0) in H0. change 1%R with (Z2R 1) in H0. - rewrite <- Z2R_abs in H0. + rewrite <- Z2R_abs in H0. exploit le_Z2R; eauto. Qed. @@ -954,29 +1105,27 @@ Proof. subst n; reflexivity. exploit binary_normalize64_exact; eauto. intros [A B]. destruct (binary_normalize64 n 0 false) as [ | | | s m e] eqn:B64; simpl in *. -- assert (0 = n) by (apply eq_Z2R; auto). subst n. simpl in GT. omegaContradiction. +- assert (0 = n) by (apply eq_Z2R; auto). subst n. simpl in GT. omegaContradiction. - discriminate. - discriminate. - set (n1 := cond_Zopp s (Z.pos m)) in *. - generalize (binary_normalize32_correct n1 e s). + generalize (binary_normalize32_correct n1 e s). fold (binary_normalize32 n1 e s). intros C. - generalize (binary_normalize32_correct n 0 false). + generalize (binary_normalize32_correct n 0 false). fold (binary_normalize32 n 0 false). intros D. assert (A': @F2R radix2 {| Fnum := n; Fexp := 0 |} = Z2R n). - { - unfold F2R. apply Rmult_1_r. - } - rewrite A in C. rewrite A' in D. + { unfold F2R. apply Rmult_1_r. } + rewrite A in C. rewrite A' in D. destruct (Rlt_bool (Rabs (round radix2 (FLT_exp (3 - 128 - 24) 24) (round_mode mode_NE) (Z2R n))) (bpow radix2 128)). -+ destruct C as [C1 C2]; destruct D as [D1 D2]. ++ destruct C as [C1 [C2 _]]; destruct D as [D1 [D2 _]]. assert (1 <= Rabs (round radix2 (FLT_exp (3 - 128 - 24) 24) (round_mode mode_NE) (Z2R n)))%R. - { apply abs_round_ge_generic. + { apply abs_round_ge_generic. apply fexp_correct. red. omega. apply valid_rnd_round_mode. - apply generic_format_bpow with (e := 0). compute. congruence. + apply generic_format_bpow with (e := 0). compute. congruence. rewrite <- Z2R_abs. change 1%R with (Z2R 1). apply Z2R_le. omega. } apply B2R_inj. apply is_finite_strict_ge_1; auto. rewrite C1; auto. @@ -988,17 +1137,102 @@ Qed. Theorem singleofint_floatofint: forall n, singleofint n = singleoffloat (floatofint n). Proof. - intros. symmetry. apply single_float_of_int. + intros. symmetry. apply single_float_of_int. generalize (Int.signed_range n). smart_omega. Qed. Theorem singleofintu_floatofintu: forall n, singleofintu n = singleoffloat (floatofintu n). Proof. - intros. symmetry. apply single_float_of_int. + intros. symmetry. apply single_float_of_int. generalize (Int.unsigned_range n). smart_omega. Qed. +Theorem mul2_add: + forall f, add f f = mul f (floatofint (Int.repr 2%Z)). +Proof. + intros. unfold add, b64_plus, mul, b64_mult. + destruct (is_finite_strict _ _ f) eqn:EQFINST. + - assert (EQFIN:is_finite _ _ f = true) by (destruct f; simpl in *; congruence). + pose proof (Bplus_correct 53 1024 eq_refl eq_refl binop_pl mode_NE f f EQFIN EQFIN). + pose proof (Bmult_correct 53 1024 eq_refl eq_refl binop_pl mode_NE f + (floatofint (Int.repr 2%Z))). + rewrite <- double, Rmult_comm in H. + replace (B2R 53 1024 (floatofint (Int.repr 2))) with 2%R in H0 by (compute; field). + destruct Rlt_bool. + + destruct H0 as [? []], H as [? []]. + rewrite EQFIN in H1. + apply B2R_Bsign_inj; auto. + etransitivity. apply H. symmetry. apply H0. + etransitivity. apply H4. symmetry. etransitivity. apply H2. + destruct Bmult; try reflexivity; discriminate. + simpl. rewrite xorb_false_r. + erewrite <- Rmult_0_l, Rcompare_mult_r. + destruct f; try discriminate EQFINST. + simpl. unfold F2R. + erewrite <- Rmult_0_l, Rcompare_mult_r. + rewrite Rcompare_Z2R with (y:=0). + destruct b; reflexivity. + apply bpow_gt_0. + apply (Z2R_lt 0 2). omega. + + destruct H. + apply B2FF_inj. + etransitivity. apply H. + symmetry. etransitivity. apply H0. + f_equal. destruct Bsign; reflexivity. + - destruct f as [[]|[]| |]; try discriminate; try reflexivity. + simpl. erewrite binop_propagate1; reflexivity. +Qed. + +Program Definition pow2_float (b:bool) (e:Z) (H:-1023 < e < 1023) : float := + B754_finite _ _ b (nat_iter 52 xO xH) (e-52) _. +Next Obligation. + unfold Fappli_IEEE.bounded, canonic_mantissa. + rewrite andb_true_iff, Zle_bool_true by omega. split; auto. + apply Zeq_bool_true. unfold FLT_exp. simpl Z.of_nat. + apply Z.max_case_strong; omega. +Qed. + +Theorem mul_div_pow2: + forall b e f H H', + mul f (pow2_float b e H) = div f (pow2_float b (-e) H'). +Proof. + intros. unfold mul, b64_mult, div, b64_div. + pose proof (Bmult_correct 53 1024 eq_refl eq_refl binop_pl mode_NE f (pow2_float b e H)). + pose proof (Bdiv_correct 53 1024 eq_refl eq_refl binop_pl mode_NE f (pow2_float b (-e) H')). + lapply H1. clear H1. intro. + change (is_finite 53 1024 (pow2_float b e H)) with true in H0. + unfold Rdiv in H1. + replace (/ B2R 53 1024 (pow2_float b (-e) H'))%R + with (B2R 53 1024 (pow2_float b e H)) in H1. + destruct (is_finite _ _ f) eqn:EQFIN. + - destruct Rlt_bool. + + destruct H0 as [? []], H1 as [? []]. + apply B2R_Bsign_inj; auto. + etransitivity. apply H0. symmetry. apply H1. + etransitivity. apply H3. destruct Bmult; try discriminate H2; reflexivity. + symmetry. etransitivity. apply H5. destruct Bdiv; try discriminate H4; reflexivity. + reflexivity. + + apply B2FF_inj. + etransitivity. apply H0. symmetry. etransitivity. apply H1. + reflexivity. + - destruct f; try discriminate EQFIN. reflexivity. + simpl. erewrite binop_propagate2. reflexivity. + reflexivity. reflexivity. reflexivity. + - simpl. + assert ((4503599627370496 * bpow radix2 (e - 52))%R = + (/ (4503599627370496 * bpow radix2 (- e - 52)))%R). + { etransitivity. symmetry. apply (bpow_plus radix2 52). + symmetry. etransitivity. apply f_equal. symmetry. apply (bpow_plus radix2 52). + rewrite <- bpow_opp. f_equal. ring. } + destruct b. unfold cond_Zopp. + rewrite !F2R_Zopp, <- Ropp_inv_permute. f_equal. auto. + intro. apply F2R_eq_0_reg in H3. omega. + apply H2. + - simpl. intro. apply F2R_eq_0_reg in H2. + destruct b; simpl in H2; omega. +Qed. + Global Opaque zero eq_dec neg abs singleoffloat intoffloat intuoffloat floatofint floatofintu add sub mul div cmp bits_of_double double_of_bits bits_of_single single_of_bits from_words. diff --git a/powerpc/Nan.v b/powerpc/Nan.v new file mode 100644 index 0000000..77a752e --- /dev/null +++ b/powerpc/Nan.v @@ -0,0 +1,28 @@ +Require Import Fappli_IEEE. +Require Import Fappli_IEEE_bits. +Require Import Floats. +Require Import ZArith. +Require Import Integers. + +(* Needed to break a circular reference after extraction *) +Definition transform_quiet_pl := + Eval unfold Float.transform_quiet_pl in Float.transform_quiet_pl. + +Program Definition default_pl : bool * nan_pl 53 := (false, nat_iter 51 xO xH). + +Definition binop_pl (pl1 pl2:binary64) : bool*nan_pl 53 := + match pl1, pl2 with + | B754_nan s1 pl1, _ => (s1, transform_quiet_pl pl1) + | _, B754_nan s2 pl2 => (s2, transform_quiet_pl pl2) + | _, _ => default_pl + end. + +Theorem binop_propagate1: Float.binop_propagate1_prop binop_pl. +Proof. + repeat intro. destruct f1, f2; try discriminate; reflexivity. +Qed. + +Theorem binop_propagate2: Float.binop_propagate2_prop binop_pl. +Proof. + repeat intro. destruct f1, f2, f3; try discriminate; simpl; reflexivity. +Qed. |