开发者

Scala^Z3 (Z3 Version 3.2) and parsesmtlib2string(...) not working

While trying to implement a test using parsesmtlib2string I hit an error:

println("Hello World!");
var smtlib2String = ""
smtlib2String += "(declare-fun x () bool)" + "\n"
smtlib2String += "(declare-fun y () bool)" + "\n"
sm开发者_Python百科tlib2String += "(assert (= x y))" + "\n"
smtlib2String += "(assert (= x true))" + "\n"
//  smtlib2String += "(check-sat)" + "\n"
//  smtlib2String += "(model)" + "\n"
smtlib2String += "(exit)" + "\n"

val cfg = new Z3Config
val z3 = new Z3Context(cfg)

z3.parseSMTLIB2String(smtlib2String)

When uncommenting "Check-sat" I get "unknown". When uncommenting "model" I get "unsupported".

Using F# with Z3 3.2 it would just give me a Term back, but in Scala the return type is Unit. I looked through the Z3-C API but didn't find a good example on how to use ist.

So, what is the best way to get a model using smtlib2string?

Btw: Using Scala^Z3 and building a Z3AST works just fine and I can get a model using .checkAndGetModel(). The SMT-LIB2 Code above works fine with the F# .NET parsesmtlib2string method.

Using one of "getSMTLIBFormulas, getSMTLIBAssumptions, getSMTLIBDecls, getSMTLIBSorts" yields "Error: parser (data) is not available".

Using "getSMTLIBError.size" yields "0".


The parseSMTLIB2[...] methods should indeed have returned a Z3AST, thanks for reporting the problem. This is fixed in scalaz3-3.2.b.jar. Now regarding the use of the SMT-LIB 2 parser, I'm myself new to this, so Leo should perhaps confirm, but my understanding is that you should only use it to parse formulas, not to issue commands such as (check-sat).

Here is an example that works for me:

import z3.scala._
val smtlib2String = """
  (declare-fun x () bool)
  (declare-fun y () bool)
  (assert (= x y))
  (assert (= x true))"""

val ctx = new Z3Context("MODEL" -> true)
val assertions = ctx.parseSMTLIB2String(smtlib2String)
println(assertions) // prints "(and (= x y) (= x true))"
ctx.assertCnstr(assertions)
println(ctx.checkAndGetModel._1) // prints "Some(true)", i.e. SAT

Now if you want to programmatically recover the model for x, my understanding is that the only way to do it is to create a symbol for x before parsing and to pass it to the parser, using the overloaded definition of the parseSMTLIB2[...] method. Here is how you do it:

val ctx = new Z3Context("MODEL" -> true)
val xSym = ctx.mkStringSymbol("x") // should be the same symbol as in the SMT-LIB string
val assertions = ctx.parseSMTLIB2String(smtlib2String, Map(xSym -> ctx.mkBoolSort), Map.empty)
ctx.assertCnstr(assertions)
val model = ctx.checkAndGetModel._2
val xTree = ctx.mkConst(xSym, ctx.mkBoolSort) // need a tree to evaluate using the model
println(model.evalAs[Boolean](xTree)) // prints "Some(true)"

Hope this helps.

(Again, there may be a simpler way to do this, but I'm not aware of it. The parsing methods are directly bound to their C equivalent and the only example I could find doesn't show much.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜