Changing order of Z3 fixepoint queries changes the result

114 Views Asked by At

I am trying to find out why swapping query orders may modify the answer of Z3 fixedpoint engine:

(declare-rel fib (Int Int))
(declare-rel q1 ())
(declare-rel q2 ())
(declare-var n Int)
(declare-var tmp1 Int)
(declare-var tmp2 Int)

(rule (=> (< n 2) (fib n 1)))
(rule (=> (and (>= n 2)
               (fib (- n 1) tmp1)
               (fib (- n 2) tmp2))
       (fib n (+ tmp1 tmp2))))

(rule (=> (< n 2) q1))
(rule (=> (and (fib n tmp1) (<= tmp1 0)) q2))

(query q1)
(query q2)

First query q1 is a dummy one, just to ask engine about something. The second query q2 contradicts with infered invariant that fibonacci numbers are always positive.

If the order of queries is

(query q2)
(query q1)

everything works fine, correct answers are given. But swapping them gives the next error while querying q2:

(smt.diff_logic: non-diff logic expression (+ fib_1_1 fib_1_0 (* (- 1) fib_1_n)))
unknown

Can someone explain the reason? Is it Z3 issue or I am doing something wrong? If first, any suggestions of working it arround (I am using .NET API) will be greately appreciated. Thanks!

1

There are 1 best solutions below

0
On BEST ANSWER

It is a bit aggressive assuming that all constraints are UTVPI (Unit two-variable per inequality). The UTVPI mode is often faster than general linear arithmetic. It cuts the search space for candidate invariants down to UTVPI formulas and uses flow based decision procedures for constraints. On the other hand, it may miss invariants that cannot be expressed in the UTVPI fragment. By default, the PDR engine checks if the formulas all belong to UTVPI in which case it switches to the UTVPI mode.

You can disable the UTVPI mode by using the option.

fixedpoint.pdr.utvpi=false

I will try to make the switch more graceful. Thanks for the example.