我正在尝试弄清楚如何使用 flocq 包。下面我有一个简单的脚本,我创建了一个简单的函数。但是我无法弄清楚如何创建两个 binary32 ,我可以用它来评估这个函数。我不知道如何创建“有界”的证明。我也希望能够证明,例如,对于特定的x和y,我不会得到 NaN 。这是 flocq 有用的东西吗?或者可能还有另一个我应该研究的方案?任何帮助表示赞赏!
Require Import Psatz.
From Flocq Require Import Fcore_FTZ Fcore Fcalc_ops Fappli_IEEE Fappli_IEEE_bits.
Definition b32_my_fun (x y : binary32) : binary32 :=
b32_div mode_NE (b32_plus mode_NE x y) y.
答案 0 :(得分:4)
我通过探索CompCert中包含的flocq副本,将这个答案拼凑在一起。您可能有兴趣查看CompCert的lib/Floats.v
,尤其是lib/Fappli_IEEE_extra.v
,它在flocq之上添加了一些便利功能。 (这也意味着我的答案可能不适用于vanilla flocq,但我认为应该。)
要创建binary32
,请使用binary_normalize
中的flocq Fappli_IEEE
函数。这是它的类型:
binary_normalize
: forall prec emax : Z,
Prec_gt_0 prec -> prec < emax -> mode -> Z -> Z -> bool -> binary_float prec emax
对于32位IEEE浮点数,prec
为24(尾数中的精度位数),emax
为128(指数的最大值)。 mode
参数是舍入模式,mode_NE
应该是合理的选择。两个Z
参数分别是尾数和指数的值;如果尾数为0,则最终的bool似乎是使用的符号。
因此对于具有尾数42和指数32的32位浮点数,我们可以尝试以下方法:
Check (binary_normalize 24 128 _ _ mode_NE 42 23 false).
binary_normalize 24 128 ?prec_gt_0_ ?Hmax mode_NE 42 23 false
: binary_float 24 128
where
?prec_gt_0_ : [ |- Prec_gt_0 24]
?Hmax : [ |- 24 < 128]
仍然需要提供两个简单目标的证明:Prec_gt_0 24
和24 < 128
。在交互模式下,这些都可以通过reflexivity
:
Goal Prec_gt_0 24.
Proof.
reflexivity.
Qed.
此类证明的证明条件只是eq_refl
(例如,您可以在Show Proof.
之前查看Qed.
。所以我们到达:
Check (binary_normalize 24 128 eq_refl eq_refl mode_NE 42 23 false).
binary_normalize 24 128 eq_refl eq_refl mode_NE 42 23 false
: binary_float 24 128
我们可以看看这个的真实内部表现:
Eval simpl in (binary_normalize 24 128 eq_refl eq_refl mode_NE 42 23 false).
= B754_finite 24 128 false 11010048 (FLT_exp (-149) 24 29)
(proj1 (binary_round_correct 24 128 eq_refl eq_refl mode_NE false 42 23))
: binary_float 24 128
Eval compute in (binary_normalize 24 128 eq_refl eq_refl mode_NE 42 23 false).
= B754_finite 24 128 false 11010048 5
(proj1 (binary_round_correct 24 128 eq_refl eq_refl mode_NE false 42 23))
: binary_float 24 128
最后我们可以将它打包成一个很好的小函数:
Definition my_binary32 (mantissa exponent: Z): binary32 :=
binary_normalize 24 128 eq_refl eq_refl mode_NE mantissa exponent false.
测试一下:
Eval simpl in (my_binary32 42 23).
= B754_finite 24 128 false 11010048 (FLT_exp (-149) 24 29)
(proj1 (binary_round_correct 24 128 eq_refl eq_refl mode_NE false 42 23))
: binary32
Eval simpl in (my_binary32 42 230).
= B754_infinity 24 128 false
: binary32