Search code examples
z3smtassociativity

Multi-element subtraction in Z3


I'm using Z3 to solve a problem that needs subtraction and I've run into the fact that subtraction in Z3 allows multiple arguments. This seems odd to me as subtraction is not an associative operation. This can be seen from the following script.

(declare-fun a () Int)
(declare-fun b () Int)
(declare-fun c () Int)
(assert (= a (- 1 2 3)))
(assert (= b (- 1 (- 2 3))))
(assert (= c (- (- 1 2) 3)))

which is satisfied by a=c=-4 and b=2 So this means that subtraction in Z3 is defined by applying the binary operation from left to right?


Solution

  • This is actually a feature of SMT-Lib, z3 is simply implementing that. See here: http://smtlib.cs.uiowa.edu/theories-Ints.shtml

    And yes, if you have multiple elements, it simply associates to the left. That is:

     (- 1 2 3 4)
    

    means exactly the same thing as:

     (- (- (- 1 2) 3) 4)
    

    This is indeed confusing as we only want to do for associative operators where parenthesization doesn't matter (like + and *), but SMTLib is liberal in this sense. This does not mean subtraction is associative in SMT-Lib, it just means if you have multiple arguments it's parsed as described above. Hope that helps!