I am pretty sure it has something to do with the python API. Is there a way to get back a partial model from z3 even when the status is unknown
?
I am trying to get a model out of z3 even when the status returns unknown
result. It fails with raising an exception
for model not available
. Any suggestions what can be done?
I converted the assertions to smt-lib format using sexpr()
method from the z3 Solver
interface and it returns a partial model even when the status is unknown
. I have attached example below.
# -*- coding: utf-8 -*-
from z3 import *
x, y, z = Reals('x y z')
m, n, l = Reals('m n l')
u, v = Ints('u v')
S = SolverFor("NRA")
S.add(x >= 0)
S.add(y >= 30, z <= 50)
S.add(m >= 5, n >= 5)
S.add(m * x + n * y + l > 300)
S.add(ForAll([u, v], Implies(m * u + n * v + l > 300, u + v + z <= 50)))
print(S.check())
print(S.sexpr())
In SMMT-LIB Format
(set-option :print-success true)
(set-option :produce-unsat-cores true) ; enable generation of unsat cores
(set-option :produce-models true) ; enable model generation
(set-option :produce-proofs true) ; enable proof generation
(declare-fun x () Real)
(declare-fun y () Real)
(declare-fun z () Real)
(declare-fun m () Real)
(declare-fun n () Real)
(declare-fun l () Real)
(assert (>= x 0.0))
(assert (>= y 30.0))
(assert (<= z 50.0))
(assert (>= m 5.0))
(assert (>= n 5.0))
(assert (not (<= (+ (* m x) (* n y) l) 300.0)))
(assert (forall ((u Int) (v Int))
(let ((a!1 (<= (+ (* m (to_real u)) (* n (to_real v)) l) 300.0)))
(or (<= (+ (to_real u) (to_real v) z) 50.0) a!1))))
(check-sat)
(get-model)
I am running this file like this from the command line (terminal)
$ z3 example.py
Output :
success
success
success
success
success
success
success
success
success
success
success
success
success
success
success
success
success
unknown
(model
(define-fun z () Real
20.0)
(define-fun y () Real
30.0)
(define-fun l () Real
145.0)
(define-fun x () Real
0.0)
(define-fun n () Real
5.0)
(define-fun m () Real
5.0)
)
Any suggestions on how to get this model via the python interface directly?
The exception which z3 raises after model()
call on unknown
status.
unknown
Traceback (most recent call last):
File "C:\Python38\Lib\site-packages\z3\z3.py", line 6696, in model
return ModelRef(Z3_solver_get_model(self.ctx.ref(), self.solver), self.ctx)
File "C:\Python38\Lib\site-packages\z3\z3core.py", line 3759, in Z3_solver_get_model
_elems.Check(a0)
File "C:\Python38\Lib\site-packages\z3\z3core.py", line 1385, in Check
raise self.Exception(self.get_error_message(ctx, err))
Z3Exception: b'there is no current model'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "C:\Users\lahir\Documents\GitHub\codersguild\Research\tangram-solve\z3_tryouts.py", line 19, in <module>
print(S.model())
File "C:\Python38\Lib\site-packages\z3\z3.py", line 6698, in model
raise Z3Exception("model is not available")
Z3Exception: model is not available
Thanks