I'm learning Z3. I was working with some simple "isPrime" function and stumbled upon some hard to understand behavior. A seemingly "simpler" inlined formula, (> q 1)
, leads to "unknown", versus a more "complex" define-fun (macro), (isPrime q)
, leads to a quick solution, even as (isPrime q)
subsumes (> 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)