我正在尝试创造一种新的切割来取代Z3中实施的gomory切割。 我设计了我的剪辑以使用用户输入的原始约束。 不幸的是,我发现约束的Z3预处理增加了松弛变量并改变了约束的结构。 我可以调整我的算法来处理Z3约束结构和松弛变量,但算法的一个关键部分需要知道哪些变量是松弛变量,哪些变量是原始变量。 我在Z3源代码中找不到任何帮助我这样做的东西。 我也尝试在线搜索解决方案但找不到任何东西。
有谁知道如何做到这一点?
由于
答案 0 :(得分:3)
在文件mk_gomory_cut(row const & r)
中的方法src/smt/theory_arith_int.h
中,r
是Simplex画面的一行。此外,基本变量x_i
是整数,但它分配给非整数值。
迭代器it
用于遍历行条目。每个条目基本上是一对a_ij
和x_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
的方法。实际上,每个理论插件都有这种方法。