In the Z3 tutorial, section 13.2.3, there is a nice example on how to reduce the number of patterns that have to be instantiated when dealing with the axiomatisation of inje
Z3 does not terminate because it keeps trying to build an interpretation for the problem.
Satisfiable problems containing injectivity axiom are usually hard for Z3.
They usually fall in a class of problems that can't be decided by Z3
The Z3 guide describes most of the classes that can be decided by Z3.
Moreover, Z3 can produce models for infinite domains such as integers and reals. However, in most cases, the functions produced by Z3 have finite ranges. For example, the quantifier forall x, y: x <= y implies f(x) <= f(y)
can be satisfied by assigning f
to a function that has a finite range. More information can be found in this article. Unfortunately, injectivity usually requires a range that is as "big" as the domain. Moreover, it is very easy to write axioms that can only be satisfied by an infinite universe. For example, the formula
(assert
(forall ((d1 Value)(d2 Value)(d3 Value)(d4 Value))
(! (=>
(and (= (ENC d1 d2) (ENC d3 d4)))
(and (= d1 d3) (= d2 d4))
)
:pattern ((ENC d1 d2) (ENC d3 d4)))
)
)
can only be satisfied if the universe of Value
has one element or is infinite.
Another problem is combining the injectivity axiom for a function f
with axioms of the form forall x: f(x) != a
. If f
is a function from A
to A
, then the formula can only be satisfied if A
has an infinite universe.
That being said, we can prevent the non-termination by reducing the amount of "resources" used by the Z3 model finder for quantified formulas. The options
(set-option :auto-config false)
(set-option :mbqi-max-iterations 10)
If we use these options, Z3 will terminate in your example, but will return unknown
. It also returns a "candidate" model. It is not really a model since it does not satisfy all universal quantifiers in the problem. The option
(set-option :mbqi-trace true)
will instruct Z3 to display which quantifiers were not satisfied.
Regarding the example in section 13.2.3, the function may use the same input and return types. Using the trick described in this section will only help unsatisfiable instances. Z3 will also not terminate (for satisfiable formulas) if you re-encode the injectivity axioms using this trick.
Note that the tutorial you cited is very old, and contains outdated information.