在我的一个 SMT 程序中,我使用了一个实数。我需要限制实数的精度以提高效率,因为这个数字几乎可以有无数种解决方案,尽管只需要小数点后的 5/6 位。例如,实数的可能估值如下,尽管如果我们取小数点后的前七位数字,所有这些都是相同的。
1197325/13631488 = 0.087835238530……
19157213/218103808 = 0.087835298134……
153257613/1744830464 = 0.087835245980……
1226060865/13958643712 = 0.087835243186……
我希望 SMT 求解器将所有这四个数字视为一个数字(以便减少搜索空间)。有没有办法控制实数的精度?
我尝试以编程方式(使用 Z3 Dot Net API)来解决上述问题,如下所示。这里 DelBP[j] 是一个实数。
{
BoolExpr[] _Exprs = new BoolExpr[nBuses];
for (j = 1; j <= nBuses; j++)
{
_Exprs[j - 1] = z3.MkEq(DelBP[j], z3.MkDiv(z3.MkInt2Real(DelBP_A[j]), z3.MkInt2Real(DelBP_B[j])));
}
BoolExpr Expr = z3.MkAnd(_Exprs);
s.Assert(Expr);
tw.WriteLine("(assert {0})", Expr.ToString());
}
{
BoolExpr[] _Exprs = new BoolExpr[nBuses];
for (j = 1; j <= nBuses; j++)
{
_Exprs[j - 1] = z3.MkAnd(z3.MkGe(DelBP_A[j], z3.MkInt(1)),
z3.MkLe(DelBP_A[j], z3.MkInt(10000)));
}
BoolExpr Expr = z3.MkAnd(_Exprs);
s.Assert(Expr);
tw.WriteLine("(assert {0})", Expr.ToString());
}
{
BoolExpr[] _Exprs = new BoolExpr[nBuses];
for (j = 1; j <= nBuses; j++)
{
_Exprs[j - 1] = z3.MkAnd(z3.MkGe(DelBP_B[j], z3.MkInt(1)),
z3.MkLe(DelBP_B[j], z3.MkInt(10000)));
}
BoolExpr Expr = z3.MkAnd(_Exprs);
s.Assert(Expr);
tw.WriteLine("(assert {0})", Expr.ToString());
}
但是,它没有用。谁能帮我解决这个问题?先感谢您。