使用z3获取Int的域

时间:2017-02-06 10:41:54

标签: z3

有没有办法用z3获取Integer变量的特定域(假设变量属于有限域)?

我有以下一组约束:

1 <= X <= 5
2 <= Y <= 8
X + Y == T

我想获得:

3 <= T <= 13

甚至是一个更简单的案例:

1 <= X <= 10
5 <= X <= 15

我想得到:

5 <= X <= 10

这似乎很微不足道,但我找不到用z3获得这样一个答案的方法。

1 个答案:

答案 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表示最大化。