Z3Py中的量词错误

时间:2018-07-26 03:20:52

标签: python z3 z3py

我希望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())

1 个答案:

答案 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