Z3 根据解算器执行get模型或unsat核心';s的决定

Z3 根据解算器执行get模型或unsat核心';s的决定,z3,smt,mathsat,Z3,Smt,Mathsat,我想知道SMT-LIB 2.0脚本中是否有可能访问解算器的最后一个可满足性决策(sat、unsat等)。例如,以下代码: (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) :n

我想知道SMT-LIB 2.0脚本中是否有可能访问解算器的最后一个可满足性决策(sat、unsat等)。例如,以下代码:

(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)
在Z3中运行返回:

unsat
(error "line 15 column 10: model is not available")
(PQ QR nPR)
并在MathSAT返回中运行:

unsat
(error "model generation not enabled")
在MathSat5中,它只是中断(获取模型),甚至没有到达(获取未sat核心)。 在SMT-LIB2.0语言中,当决策为SAT时,是否有任何方法可以获取模型,当决策为unsat时,是否有任何方法可以获取unsat核心?例如,解决方案可能如下所示:

(check-sat)
(ite (= (was-sat) true) (get-model) (get-unsat-core))
我搜索了SMT-LIB2.0语言文档,但没有找到任何提示

编辑: 我也尝试了下面的代码,不幸的是它没有工作

(ite (= (check-sat) "sat") (get-model) (get-unsat-core))

SMT语言不允许您编写这样的命令。 像Boogie这样的工具处理这个问题的方式是使用 双向文本管道:它从(检查sat)读取结果。 如果结果字符串为“unsat”,则模型不可用,但 如果支票使用假设,则核心将为。如果结果是 字符串是“sat”,该工具可以使用(get model)命令
成功

正如Nikolaj在回答中所说,正确的方法是解析解算器输出并有条件地生成
(获取模型)
(获取unsat核心)
语句

但是,使用mathsat,您可以在不使用
(get model)
语句的情况下使用代码,并使用
-model
选项调用
mathsat
。例如:

$ 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")
在unsat案例中:

$ 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 )

不幸的是,似乎不存在像
-model
这样的选项来生产unsat内核。因此,如果您想将其用于增量问题,则此攻击将不起作用,除非您同意在第一个
sat
结果之后终止解算器。(因为在第一次
sat
结果时,解算器将退出
(获取unsat核心)
)的错误。

谢谢您的回复。我正在考虑这个选项,但如果可能的话,我更愿意将单个文件作为输入传递给解算器,然后读取结果。我认为以我所提到的方式执行检查的能力应该被纳入下一版本的SMT-LIB语言中,因为现在它是一种使用交互模式的力量。谢谢你的回复。最后,我按照尼古拉的建议实现了这一点。我刚刚测试了mathsat的-model选项,它实际上可以运行一次解算器,解析整个输出并获取模型或unsat核心。在Z3中,从一开始就有可能,因为它不会因错误而中断。我想在我的项目中支持任何符合SMT-LIB 2.0的解算器,而这两个解算器的不同行为+缺乏对非交互模式的真正SMT-LIB支持使得我在这种情况下使用了最可靠的交互方法。现在我不知道,我应该接受哪个答案…@Mr525我会接受尼古拉的答案。我本想把我的作为简单的评论发布,但我不能,因为我想发布代码示例以获得最大的清晰度。另外:如果你将一个问题标记为“z3”,而z3的作者需要时间来回答,那么我认为他应该为此获得“额外的互联网点数”。)无可争辩