ここでゼロによる除算が発生するケースはありません。
SMTソルバー Z3は、正確なIEEE浮動小数点演算をサポートします。Z3にa
、次のb
ような数値などを見つけるように依頼してみましょうa != b && (a - b) == 0
。
(set-info :status unknown)
(set-logic QF_FP)
(declare-fun b () (FloatingPoint 8 24))
(declare-fun a () (FloatingPoint 8 24))
(declare-fun rm () RoundingMode)
(assert
(and (not (fp.eq a b)) (fp.eq (fp.sub rm a b) +zero) true))
(check-sat)
結果はUNSAT
です。そのような数はありません。
上記のSMTLIB文字列により、Z3は任意の丸めモード(rm
)を選択することもできます。これは、結果がすべての可能な丸めモード(5つある)に当てはまることを意味します。結果には、関係する変数がNaN
無限または無限である可能性も含まれます。
a == b
実装されているfp.eq
ように、品質+0f
と-0f
等しい比較。ゼロとの比較fp.eq
も使用して実装されています。質問はゼロによる除算を回避することを目的としているため、これは適切な比較です。
同等性テストがビット単位の同等性を使用して実装されていて、ゼロにする方法だった+0f
とし-0f
たら、a - b
この回答の誤った以前のバージョンには、好奇心が強い人のために、そのケースに関するモードの詳細が含まれています。
Z3 OnlineはまだFPA理論をサポートしていません。この結果は、最新の不安定なブランチを使用して取得されました。次のように.NETバインディングを使用して再現できます。
var fpSort = context.MkFPSort32();
var aExpr = (FPExpr)context.MkConst("a", fpSort);
var bExpr = (FPExpr)context.MkConst("b", fpSort);
var rmExpr = (FPRMExpr)context.MkConst("rm", context.MkFPRoundingModeSort());
var fpZero = context.MkFP(0f, fpSort);
var subExpr = context.MkFPSub(rmExpr, aExpr, bExpr);
var constraintExpr = context.MkAnd(
context.MkNot(context.MkFPEq(aExpr, bExpr)),
context.MkFPEq(subExpr, fpZero),
context.MkTrue()
);
var smtlibString = context.BenchmarkToSMTString(null, "QF_FP", null, null, new BoolExpr[0], constraintExpr);
var solver = context.MkSimpleSolver();
solver.Assert(constraintExpr);
var status = solver.Check();
Console.WriteLine(status);
(のような例を見落とすことは困難であるため、IEEEフロートの質問に答えるためにZ3を使用するといいですNaN
、-0f
、+-inf
)あなたは、任意の質問をすることができます。仕様を解釈して引用する必要はありません。「この特定のint log2(float)
アルゴリズムは正しいですか?」のように、floatとintegerの混合の質問をすることもできます。