سؤال

The following program generates a Z3 model that cannot be printed (that is, print solver.model() throws an exception), using the latest version of Z3 from the master git branch (commit 89c1785b):

x = Int('x')
a = Array('a', IntSort(), BoolSort())
b = Array('b', IntSort(), BoolSort())
c = Array('c', BoolSort(), BoolSort())

e = ForAll(x, Or(Not(a[x]), c[b[x]]))
print e

solver = Solver()
solver.add(e)
c = solver.check()
print c
if c == sat:
    print solver.model()

produces:

ForAll(x, Or(Not(a[x]), c[b[x]]))
sat
Traceback (most recent call last):
  File "z3bug.py", line 16, in <module>
    print solver.model()
  File "src/api/python/z3.py", line 5177, in __repr__
  File "src/api/python/z3printer.py", line 939, in obj_to_string
  File "src/api/python/z3printer.py", line 841, in __call__
  File "src/api/python/z3printer.py", line 831, in main
  File "src/api/python/z3printer.py", line 760, in pp_model
  File "src/api/python/z3printer.py", line 794, in pp_func_interp
  File "src/api/python/z3.py", line 5088, in else_value
  File "src/api/python/z3.py", line 818, in _to_expr_ref
  File "src/api/python/z3core.py", line 2307, in Z3_get_ast_kind
z3types.Z3Exception: 'invalid argument'

I can also reproduce the same behavior in the online z3py interface, at http://rise4fun.com/Z3Py/lfQG. Slightly more debugging suggests that the model's assignment for c is a z3.FuncInterp that throws an 'invalid argument' exception when you call else_value() on it.

Is this a bug in Z3, or are my expectations not quite right? My expectation was that it should always be possible to get the else_value() of a FuncInterp, since otherwise it's not a complete function, but perhaps this is not always correct?

هل كانت مفيدة؟

المحلول

This is a bug in the Z3 Python printer. I fixed the bug, and the fix is already available at codeplex.

http://z3.codeplex.com/SourceControl/changeset/f8014f54c18a

To get the fix (now), we have to retrieve the "work-in-progress" (unstable) branch. The fix will be available in the master branch in the next official release. To retrieve the unstable branch, we should use:

git clone https://git01.codeplex.com/z3 -b unstable

Another option is to use print solver.model().sexpr(). It will use Z3 internal printer instead of the Python based one.

Regarding else_value(), its value may not be specified by Z3. The meaning it: it is a "don't care". That is, any interpretation can be used to satisfy the formula. I also fixed the Z3 Python API to return None when the else_value is not specified.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top