Performance Z3:if-then-else与命题逻辑的性能

Performance Z3:if-then-else与命题逻辑的性能,performance,z3,Performance,Z3,在Z3中,有(至少)两种表达if-then-else的方法——使用ite表达式和使用命题逻辑: (ite X Y Z) (and (=> X Y) (=> (not X) Z)) 第二个表达式的缺点是它重复了X。如果X非常大(或者我们有很多这样的表达式),这可能会显著增加术语的大小。我们可以通过引入一个新变量来缓解这种情况,比如说X\u is\u true: (and (= X_is_true X) (=> X_is_true Y) (=> (not X_is_tru

在Z3中,有(至少)两种表达if-then-else的方法——使用
ite
表达式和使用命题逻辑:

(ite X Y Z)

(and (=> X Y) (=> (not X) Z))
第二个表达式的缺点是它重复了
X
。如果
X
非常大(或者我们有很多这样的表达式),这可能会显著增加术语的大小。我们可以通过引入一个新变量来缓解这种情况,比如说
X\u is\u true

(and (= X_is_true X) (=> X_is_true Y) (=> (not X_is_true) Z))
我的问题是:
ite
在其中一种编码之上是否本质上是语法糖?如果没有,它的时间/空间效率与这些编码相比如何

我的问题是:它本质上是在这些编码之上的语法糖吗

通常不需要。在您的示例中,
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
策略,其工作方式不同)

起初的 Z3的回应是

(goals
(goal
  (or (not X) Y)
  (or X Z)
  :precision precise :depth 1)
)
编码1 Z3的回应是

(goals
(goal
  (or (not X) Y)
  (or X Z)
  :precision precise :depth 2)
)
(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)
)
编码2 Z3的回应是

(goals
(goal
  (or (not X) Y)
  (or X Z)
  :precision precise :depth 2)
)
(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)
)
(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)
)