3

Suppose I have a list of 10 variables

v = [Real('v_%s' % (i+1)) for i in range(10)]

and I want to add a simple constraint like this

s = Solver()
for i in range(10):
    s.add(v[i] == i)
if s.check() == sat:
    print(s.model())

So a satisfying model is v_1 = 0, v_2 = 1 .... v_10 = 9. However the output of print(s.model()) is totoally unordered which makes me confused when I have lots of variables in a bigger model. For this example, the output of my computer is v_5, v_7, v_4, v_2, v_1, v_3, v_6, v_8, v_9, v_10, but I want to ouput the variables of this model in order like v_1, v_2, ..., v_10. Can anyone tell me does z3Py have this kind of function or not? Thanks!

Francis
  • 189
  • 1
  • 11

2 Answers2

3

You can turn the model into a list and sort it in any way you like:

from z3 import *

v = [Real('v_%s' % (i+1)) for i in range(10)]

s = Solver()
for i in range(10):
    s.add(v[i] == i)
if s.check() == sat:
    m = s.model()
    print (sorted ([(d, m[d]) for d in m], key = lambda x: str(x[0])))

This prints:

[(v_1, 0), (v_10, 9), (v_2, 1), (v_3, 2), (v_4, 3), (v_5, 4), (v_6, 5), (v_7, 6), (v_8, 7), (v_9, 8)]

Note that the names are sorted lexicographically, hence v_10 comes after v_1 and before v_2. If you want v_10 to come at the end, you can do further processing as it fits your needs.

alias
  • 28,120
  • 2
  • 23
  • 40
0

When you work with a vector like an IntVector, you can call the element on the i position with m[v[i]] where m is the model, v is the vector and i is desidered position:

v = IntVector('v', 10)

for i in range(10):
    s.add(v[i] == i)

s = Solver()
if (s.check()):
    m = s.model()

    for i in range(10):
        print(m[v[i]])

It will not print the i-element on the model, but the correct element in the original position.

In your case you can do the same thing:

v = [Real('v_%s' % (i+1)) for i in range(10)]

for i in range(10):
    s.add(v[i] == i)

s = Solver()
if (s.check()):
    m = s.model()

    for i in range(10):
        print(m[v[i]])
Marco Lampis
  • 403
  • 5
  • 15