有没有办法在 z3py 中使用 Z3ints 的范围?

Is there a way to use range with Z3ints in z3py?

我对 Z3 比较陌生,在 python 中进行了试验。我编写了一个程序,其中 returns 执行不同操作的顺序,用数字表示。 Z3 returns 表示动作开始的秒数的整数。

现在我想看看这个模型,看看是否有一个没有任何反应的时间实例。为此,我制作了一个只有 0 的列表,我想在执行每个动作时将索引更改为 1。例如,如果一个动作从第 5 秒开始并需要 8 秒才能执行,则索引 5 到 12 将设置为 1。对所有操作执行此操作,然后在列表中查找 0 将有望为我提供没有任何反应的实例。

问题是:我想写这样的东西来编码问题

list_for_check = [0]*total_time
m = s.model()
for action in actions: 
    for index in range(m.evaluate(action.number) , m.evaluate(action.number) + action.time_it_takes):
        list_for_check[index] = 1

但是我得到错误:

'IntNumRef' object cannot be interpreted as an integer

我知道 Z3 在他们的模型中不返回正常的整数或布尔值,而是写

if m.evaluate(action.boolean):

有效,所以我假设 if 以某种方式被覆盖,但范围似乎并非如此。所以我的问题是:有没有办法将范围与 Z3 整数一起使用?或者还有其他方法吗?

问题也可能是 action.time_it_takes 是一个整数,添加一个带有“普通”int 的 Z3int 不起作用。 (在范围的第二部分完成)。

我也尝试过使用 int(m.evaluate(action.number)),但它不起作用。

提前致谢:)

当你调用 evaluate 时,它 returns 一个 IntNumRef,它是 z3 中整数的内部 z3 表示。您需要调用它的 as_long() 方法将其转换为 Python 数字。这是一个例子:

from z3 import *

s = Solver()
a = Int('a')

s.add(a > 4);
s.add(a < 7);

if s.check() == sat:
    m = s.model()
    print("a is %s" % m.evaluate(a))
    print("Iterating from a to a+5:")
    av = m.evaluate(a).as_long()
    for index in range(av, av + 5):
        print(index)

当我 运行 这个时,我得到:

a is 5
Iterating from a to a+5:
5
6
7
8
9

这正是您要实现的目标。

方法as_long()定义here. Note that there are similar conversion functions from bit-vectors and rationals as well. You can search the z3py api using the interface at: https://z3prover.github.io/api/html/namespacez3py.html