3

I wonder, if there is a possibility in a SMT-LIB 2.0 script to access the last satisfiability decision of a solver (sat, unsat, ...). For example, the following code:

(set-option :produce-unsat-cores true)
(set-option :produce-models true)
(set-logic QF_UF)
(declare-fun p () Bool)
(declare-fun q () Bool)
(declare-fun r () Bool)

(assert (! (=> p q) :named PQ))
(assert (! (=> q r) :named QR))
(assert (! (not (=> p r)) :named nPR))

(check-sat)
(get-model)
(get-unsat-core)

ran in Z3 returns:

unsat
(error "line 15 column 10: model is not available")
(PQ QR nPR)

and ran in MathSAT returns:

unsat
(error "model generation not enabled")

In MathSAT 5 it just breaks on (get-model) and doesn't even reach (get-unsat-core). Is there any way in SMT-LIB 2.0 language to get-model iff the decision was SAT and unsat-core iff the decision was UNSAT? Solution could for example look like this:

(check-sat)
(ite (= (was-sat) true) (get-model) (get-unsat-core))

I searched SMT-LIB 2.0 language documentation, but I did not found any hint.

EDIT: I also tried the code below, and unfortunately it did not work.

(ite (= (check-sat) "sat") (get-model) (get-unsat-core))
Patrick Trentin
  • 7,126
  • 3
  • 23
  • 40
Mr 525
  • 75
  • 8

2 Answers2

3

The SMT language does not let you write commands like this. The way that tools, such as Boogie, deal with this is to use a two-way text pipe: It reads back the result from (check-sat). If the resulting string is "unsat" models are not available, but cores would be if the check uses asssumptions. If the resulting string is "sat" the tool can expect that a (get-model) command succeeds.

Nikolaj Bjorner
  • 8,229
  • 14
  • 15
  • 1
    Thank you for the reply. I was considering this option, but if possible I would prefer to pass a single file as an input to the solver and just read the result. I think that capability to perform checks in the way I mentioned should be incorporated in the next edition of SMT-LIB language, because as it is now it kind of forces to use interactive mode. – Mr 525 Aug 25 '16 at 23:22
3

As Nikolaj said in his answer, the right way to do this is to parse the solver output and conditionally generate either a (get-model) or a (get-unsat-core) statement.

However, with mathsat you can use the code without the (get-model) statement, and call mathsat with the -model option. For example:

$ cat demo_sat.smt2 
(set-option :produce-unsat-cores true)
(set-option :produce-models true)
(set-logic QF_UF)
(declare-fun p () Bool)
(declare-fun q () Bool)
(declare-fun r () Bool)

(assert (! (=> p q) :named PQ))
(assert (! (=> q r) :named QR))
; (assert (! (not (=> p r)) :named nPR))

(check-sat)
(get-unsat-core)

$ mathsat -model demo_sat.smt2 
sat
( (p false)
  (q false)
  (r false) )
(error "no unsatisfiability proof, impossible to compute unsat core")

And in the unsat case:

$ cat demo_unsat.smt2 
(set-option :produce-unsat-cores true)
(set-option :produce-models true)
(set-logic QF_UF)
(declare-fun p () Bool)
(declare-fun q () Bool)
(declare-fun r () Bool)

(assert (! (=> p q) :named PQ))
(assert (! (=> q r) :named QR))
(assert (! (not (=> p r)) :named nPR))

(check-sat)
(get-unsat-core)

$ mathsat -model demo_unsat.smt2 
unsat
( PQ
  QR
  nPR )

Unfortunately there does not seem to exist an option like -model for producing unsat cores. So this hack won't work if you want to use it with an incremental problem, unless you are OK with the solver terminating after the first sat result. (Because at the first sat result the solver will exit on the error for (get-unsat-core).)

CliffordVienna
  • 7,995
  • 1
  • 37
  • 57
  • Thank you for your reply. In the end, I implemented this in the way Nikolaj suggested. I tested just now -model option for mathsat, and it actually makes it possible to run solver once, parse whole output and get either model or unsat core. In Z3 it was possible from the start, because it doesn't break on errors. I wanted to support in my project any SMT-LIB 2.0 compliant solver, and different behaviors of those two + lack of real SMT-LIB support for non-interactive mode made me use most reliable under these circumstances interactive approach. Now I don't know, which answer I should accept... – Mr 525 Sep 11 '16 at 17:13
  • @Mr525 I'd accept Nikolaj's answer. I would have posted mine as simple comment, but I couldn't because I wanted to post the code examples for maximum clarity. Also: If you tag a question as 'z3', and the author of z3 takes time to answer it, then I think he should get "extra internet points" for that. :) – CliffordVienna Sep 11 '16 at 17:22
  • Can't argue with that. ;) – Mr 525 Sep 11 '16 at 18:13