简体   繁体   中英

Error with quantifier in Z3Py

I would like Z3 to check whether it exists an integer t that satisfies my formula. I'm getting the following error:

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

Code:

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())

You are mixing and matching Python and Z3 expressions, and while that is the whole point of Z3py, it definitely does not mean that you can mix/match them arbitrarily. In general, you should keep all the "concrete" parts in Python, and relegate the symbolic parts to "z3"; carefully coordinating the interaction in between. In your particular case, you are accessing a Python list (your user ) with a symbolic z3 integer ( t ), and that is certainly not something that is allowed. You have to use a Z3 symbolic Array to access with a symbolic index.

The other issue is the use of strings ( "create" / "read" etc.) and expecting them to have meanings in the symbolic world. That is also not how z3py is intended to be used. If you want them to mean something in the symbolic world, you'll have to model them explicitly.

I'd strongly recommend reading through http://ericpony.github.io/z3py-tutorial/guide-examples.htm which is a great introduction to z3py including many of the advanced features.

Having said all that, I'd be inclined to code your example as follows:

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

Note how the enumerated type Right in the symbolic land is used to model your "permissions."

When I run this program multiple times, I get:

$ python a.py
5
$ python a.py
9
$ python a.py
unsat
$ python a.py
6

Note how unsat is produced, if it happens that the "random" initialization didn't put any users with a read permission.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM