Scala ^Z3(Z3版本3.2)和parsesmtlib2string(…)不工作

Scala ^Z3(Z3版本3.2)和parsesmtlib2string(…)不工作,scala,z3,Scala,Z3,尝试使用parsesmtlib2string实现测试时,我遇到了一个错误: println("Hello World!"); var smtlib2String = "" smtlib2String += "(declare-fun x () bool)" + "\n" smtlib2String += "(declare-fun y () bool)" + "\n" smtlib2String += "(assert (= x y))" + "\n" smtlib2String += "(as

尝试使用parsesmtlib2string实现测试时,我遇到了一个错误:

println("Hello World!");
var smtlib2String = ""
smtlib2String += "(declare-fun x () bool)" + "\n"
smtlib2String += "(declare-fun y () bool)" + "\n"
smtlib2String += "(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)
当取消注释“Check sat”时,我得到“unknown”。 当取消注释“model”时,我得到“unsupported”

将F#与Z3.2一起使用只会返回一个术语,但在Scala中,返回类型是Unit。我浏览了Z3-CAPI,但没有找到一个关于如何使用ist的好例子

那么,使用smtlib2string获取模型的最佳方法是什么

顺便说一句:使用Scala^Z3和构建Z3AST工作得很好,我可以使用.checkAndGetModel()获得一个模型。上面的SMT-LIB2代码与F#.NET parsesmtlib2string方法配合使用效果良好

使用“getSMTLIBFormulas、getSMTLIBAssumptions、getSMTLIBDecls、getSMTLIBSorts”中的一个会产生“错误:解析器(数据)不可用”


使用“getSMTLIBError.size”会产生“0”。
parseSMTLIB2[…]
方法确实应该返回一个
Z3AST
,感谢您报告此问题。这是固定的。现在,关于SMT-LIB 2解析器的使用,我自己还不熟悉,所以Leo也许应该确认一下,但我的理解是,您应该只使用它来解析公式,而不是发出诸如
(check sat)
之类的命令

下面是一个适合我的例子:

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
现在,如果您想以编程方式恢复
x
的模型,我的理解是,唯一的方法是在解析之前为
x
创建一个符号,并使用
parseSMTLIB2[…]
方法的重载定义将其传递给解析器。以下是您的操作方法:

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)"
希望这有帮助


(同样,可能有一种更简单的方法可以做到这一点,但我不知道。解析方法直接绑定到它们的C等价物上,并且没有显示太多。)

干得好!您还有一个名为“.checkAndGetAllModels()”的函数,我甚至还没有找到与.NET或C等效的函数。。。这对我来说很好。你是怎么做到的?非常感谢。Levent Erkok在另一篇帖子中询问了这一特性:“Z3:一种更好的建模方法?”Philippe是正确的,函数
parseSMTLIB2String
应该用于解析公式。诸如
check sat
之类的命令被该命令忽略。checkAndGetAllModels函数只是使用push和pops将先前模型的否定添加到上下文中,没有什么特别之处。顺便说一句,您可能不应该尝试在两个调用之间向结果迭代器推送新的约束。