Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

In Z3-Python, I get "builtin_function_or_method' object is not iterable" when performing model search

I am exploring fast ways to perform SAT solving in Z3 (Python). To do so, I am trying to imitate the results of Chapter 5.1 of https://theory.stanford.edu/~nikolaj/programmingz3.html#sec-blocking-evaluations.

The code I am using is the following:

def block_modelT(s, terms): #I used the name 'block_modelT' so as not to use 'block_model'
    m = s.model()
    s.add(Or([t != m.eval(t) for t in terms]))

def all_smt(s, terms):
    while sat == s.check():
       print(s.model())
       block_modelT(s, terms)

Thus, I execute it:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

pip install z3-solver
from z3 import *

x, y, z = Bools('x y z')
vars = [x,y,z]

phi_0 = x #ignore that I call them phi: it is because I am used to do it like that for predicates (i.e. literals) of other theories: e.g., if x is Int, then phi_0 = (x>0)
phi_1 = y
phi_2 = z

phi = And(phi_0, Or(phi_1, phi_2))

all_smt(s, vars)

And get the following error:

      1 def block_modelT(s, terms):
      2     m = s.model()
----> 3     s.add(Or([t != m.eval(t) for t in terms]))

TypeError: 'builtin_function_or_method' object is not iterable

Any help?

EDIT:

The problem has been solved so I finally try the next piece of code:

def all_smt(s, initial_terms):
    def block_term(s, m, t):
        s.add(t != m.eval(t))
    def fix_term(s, m, t):
        s.add(t == m.eval(t))
    def all_smt_rec(terms):
        if sat == s.check():
           m = s.model()
           yield m
           for i in range(len(terms)):
               s.push()
               block_term(s, m, terms[i])
               for j in range(i):
                   fix_term(s, m, terms[j])
               for m in all_smt_rec(terms[i:]):
                   yield m
               s.pop()   
    for m in all_smt_rec(list(initial_terms)):
        yield m   

I execute it: all_smt(s, varss) #has the same name. And get a generator <generator object all_smt at 0x7... instead of a valid assignment (i.e. a model). How can obtain the correct answer [z = False, y = True, x = True], [z = True, x = True]? I tried both print and return.

>Solution :

Your program doesn’t define an s; and you haven’t added the formula to it. The following works for me:

from z3 import *

def block_modelT(s, terms): #I used the name 'block_modelT' so as not to use 'block_model'
    m = s.model()
    s.add(Or([t != m.eval(t) for t in terms]))

def all_smt(s, terms):
    while sat == s.check():
       print(s.model())
       block_modelT(s, terms)

x, y, z = Bools('x y z')
vars = [x,y,z]

phi_0 = x #ignore that I call them phi: it is because I am used to do it like that for predicates (i.e. literals) of other theories: e.g., if x is Int, then phi_0 = (x>0)
phi_1 = y
phi_2 = z

phi = And(phi_0, Or(phi_1, phi_2))

s = Solver()
s.add(phi)

all_smt(s, vars)

This prints:

[z = False, y = True, x = True]
[z = True, x = True]
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading