-1

Can somebody please explain why I am getting a counter example with this py code.

a = Int('a')    
def X(a):
  if (a == 3): 
    return 1
  else:
    return 2

z3.prove( X(a) == If (a == 3, 1, 2) )

counterexample [a = 3]

2 Answers2

3

Your function 'X' will always return '2' for all symbolic variables. That is:

from z3 import *

a = Int('a')

def X(a):
  if (a == 3):
    return 1
  else:
    return 2

print X(a)

will always print:

2

This is precisely why Z3 provides the If function. Python's 'if' does not work for symbolic values and the tests will simply take the else branch.

Aside:

I'd call this a weakness of the Python interface to Z3, since it's really weakly typed. Ideally, this program should be rejected because of the illegal use of if-then-else, but Python isn't a sufficiently strongly-typed language to give you that level of safety. Bindings to Z3 from other languages would reject the equivalent expression as type incorrect at compile time.

alias
  • 28,120
  • 2
  • 23
  • 40
  • Thanks for the reply. So is there any way to add axioms involving functions. Just to give you the context: I need to define axioms over 2 related unnterpreted functions. For example. one function maxcmp(A, B) which returns true is A > B, false otherwise and another function max(A, B) which return the max of A and B. My idea is to define max(A, B) as if(maxcmp(A,B) = True) return A else B, which in turn help me to prove equivalnce in this case. – Sandeep Dasgupta Feb 22 '18 at 19:38
2

X(.) is a Python function, not a logical or Z3 function. It is evaluated when it is called. This means that the value of X(a) in

z3.prove( X(a) == If (a == 3, 1, 2) )

is determined to be 2 before z3.prove is called, because a is an Int('a') (and not 3). In this particular case, it's easy to debug such problems by simply printing the Z3 expressions, e.g.

print( X(a) == If (a == 3, 1, 2) )

reports

If(a == 3, 1, 2) == 2
Christoph Wintersteiger
  • 8,234
  • 1
  • 16
  • 30
  • Thanks for the reply. So is there any way to add axioms involving functions. Just to give you the context: I need to define axioms over 2 related unnterpreted functions. For example. one function maxcmp(A, B) which returns true is A > B, false otherwise and another function max(A, B) which return the max of A and B. My idea is to define max(A, B) as if(maxcmp(A,B) = True) return A else B, which in turn help me to prove equivalnce in this case. – Sandeep Dasgupta Feb 22 '18 at 19:37
  • Yes, use the aptly named `Function(name, sig)` to declare/create uninterpreted function terms: http://z3prover.github.io/api/html/namespacez3py.html#ac526eb9d18decf6dbbe2a64ff844b15d – Christoph Wintersteiger Feb 22 '18 at 23:02
  • Very true, but IMHO `Function` is used to create a declaration, but what I need is some way to define the function, which in z3 world is achieved by 'define-fun', but I need a python-way to do the same. – Sandeep Dasgupta Feb 23 '18 at 23:45
  • 1
    @SandeepDasgupta You originally said "uninterpreted functions," and Christoph described precisely how to achieve that. Now you seem to want to actually `define` the function, which is no longer uninterpreted. In any case, this is a sufficiently different topic from the original post. I recommend you post a separate question to detail what you are trying to achieve. – alias Feb 24 '18 at 07:39