在我的工具中,我使用将常数与整数变量进行比较的条件(例如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?
答案 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