z3处理非线性真实算术的局限性

时间:2012-12-04 20:30:40

标签: z3

我有一个程序在非线性实数算术中生成一组约束。考虑以下两个约束:

(<( - ( - ( - (+(*( - v0_x v3_x))                   ( - v1_y v3_y)                   (+(*( - v2_x v3_x)( - v2_x v3_x))                      (*( - v2_y v3_y)( - v2_y v3_y))))                (*( - v0_y v3_y)                   ( - v2_x v3_x)                   (+(*( - v1_x v3_x)( - v1_x v3_x))                      (*( - v1_y v3_y)( - v1_y v3_y))))                (*( - v1_x v3_x)                   ( - v2_y v3_y)                   (+(*( - v0_x v3_x)( - v0_x v3_x))                      (*( - v0_y v3_y)( - v0_y v3_y)))))             (*( - v1_y v3_y)                ( - v2_x v3_x)                (+(*( - v0_x v3_x)( - v0_x v3_x))                   (*( - v0_y v3_y)( - v0_y v3_y)))))          (*( - v0_y v3_y)             ( - v1_x v3_x)             (+(*( - v2_x v3_x)( - v2_x v3_x))(*( - v2_y v3_y)( - v2_y v3_y))))))       (*( - v0_x v3_x)          ( - v2_y v3_y)          (+(*( - v1_x v3_x)( - v1_x v3_x))(*( - v1_y v3_y)( - v1_y v3_y)))))    0)

(>( - ( - ( - (+(*( - v0_x v2_x))                   ( - v1_y v2_y)                   (+(*( - v3_x v2_x)( - v3_x v2_x))                      (*( - v3_y v2_y)( - v3_y v2_y))))                (*( - v0_y v2_y)                   ( - v3_x v2_x)                   (+(*( - v1_x v2_x)( - v1_x v2_x))                      (*( - v1_y v2_y)( - v1_y v2_y))))                (*( - v1_x v2_x)                   ( - v3_y v2_y)                   (+(*( - v0_x v2_x)( - v0_x v2_x))                      (*( - v0_y v2_y)( - v0_y v2_y)))))             (*( - v1_y v2_y)                ( - v3_x v2_x)                (+(*( - v0_x v2_x)( - v0_x v2_x))                   (*( - v0_y v2_y)( - v0_y v2_y)))))          (*( - v0_y v2_y)             ( - v1_x v2_x)             (+(*( - v3_x v2_x)( - v3_x v2_x))(*( - v3_y v2_y)( - v3_y v2_y))))))       (*( - v0_x v2_x)          ( - v3_y v2_y)          (+(*( - v1_x v2_x)( - v1_x v2_x))(*( - v1_y v2_y)( - v1_y v2_y))))))    0)

当我将它们断言为Z3时,它表示它是可以满足的,但是只要我将第二个约束改为(< ... 0)而不是(> ... 0),现在应该是不可满足的,z3永远运行。我想知道z3在处理非线性实数算术时的局限性。 Z3是否有可能处理上述限制(例如改变它们的制定方式或任何其他方式)?

1 个答案:

答案 0 :(得分:4)

是的,当我们将(< ... 0)更改为(> ... 0)时,问题就变得不可理解了,并且有一个简单的证明,因为它变为p < 0 and p > 0。简化后,帖子中的两个多项式是相同的。然而,Z3错过了这个简单的证明。这将在下一版本中修复。与此同时,我们可以通过使用自定义策略来捕获具有此类简单证据的示例。

(check-sat-using (then (! simplify :som true) (! simplify :sort-sums true) smt))

此策略执行多项式规范化并调用检测p < 0p > 0中的不一致性的引擎。整个示例可在线获取:http://rise4fun.com/Z3/JP4。我还在信息的最后粘贴了它。

Z3一直在运行,因为它错过了简短的证据,并试图使用更昂贵和完整的方法找到证据。 Z3使用的算法描述为here。该算法使用基于subresultants的投影算子。此操作非常昂贵,并为您的示例生成非常大的多项式。这个过程适用于包含小多项式的问题,每个小多项式都有一小组变量。在未来,我们计划将完整和不完整的技术结合起来,并改善Z3在合理的时间内可以解决的问题集。

(declare-const v0_x Real)
(declare-const v1_x Real)
(declare-const v2_x Real)
(declare-const v3_x Real)
(declare-const v4_x Real)
(declare-const v0_y Real)
(declare-const v1_y Real)
(declare-const v2_y Real)
(declare-const v3_y Real)
(declare-const v4_y Real)


(assert
(< (- (- (- (+ (* (- v0_x v3_x) (- v1_y v3_y) (+ (* (- v2_x v3_x) (- v2_x v3_x)) (* (- v2_y v3_y) (- v2_y v3_y)))) (* (- v0_y v3_y) (- v2_x v3_x) (+ (* (- v1_x v3_x) (- v1_x v3_x)) (* (- v1_y v3_y) (- v1_y v3_y)))) (* (- v1_x v3_x) (- v2_y v3_y) (+ (* (- v0_x v3_x) (- v0_x v3_x)) (* (- v0_y v3_y) (- v0_y v3_y))))) (* (- v1_y v3_y) (- v2_x v3_x) (+ (* (- v0_x v3_x) (- v0_x v3_x)) (* (- v0_y v3_y) (- v0_y v3_y))))) (* (- v0_y v3_y) (- v1_x v3_x) (+ (* (- v2_x v3_x) (- v2_x v3_x)) (* (- v2_y v3_y) (- v2_y v3_y))))) (* (- v0_x v3_x) (- v2_y v3_y) (+ (* (- v1_x v3_x) (- v1_x v3_x)) (* (- v1_y v3_y) (- v1_y v3_y))))) 0.0))

(assert
(< (- (- (- (+ (* (- v0_x v2_x) (- v1_y v2_y) (+ (* (- v3_x v2_x) (- v3_x v2_x)) (* (- v3_y v2_y) (- v3_y v2_y)))) (* (- v0_y v2_y) (- v3_x v2_x) (+ (* (- v1_x v2_x) (- v1_x v2_x)) (* (- v1_y v2_y) (- v1_y v2_y)))) (* (- v1_x v2_x) (- v3_y v2_y) (+ (* (- v0_x v2_x) (- v0_x v2_x)) (* (- v0_y v2_y) (- v0_y v2_y))))) (* (- v1_y v2_y) (- v3_x v2_x) (+ (* (- v0_x v2_x) (- v0_x v2_x)) (* (- v0_y v2_y) (- v0_y v2_y))))) (* (- v0_y v2_y) (- v1_x v2_x) (+ (* (- v3_x v2_x) (- v3_x v2_x)) (* (- v3_y v2_y) (- v3_y v2_y))))) (* (- v0_x v2_x) (- v3_y v2_y) (+ (* (- v1_x v2_x) (- v1_x v2_x)) (* (- v1_y v2_y) (- v1_y v2_y))))) 0.0))

(check-sat-using (then (! simplify :som true) (! simplify :sort-sums true) smt))