如何在Z3中实现自定义简化策略?

时间:2014-01-21 14:28:04

标签: c++ z3 simplify

在我的工具中,我使用将常数与整数变量进行比较的条件(例如y <100)。通常,一个变量有多个条件,我想简化这些情况。例如:y&lt; 100&amp;&amp; y!= 99应该变成y&lt;简化策略不会这样做,并且没有任何简化声音的论据可以帮助他们。

在代码中:

context c;
goal g(c);
expr x = c.int_const("x");
expr y = c.int_const("y");
solver s(c);
expr F = y < 100 && y != 99;
g.add(F);
tactic t = tactic(c, "simplify");
apply_result r = t(g);
for (unsigned i = 0; i < r.size(); i++) {
    std::cout << "subgoal " << i << "\n" << r[i] << "\n";
}

最后的输出返回:subgoal 0 (goal (not (<= 100 y)) (not (= y 99)))

而不是subgoal 0(goal(not(<= 99 y))或类似我想要的东西。

因此我想实现自己的简化策略。不幸的是我找不到怎么做。我知道,这个策略需要用C ++实现,但我怎样才能将我的策略引入Z3?

1 个答案:

答案 0 :(得分:3)

Z3策略存储在目录:src/tactic中。算术相关策略位于子目录arith中。您应该使用现有的策略作为实施策略的“模板”。 一个很好的例子是 https://z3.codeplex.com/SourceControl/latest#src/tactic/arith/normalize_bounds_tactic.cpp

为了在API和SMT 2.0前端提供新策略,我们必须包含一个包含ADD_TACTIC命令的注释。此命令指示Z3 mk_make脚本将所有内容粘合在一起。参数是:用于创建策略的策略名称,描述和C ++代码。

/*
  ADD_TACTIC("normalize-bounds",
             "replace a variable x with lower bound k <= x with x' = x - k.",
             "mk_normalize_bounds_tactic(m, p)")
*/
顺便说一句,您也可以尝试通过扩展现有策略来实现新功能,例如: https://z3.codeplex.com/SourceControl/latest#src/tactic/arith/propagate_ineqs_tactic.cpp