是Z3';s搜索时间对公式顺序敏感?

是Z3';s搜索时间对公式顺序敏感?,z3,smt,theorem-proving,Z3,Smt,Theorem Proving,在许多编程语言中,分支效率取决于子句的提供顺序。例如,在Python中 if p or q : 只要p的计算结果为true,就会分支到if语句,因此通常最好首先提供计算量较小的子句。我想知道Z3中的可满足性检查是否也是如此。换句话说,检查和(P,Q)和和(Q,P)之间是否有任何区别,前提是其中一个公式比另一个公式复杂得多?是的,它可以改变您指定子句的顺序。然而,当涉及Z3时,重新安排条款可能不会有什么好处。此外,事先确定一个通用的“最佳顺序”可能很困难(也许不值得) 与其他SMT解算器一起,我

在许多编程语言中,分支效率取决于子句的提供顺序。例如,在Python中

if p or q :

只要
p
的计算结果为true,就会分支到if语句,因此通常最好首先提供计算量较小的子句。我想知道Z3中的可满足性检查是否也是如此。换句话说,检查
和(P,Q)
和(Q,P)
之间是否有任何区别,前提是其中一个公式比另一个公式复杂得多?

是的,它可以改变您指定子句的顺序。然而,当涉及Z3时,重新安排条款可能不会有什么好处。此外,事先确定一个通用的“最佳顺序”可能很困难(也许不值得)

与其他SMT解算器一起,我观察到了您以极端方式描述的内容。对于某些解算器,它可以完成或中断计算,从某种意义上说,我看到过这样的情况:当子句以一种顺序呈现时,解算器会超时,但当相同的子句以不同的顺序呈现时,解算器会很快找到解决方案。然而,对我来说,这是一个设计拙劣的解决方案的迹象。Z3和其他现代SMT解算器(如CVC4)比旧的或不太健壮的SMT解算器更不容易受到此类问题的影响

关于实际寻找最佳排序,SMT解算器的“计算轻”或“更复杂”的组成部分与传统计算机语言不同。真正重要的是连接词中的某个子句是否可能导致冲突,或者析取词中的某个特定子句是否可能导致解决方案。这类似于试图找到走出迷宫的路——如果你一开始就拐错了弯,那么你可能会在一条死胡同后花很长一段时间,然后才最终决定回到起点,走另一条路。同样,现代SMT和SAT解决方案也有缓解这一问题的技术

另外,具体到Z3,如果Z3可以在现实世界的应用程序中更有效地根据一些人类可以理解的通用复杂性度量对子句进行排序,那么这可能已经作为Z3的预处理步骤添加了。一般来说,对于这种复杂的优化问题,有多个因素在起作用(例如,Z3实现的细节),您必须尝试多种方法,并对与您的应用程序相关的一组测试示例进行基准测试

作为我上述一些主张的一点证据,我写了这个SMT问题的小例子:

(declare-fun p () Int)
(declare-fun q () Int)
(declare-fun n () Int)
(assert (> p 1))
(assert (> q 1))
(assert (and (= n 18679565357) (= n (* p q))))
(check-sat)
(get-value (p q n))
(exit)
语句中交换子句的顺序对我的系统影响很小(小于1%)。如果我将其分解为两个独立的断言,那么差异会更大,但要知道这种差异是否普遍存在(在这个类的不同SMT问题中),我必须运行一个包含许多此类问题的基准测试套件