我希望Z3检查它是否存在满足我的公式的整数t
。我收到以下错误:
Traceback (most recent call last):
File "D:/z3-4.6.0-x64-win/bin/python/Expl20180725.py", line 18, in <module>
g = ForAll(t, f1(t) == And(t>=0, t<10, user[t].rights == ["read"] ))
TypeError: list indices must be integers or slices, not ArithRef
代码:
from z3 import *
import random
from random import randrange
class Struct:
def __init__(self, **entries): self.__dict__.update(entries)
user = [Struct() for i in range(10)]
for i in range(10):
user[i].uid = i
user[i].rights = random.choice(["create","execute","read"])
s=Solver()
f1 = Function('f1', IntSort(), BoolSort())
t = Int('t')
f2 = Exists(t, f1(t))
g = ForAll(t, f1(t) == And(t>=0, t<10, user[t].rights == ["read"] ))
s.add(g)
s.add(f2)
print(s.check())
print(s.model())
答案 0 :(得分:1)
您正在混合和匹配Python和Z3表达式,尽管这是Z3py的重点,但这绝对并不意味着您可以随意混合/匹配它们。通常,您应该将所有“具体”部分保留在Python中,并将符号部分移交给“ z3”;仔细协调两者之间的互动。在您的特定情况下,您正在访问带有符号z3整数(user
)的Python列表(您的t
),这当然是不允许的。您必须使用Z3符号Array
来访问符号索引。
另一个问题是使用字符串("create"
/ "read"
等),并期望它们在符号世界中具有含义。这也不是打算使用z3py的方式。如果希望它们在符号世界中具有某种意义,则必须明确地对其建模。
我强烈建议您阅读http://ericpony.github.io/z3py-tutorial/guide-examples.htm,这是z3py的精彩介绍,其中包括许多高级功能。
话虽如此,我倾向于将您的示例编写如下:
from z3 import *
import random
Right, (create, execute, read) = EnumSort('Right', ('create', 'execute', 'read'))
users = Array('Users', IntSort(), Right)
for i in range(10):
users = Store(users, i, random.choice([create, execute, read]))
s = Solver()
t = Int('t')
s.add(t >= 0)
s.add(t < 10)
s.add(users[t] == read)
r = s.check()
if r == sat:
print s.model()[t]
else:
print r
请注意,如何使用符号域中的枚举类型Right
来建模您的“权限”。
当我多次运行该程序时,我得到:
$ python a.py
5
$ python a.py
9
$ python a.py
unsat
$ python a.py
6
请注意,如果“随机”初始化没有使任何用户拥有unsat
权限,则会产生read
。