在Z3中,有(至少)两种表达if-then-else的方式 - 使用ite
表达式,并使用命题逻辑:
(ite X Y Z)
(and (=> X Y) (=> (not X) Z))
第二个表达式的缺点是它重复了X
。如果X
非常大(或者我们有很多这样的表达式),这可能会大大增加术语的大小。我们可以通过引入一个新变量来缓解这个问题,比如X_is_true
:
(and (= X_is_true X) (=> X_is_true Y) (=> (not X_is_true) Z))
我的问题是:ite
在这些编码之一上基本上是语法糖吗?如果没有,它的时间/空间效率如何与这些编码相比?
答案 0 :(得分:3)
我的问题是:在这些编码之一的基础上,迭代主要是语法糖吗?
一般没有。在您的示例Y
和Z
中,不需要Bool
排序。例如
(declare-fun a () Float64)
(declare-fun b () Float64)
(declare-fun c () Float64)
(declare-fun d () Bool)
(assert (= c (ite d a b)))
(check-sat)
由于a
和b
的排序Float64
不是Bool
,因此您的转换不起作用。从技术上讲,如果ite
在=
运算符之外悬挂,则可以应用您的转换
(declare-fun a () Float64)
(declare-fun b () Float64)
(declare-fun c () Float64)
(declare-fun d () Bool)
(assert (ite d (= c a) (= c b)))
(check-sat)
但是我不确定这种转换是否总是可行的,而且你有时必须应用语义保留转换这一事实意味着你的转换不是合成糖。
修改强>
它的时间/空间效率与这些编码相比如何?
这很难回答,因为答案取决于您使用的逻辑和使用的求解方法。我也不太了解Z3的实现,给你一个很好的答案。
然而,作为调查的起点,您可以了解如果您尝试应用Tseitin变换会发生什么。这是在急切地将问题转换为SAT时经常使用的步骤。但请注意,这是不 Z3将执行的操作(它应用其smt
策略,其工作方式不同。)
(declare-const X Bool)
(declare-const Y Bool)
(declare-const Z Bool)
(assert (ite X Y Z))
(apply (and-then tseitin-cnf))
Z3以
回应(goals
(goal
(or (not X) Y)
(or X Z)
:precision precise :depth 1)
)
(declare-const X Bool)
(declare-const Y Bool)
(declare-const Z Bool)
(assert (and (=> X Y) (=> (not X) Z)))
(apply (and-then tseitin-cnf))
Z3以
回应(goals
(goal
(or (not X) Y)
(or X Z)
:precision precise :depth 2)
)
(declare-const X Bool)
(declare-const Y Bool)
(declare-const Z Bool)
(declare-const X_is_true Bool)
(assert (and (=> X_is_true Y) (=> (not X_is_true) Z)))
(assert (= X X_is_true))
(apply (and-then tseitin-cnf))
Z3以
回应(goals
(goal
(or (not X_is_true) Y)
(or X_is_true Z)
(or X (not X_is_true))
(or (not X) X_is_true)
:precision precise :depth 2)
)