我们能用Z3来限制实数项的精度吗?

我们能用Z3来限制实数项的精度吗?,z3,Z3,在我的一个SMT程序中,我使用了一个实术语。为了提高效率,我需要限制实数的精度,因为这个数字几乎有无穷多个解,尽管小数点后只需要5/6位。例如,实数的可能估值可以如下所示,但如果我们取小数点后的前七位数字,则所有实数的估值都是相同的 1197325/13631488=0.087835238530 19157213/218103808=0.087835298134 153257613/1744830464=0.087835245980 1226060865/13958643712=0.087835

在我的一个SMT程序中,我使用了一个实术语。为了提高效率,我需要限制实数的精度,因为这个数字几乎有无穷多个解,尽管小数点后只需要5/6位。例如,实数的可能估值可以如下所示,但如果我们取小数点后的前七位数字,则所有实数的估值都是相同的

1197325/13631488=0.087835238530

19157213/218103808=0.087835298134

153257613/1744830464=0.087835245980

1226060865/13958643712=0.087835243186

我希望SMT解算器将所有这四个数字视为一个数字(以便减少搜索空间)。有没有办法控制实数的精度

我尝试通过编程(使用z3dotnetapi)来解决上述问题,如下所示。这里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());
}
{
BoolExpr[]_Exprs=新的BoolExpr[nbuse];

对于(j=1;j如果你觉得有必要控制实数的“精度”,那么这就强烈地表明
real
不是解决问题的正确领域。一些想法,取决于你真正想做什么:

  • 如果您只关心小数点后的6位数字,那么您可以使用普通的
    Integer
    s,将所有值乘以
    1e6
    ,并将所有变量限制为小于
    1e6
    ;或其他类似的转换

  • 请记住,现在Z3支持IEEE浮点数,这是有限精度的定义。因此,如果您的域确实是IEEE-754规定的浮点数,则可以使用这些浮点数

  • >P>如果你试图生成“连续”的结果,即通过解决问题,然后添加约束结果应该与前一个不同,然后调用Z3;然后你可以考虑添加一个约束,该新的结果与旧的不同,绝对值大于<代码> 1E6 < < /P>

这些是否适用取决于您试图解决的确切问题。如果您能分享更多您的问题,人们可能会想出其他想法。但第一个选择应该是确定
Real
是否真的是您想要处理的领域。

谢谢您的回复。我不能使用整数术语作为我的答案实际问题需要浮点值。我已经应用了第三个,以查看通过添加精度约束可以得到多少不同的结果。但是,我的程序包含第二个部分,这取决于这些潜在值。我不希望将这两个部分分离,并以编程方式将它们组合在一起(即,模型外部)。我想你的第二个建议可能会奏效。你能给我提供任何链接或详细的建议来帮助我更多地了解这一点吗?我认为Z3 Dot Net API不支持IEEE浮点数。是吗?FP支持是相当新的,如果目前只支持SMT Lib,我不会感到惊讶。但是Z3的一位成员需要确认rm。有关更多信息,请参阅。是的,目前我们有SMTlib格式的FPA支持,并通过Z3新分支中的API,称为FPA API: