Z3 Python 从解决方案中排除跟踪器变量

Z3 Python exclude tracker variables from solution

我正在使用 Z3 Python API 并且我有以下代码来获得无法满足的内核:

for idx, constr in enumerate(z3constrs):
    solver.assert_and_track(constr, f'tracker{idx}')

但是,模型的解决方案包含跟踪器变量:

>>> print(solver.model())
[tracker71 = True,
 tracker229 = True,
 rect11_x1 = 35,
 ...]

有没有什么方法可以在不 运行 解算器两次的情况下从解决方案中删除这些变量(同时将其保留为 ModelRef 对象)?

简短回答:不。这些变量是模型的一部分,因此当您使用 solver.model() 导致其他调用(例如 m.evaluate(expr))时,它们的存在很重要。因此,您不能“忽略”它们,同时仍将结果保持为 ModelRef.

但是你可以问这个问题,为什么在那种情况下你需要结果是 ModelRef?通过消除跟踪器变量,您违反了有关模型构建方式的内部不变量。如果您只是担心不在模型中显示它们或传递包含除跟踪器以外的所有内容的数据结构,那么典型的做法是简单地创建一个对列表并使用它。这是一个例子:

from z3 import *

a = Int('a')
s = Solver()
s.assert_and_track(a > 3, 'tracker1')
s.check()
m = s.model()
clean_m = []
for d in m.decls():
    if not(d.name().startswith("tracker")):
       clean_m += [(d, m[d])]
print(m)
print(clean_m)

这会打印:

[tracker1 = True, a = 4]
[(a, 4)]

显然,您可以 post 进一步处理结果,以任何您想要的方式塑造它们。