在Z3(Java)中,如何从模型中以小数(双精度)形式获取实际值?

在Z3(Java)中,如何从模型中以小数(双精度)形式获取实际值?,java,z3,Java,Z3,我正在尝试从由解算器计算的模型中获取实际值。但是,即使我已将pp.decimal设置为true(在SMT2文件中,并使用Global.setParameter),也只有在打印模型本身时才遵守 当我尝试使用model.getConstInterp获取model.getConstDecls的值时,它们都显示分数(这使得我使用Double.parseDouble的黑客解决方案不可行) 我想知道是否有任何方便的方法来获取模型中常量函数的值,而不必强迫我编写解析器(用于模型或它生成的算术表达式) 任何帮助

我正在尝试从由
解算器计算的
模型
中获取实际值。但是,即使我已将pp.decimal设置为true(在SMT2文件中,并使用
Global.setParameter
),也只有在打印模型本身时才遵守

当我尝试使用
model.getConstInterp
获取
model.getConstDecls
的值时,它们都显示分数(这使得我使用
Double.parseDouble
的黑客解决方案不可行)

我想知道是否有任何方便的方法来获取模型中常量函数的值,而不必强迫我编写解析器(用于模型或它生成的算术表达式)

任何帮助都将不胜感激

编辑以包含示例:

BoolExpr[] assertions = ctx.parseSMTLIB2String(smt, null, null, null, null);

// get solver from context (modelled upon assertions)
Solver solver = ctx.mkSolver();
solver.add(assertions);

switch (solver.check()) {
    case SATISFIABLE: {
        // fetch our model
        Model model = solver.getModel();
        System.out.println(model);

        for(FuncDecl constant : model.getConstDecls()) {
            // get the interpretation
            Expr value = model.getConstInterp(constant);
            System.out.println(value.toString());
输出:

(define-fun b () Real
  (- 1.0))
(define-fun w2 () Real
  0.5)
(define-fun w1 () Real
  0.5)
-1
1/2
1/2
我希望以某种方式将这些常量函数的结果提取到Java
double
s中。我可以简单地解析
Expr
s'
toString()
的值,如果它们都遵守
pp.decimal

在轻度挖掘之后(超出了查看自动完成建议的范围),我发现您可以简单地检查您拥有的
Expr
是否为
RatNum
。从那里,您可以向上转换为
RatNum
并使用
getNumerator
getDenominator()
以这种方式除法生成一个
double

Expr value = model.getConstInterp(constant);
if(value.isRatNum()) {
    RatNum rational = (RatNum) value;
    IntNum num = rational.getNumerator(), den = rational.getDenominator();
    System.out.println("Value = " + ((double) num.getInt() / den.getInt()));
}

现在这是有道理的。

StackOverflow的效果最好,如果您可以发布一个日志。它应该显示你得到的输出以及你期望或希望得到的结果。我编辑了这个问题,加入了示例代码@LeventErkokIf,这对你很有用,太好了!但请记住,除以两个整数得到一个double将受到舍入错误的影响,并且不会捕获真正的“真实”值;但我想你无法避免。此外,Z3
Real
值实际上是代数实数(即多项式的根),因此这些值也是不可触及的。