使用flocq定义浮动和校样

时间:2018-05-04 04:54:39

标签: floating-point coq

我正在尝试弄清楚如何使用 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.

1 个答案:

答案 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 2424 < 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