告诉Z3中松弛变量和原始变量之间的区别

时间:2013-04-09 15:32:00

标签: z3

我正在尝试创造一种新的切割来取代Z3中实施的gomory切割。 我设计了我的剪辑以使用用户输入的原始约束。 不幸的是,我发现约束的Z3预处理增加了松弛变量并改变了约束的结构。 我可以调整我的算法来处理Z3约束结构和松弛变量,但算法的一个关键部分需要知道哪些变量是松弛变量,哪些变量是原始变量。 我在Z3源代码中找不到任何帮助我这样做的东西。 我也尝试在线搜索解决方案但找不到任何东西。

有谁知道如何做到这一点?

由于

1 个答案:

答案 0 :(得分:3)

在文件mk_gomory_cut(row const & r)中的方法src/smt/theory_arith_int.h中,r是Simplex画面的一行。此外,基本变量x_i是整数,但它分配给非整数值。

迭代器it用于遍历行条目。每个条目基本上是一对a_ijx_j,其中a_ij是数字,x_j是(理论)变量。

theory_arith是文件src/smt/smt_context.h中定义的解算器的插件。该求解器结合了许多理论插件,例如theory_arith。它维护从表达式到理论变量的映射。此映射存储在名为enode的对象中。

方法get_enode(v)检索与理论变量v关联的enode。 此外,get_enode(v)->get_owner()返回与理论变量v相关联的表达式。

现在,假设我们想测试理论变量v是否松弛。 首先,我们可以使用以下方法检索关联的表达式:

   app * t = to_app(get_enode(v)->get_owner())

我使用to_app因为理论插件只处理基础术语(即,它们不包含自由变量)。 如果v是复合算术术语,例如t(+ a b),变量(* a b c)就会松弛。也就是说, slack 本质上是复合算术术语的“名称”。 我们可以使用以下方法测试:

  t->get_family_id() == get_id()

如果此表达式的计算结果为true,那么t是一个复合算术项,因此v是一个松弛。

备注:get_id()theory_arith的方法。实际上,每个理论插件都有这种方法。