I am working with the ocaml for Z3 in order to name each constraints when getting unsat core such as
(set-option :produce-unsat-cores true)
(declare-fun x () Int)
(assert (!(> x 0) :named p1))
(assert (!(not (= x 1)) :named p2))
(assert (!(< x 0) :named p3))
(check-sat)
(get-unsat-core)
The result is unsat
. Then I found a API assert_and_track
in ocaml for Z3 and a solution in python (Unsatisfiable Cores in Z3 Python), and then I have the following simple example:
from z3 import *
x = Int('x')
s = Solver()
s.set(unsat_core=True)
s.assert_and_track(x > 0, 'p1')
s.assert_and_track(x != 1, 'p2')
s.assert_and_track(x < 0, 'p3')
print(s.check())
print(s.to_smt2())
c = s.unsat_core()
for i in range(0, len(c)):
print(c[i])
The result of this example is
unsat
; benchmark generated from python API
(set-info :status unknown)
(declare-fun x () Int)
(declare-fun p1 () Bool)
(declare-fun p2 () Bool)
(declare-fun p3 () Bool)
(assert
(let (($x7 (> x 0)))
(=> p1 $x7)))
(assert
(let (($x33 (and (distinct x 1) true)))
(=> p2 $x33)))
(assert
(let (($x40 (< x 0)))
(=> p3 $x40)))
(check-sat)
p1
p3
Then I copy the generated SMT2 format to z3 and found the result is sat
. Why the generated z3 smt2 format code from python is inconsistent with python, and How can I use this in ocaml?