This simple example generates UNKNOWN for me, I suppose there is something that I don’t understand about def’s.
from z3 import *
s = Solver()
def Min(b, r):
return If(b, r, 1)
a = Real('a')
b = Bool('b')
s.add(a==0.9)
s.add(a<=Min(b,0.9))
s.check()
print "Presenting result "
m = s.model()
print "traversing model..."
for d in m.decls():
print "%s = %s" % (d.name(), m[d])
You did not make any mistake. This is a problem in one of Z3 solvers. Your problem is in a fragment of arithmetic called “difference-logic”. A problem in in this fragment, if the arithmetic atoms can be written as
x - y <= k, wherekis a numeral. When a problem is in this fragment, Z3 will use a specialized solver for it. However, this solver may fail (returnsunknown) when the input problem also contains if-then-else terms (theIfin yourMin).The bug has been fixed, and will be available in the next release. In the meantime, you can try one of the following workarounds:
Force Z3 to eliminate if-then-else terms before invoking the solver. You just have to replace
s = Solver()withs = Then('elim-term-ite', 'smt').solver(). Here is the modified script at rise4fun.We can add a redundant assertion that is not in the different logic fragment. Example:
z + w > 2. Here is the modified script at rise4fun.