有没有办法用z3获取Integer变量的特定域(假设变量属于有限域)?
我有以下一组约束:
1 <= X <= 5
2 <= Y <= 8
X + Y == T
我想获得:
3 <= T <= 13
甚至是一个更简单的案例:
1 <= X <= 10
5 <= X <= 15
我想得到:
5 <= X <= 10
这似乎很微不足道,但我找不到用z3获得这样一个答案的方法。
答案 0 :(得分:1)
您可以使用Z3的优化例程来解决这些类型的约束。您的第一个问题可以编码为:
(declare-const X Int)
(declare-const Y Int)
(declare-const T Int)
(assert (<= 1 X 5))
(assert (<= 2 Y 8))
(assert (= (+ X Y) T))
(push)
(minimize T)
(check-sat)
(pop)
(maximize T)
(check-sat)
z3回应:
sat
(objectives
(T 3)
)
sat
(objectives
(T 13)
)
如果你眯着眼睛,说3 <= T <= 13
;正如你想要找到的那样。
您也可以使用Python界面执行相同操作。您的第二个示例可以在z3py中编码,如下所示:
from z3 import *
X = Int('X')
s = Optimize()
s.add(1 <= X); s.add(X <= 10)
s.add(5 <= X); s.add(X <= 15)
s.push()
s.minimize(X)
s.check()
print s.model()
s.pop()
s.maximize(X)
s.check()
print s.model()
产生:
[X = 5]
[X = 10]
表示5 <= X <= 10
。
如果您想避免两次调用求解器,那么您可以使用box
参数进行优化,从而独立优化目标:
(declare-const X Int)
(declare-const Y Int)
(declare-const T Int)
(assert (<= 1 X 5))
(assert (<= 2 Y 8))
(assert (= (+ X Y) T))
(minimize T)
(maximize T)
(set-option:opt.priority box)
(check-sat)
现在,z3回应:
sat
(objectives
(T 3)
(T 13)
)
其中包含给定顺序的结果,即3
表示最小化,13
表示最大化。