我正在学习Z3。我正在使用一些简单的" isPrime"功能和偶然发现一些难以理解的行为。一个看似简单的"更简单的"内联公式(> q 1)
,导致"未知",与更多"复杂" define-fun(宏),(isPrime q)
会导致快速解决方案,即使(isPrime q)
包含(> q 1)
也是如此。 http://rise4fun.com/Z3/slg2D
(define-fun isPrime ((x Int)) Bool
(and (> x 1) (not (exists ((z Int) (y Int)) (and (not (= y x)) (and (not (= z x)) (and (> y 1) (> z 1) (= x (* y z)))))))))
(declare-const q Int)
(declare-const r Int)
(assert (and
;with this the '+ 2' variation is sat: 5, 3
;(isPrime q)
(> q 1)
(> r 1)
;always answers sat: 2, 2
;(isPrime (+ (* q r) 1))
;unknown
(isPrime (+ (* q r) 2))
))
(check-sat)
(get-model)
答案 0 :(得分:1)
量化逻辑是一种高级功能,你应该阅读Z3如何解决这些公式,这将让你了解你对Z3的期望。在我谦逊的经历中,用量词解决公式是一种微妙的艺术。对你来说很明显的事情,对Z3来说可能并不明显。
你有一个forall
量词(你把它写成not exists
)Z3会试图满足。我猜Z3正在挑选一些q
和r
,然后检查isPrime
是否成立,否则尝试使用新对,依此类推。如果Z3没有做出正确的选择,可能需要一段时间才能找到q
和r
,所以也许你应该给它更多的时间(在rise4fun上解决问题的时间超时)。 / p>
另一种继续进行的方法是帮助 Z3。例如,让它知道z
和y
小于x
。这样,您可以为这些变量提供下限和上限。
(define-fun isPrime ((x Int)) Bool
(and (> x 1) (not (exists ((z Int) (y Int)) (and (< y x) (and (< z x) (and (> y 1) (> z 1) (= x (* y z)))))))))
This适合我。
<强>更新强>
参考文献: