使用 Z3_solver_get_unsat_core 获取 unsat 核心

2024-01-31

假设这是非线性实数算术的约束集,例如

pred1 = (> (- (* (- v2_x v0_x) (- v1_y v0_y)) (* (- v2_y v0_y) (- v1_x v0_x))) 0)
pred2 = (> (- (* (- v1_x v0_x) (- v2_y v0_y)) (* (- v1_y v0_y) (- v2_x v0_x))) 0)

事实上,如果我们这样做

Z3_solver_assert(ctx,solver,pred1);
Z3_solver_assert(ctx,solver,pred2);
b = Z3_solver_check(ctx, solver);

b会不满意的。我想获得 unsat 核心(对于这个例子来说是微不足道的)。因此,我为每个谓词定义了一个谓词变量。可以说他们是p1 and p2.

Z3_ast p1 = mk_bool_var(ctx, "P1");
assumptions[i] = Z3_mk_not(ctx, p1);
Z3_ast g[2] = { pred1, p1 };
Z3_solver_assert(ctx,solver,Z3_mk_or(ctx, 2, g));
Z3_ast p2 = mk_bool_var(ctx, "P2");
assumptions[i] = Z3_mk_not(ctx, p2);
Z3_ast g[2] = { pred2, p2 };
Z3_solver_assert(ctx,solver,Z3_mk_or(ctx, 2, g));

然后我打电话Z3_solver_check_assumptions(ctx, solver, 2 , assumptions);

但这会返回Z3_L_UNDEF原因是(incomplete (theory arithmetic))

我想知道我在哪里犯了错误以及如何解决这个问题。

以下是初始化的方式:

  ctx = Z3_mk_context(cfg);
  Z3_symbol logic_symbol = Z3_mk_string_symbol(ctx, "QF_UFNRA");
  solver = Z3_mk_solver_for_logic((Z3_context)ctx, logic_symbol);
  Z3_solver_inc_ref(ctx, solver);
  Z3_params params = Z3_mk_params(ctx);
  Z3_symbol param_symbol = Z3_mk_string_symbol(ctx, "unsat_core");
  Z3_params_set_bool(ctx , params, param_symbol, Z3_L_TRUE);
  Z3_solver_set_params(ctx, solver, params); 

Thanks,


Z3 包含许多求解器。对于非线性算术问题,它使用nlsat。该求解器的实现位于目录中src/nlsat,并解释了算法here http://research.microsoft.com/en-us/um/people/leonardo/files/IJCAR2012.pdf。然而,当前nlsat实施不支持 unsat 核心提取或证明生成。当用户请求unsat核心提取时,Z3切换到对于非线性算术不完整的通用求解器。也就是说,它可能会返回unknown用于非线性算术问题。通用求解器支持许多理论、量词、unsat 核心提取和证明生成。它是完整的linear算术,但正如我所说,对于非线性片段来说它并不完整。计划中,Z3将会有新版本nlsat与其他理论相结合并支持 unsat 核心提取,但这是未来的工作。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Z3_solver_get_unsat_core 获取 unsat 核心 的相关文章

随机推荐