parthood definition in Z3 - set

I'm trying to define in Z3 the parthood relation (called C in the code below) between pairs of sets (defined using array).
I wrote 3 asserts to define reflexivity, transitivity, and antisymmetry but Z3 returns "unknown" and I don't understand why.
(define-sort Set () (Array Int Bool))
(declare-rel C (Set Set))
; reflexivity
(assert (forall ((X Set)) (C X X)))
; transitive
(assert (forall ((X Set)(Y Set)(Z Set))
(=>
(and (C X Y) (C Y Z))
(C X Z)
)
))
; antisymmetric
(assert (forall ((X Set)(Y Set))
(=>
(and (C X Y) (C Y X))
(= X Y)
)
))
(check-sat)
I noticed that the unknown is returned only when the antisymmetry is considered with one of the other 2 asserts. If I only consider the antisymmetry property Z3 doesn't return unknown. The same if I consider reflexivity and transitivity without antisymmetry.

Quantifiers are inherently incomplete. So, it's not surprising that Z3 (or any other SMT solver) will return unknown when they are present. There are a few heuristics that solvers use for handling quantifiers, such as e-matching; but those will only apply when you have ground-terms around. Your formulation, having only quantified axioms, is unlikely to benefit from that.
For reasoning about quantifiers in general, an SMT solver is simply not the best choice; use a theorem prover (Isabelle, Lean, Coq, etc.) for that.
Here's a nice slide deck by Leonardo on the use of quantifiers in SMT solving: https://leodemoura.github.io/files/qsmt.pdf. It can help provide some further insight into the techniques and the difficulties associated.

Related

Is there a way to use Z3 to get models for constraints involving sets?

I am trying to model sets in Z3 such that I am able to find models to
constraints involving sets.
I currently represent a set using an array. An element belongs to the set
if the corresponding entry in the array is true. I then have some axioms
which I use in constraints.
Here is an example in SMT 2.0.
(define-sort Set (T) (Array T Bool))
(declare-fun |Set#Card| ((Set Int)) Int)
(assert (forall ((s (Set Int)))
(!
(<= 0 (|Set#Card| s))
:pattern ((|Set#Card| s)))))
(declare-fun |Set#Singleton| (Int) (Set Int))
(assert (forall ((r Int))
(!
(select (|Set#Singleton| r) r)
:pattern ((|Set#Singleton| r)))))
(assert (forall ((r Int) (o Int))
(iff (select (|Set#Singleton| r) o) (= r o))))
(assert (forall ((r Int)) (= (|Set#Card| (|Set#Singleton| r)) 1)))
(declare-fun s () (Set Int))
(assert (= 1 (|Set#Card| s)))
;(assert (= 1 (|Set#Card| (|Set#Singleton| 1))))
;(assert (not (= 1 (|Set#Card| (|Set#Singleton| 1)))))
(check-sat)
(get-info :reason-unknown)
(get-model)
My problem is that I get unknown and therefore no model for most cases.
I think my axiomatization is too weak. In the example above I would
like to get a model for a set s which contains one element.
Does anyone know how I could use Z3 to get models for constraints
involving sets?
Every answer is helpful. I.e., perhaps I misunderstand what Z3 can
and cannot do. Ideas on how I could deal with this problem are welcome
too (other tool suggestions, ...).
The problem is that Z3 will fail to build a model that satisfies assertions such as:
(assert (forall ((r Int) (o Int))
(iff (select (|Set#Singleton| r) o) (= r o))))
One possible workaround is to define |Set#Singleton| instead of axiomatizing it.
We can define it using the const array operator, and store. Here is a possible definition:
(define-fun |Set#Singleton| ((r Int)) (Set Int)
(store ((as const (Set Int)) false) r true))
Here is a link for your modified example with this definition. Z3 returns sat and a model after I use the definition.
In the textual interface, we have to use as construct to specify the kind of constant array we want.
Note that, we can encode several set operations using the extended array theory available in Z3. This paper has additional details. However, this approach can't encode the |Set#Card| function.
Another option is to use "candidate models" for unknown results. This is not the ideal solution, but several users do that.

EPR formulas with equality and inequality

I am encoding sets as relations and operations over sets as universally quantified implications. I have a selection operator over sets that produces new sets by selecting elements satisfying a unary predicate p (eg: v<4, v>4, ..). Due to this operator, I have simple arithmetic predicates in my formulas. An example Z3 encoding of such a formula is given below -
(set-option :mbqi true)
(set-option :model-compact true)
;; Rmem and Rmem1 are sets of Int
(declare-fun Rmem (Int) Bool)
(declare-fun Rmem1 (Int) Bool)
(declare-const v Int)
(declare-const v1 Int)
(declare-const x Int)
;; Rmem = Rmem1 U {x}
(assert (forall ((n Int)) (= (Rmem n)(or (Rmem1 n) (= n x)))))
;; Select(m<v1) from Rmem1 = {}
(assert (forall ((m Int)) (= false (and (Rmem1 m) (< m v1)))))
(assert (or (< v x) (= v x)))
(assert (or (< v v) (= v v1)))
(assert (exists ((q Int)) (and (Rmem q) (< q v))))
(check-sat)
(get-model)
As expected, Z3 returns UNSAT for the above formula. However, my questions are -
Given that I can write my formula in prenex normal form, is it still in EPR class?
Are such formulas decidable? Is z3 a decision procedure for such formulas? How should I constrain my predicates such that the formulas are decidable?
Update - The aforementioned set of formulas can be expressed as conjunctive queries in relational algebra, but with inequality.
Your formula is in decidable fragment that is supported by Z3. Technically, the formula is not in EPR because you use atoms of the form x < c in quantifiers. The Z3 guide (Quantifiers section) describes many fragments that can be decided by Z3. Note that some of these fragments are very expensive (e.g., NEXPTIME-hard). So, Z3 may still fail to solve them in a reasonable amount of time, or run out of memory.

What exactly are Bernie-Schonfinkel class of formulas?

I have a simple proposition. I would like to assert that first element from a strictly sorted list of integers is the minimum of all elements in the list. The way I define sorted list is by defining a local invariant that every element is less than its next element. I have formulated my proposition in following way in Z3 -
(set-option :mbqi true)
(set-option :model-compact true)
(declare-fun S (Int) Bool)
(declare-fun preceeds (Int Int) Bool)
(declare-fun occurs-before (Int Int) Bool)
;; preceeds is anti-reflexive
(assert (forall ((x Int)) (=> (S x) (not (preceeds x x)))))
;; preceeds is monotonic
(assert (forall ((x Int) (y Int)) (=> (and (S x) (and (S y) (and (preceeds x y))))
(not (preceeds y x)))))
;; preceeds is a function
(assert (forall ((x Int) (y Int) (z Int)) (=> (and (S x) (and (S y) (and (S z) (and (preceeds x y)
(preceeds x z)))))
(= y z))))
;; preceeds induces local order
(assert (forall ((x Int) (y Int)) (=> (and (S x) (and (S y) (preceeds x y)))
(< x y))))
;; preceeds implies occurs-before
(assert (forall ((x Int) (y Int)) (=> (and (and (S x) (S y)) (preceeds x y))
(occurs-before x y))))
;;occurs-before is transitivie
(assert (forall ((x Int)(y Int)(z Int))
(=> (and (S x) (and (S y) (and (S z)(and (occurs-before x y) (occurs-before y z)))))
(occurs-before x z))
))
(declare-const h Int)
(assert (S h))
(assert (forall ((x Int)) (=> (S x) (occurs-before h x))))
(assert (forall ((y Int)) (=> (S y) (< h y))))
(check-sat)
(get-model)
Firstly, I would like to know exactly what class of formulas are effectively propositional. Can my assertion be classified as effectively propositional?
Secondly, is my formulation shown above correct?
Thirdly, what options should I set in Z3 to make it accept quantified formulas only if they are effectively propositional?
We say a formula is in the effectively propositional fragment when it contains only predicates, constants, universal quantifiers, and does not use theories (e.g., arithmetic). It is very common to find alternative definitions that says that the formula has a Exists* Forall* quantifier prefix and uses only predicates. These definitions are equivalent since the existential quantifier can be eliminated using fresh uninterpreted constants. For more information see here.
Your assertions are not in the effectively propositional fragment because you use arithmetic. Z3 can decide other fragments. The Z3 tutorial has a list of fragments that can be decided by Z3.
Your assertions is not in any of the fragments listed, but Z3 should be able to handle them and other similar assertions without problems.
Regarding the correctness of your assertions, the following two assertions cannot be satisfied.
(assert (S h))
(assert (forall ((y Int)) (=> (S y) (< h y))))
If we instantiate the quantifier with h we can deduce (< h h) which is false.
I see what you are trying to do. You may also consider the following simple encoding (maybe it is too simple). It is also available online here.
;; Encode a 'list' as a "mapping" from position to value
(declare-fun list (Int) Int)
;; Asserting that the list is sorted
(assert (forall ((i Int) (j Int)) (=> (<= i j) (<= (list i) (list j)))))
;; Now, we prove that for every i >= 0 the element at position 0 is less than equal to element at position i
;; That is, we show that the negation is unsatisfiable with the previous assertion
(assert (not (forall ((i Int)) (=> (>= i 0) (<= (list 0) (list i))))))
(check-sat)
Finally, Z3 does not have any command line for checking whether a formula is in the effectively propositional fragment or not.

Z3 Theorem Prover: Pythagorean Theorem (Non-Linear Artithmetic)

Wherefore?
The usecase context in which my problem occures
I define 3 random item of a triangle. Microsoft Z3 should output:
Are the constraints satisfiabe or are there invalid input values?
A model for all the other triangle items where all the variables are assigned to concrete values.
In order to constrain the items i need to assert triangle equalities - i wanted to start out with the Pythagorean Theorem ((h_c² + p² = b²) ^ (h_c² + q² = a²)).
The Problem
I know that Microsoft Z3 has only limited capabilities to solve non-linear arithematic problems. But even some hand calculators are able to solve a very simplified version like this:
(set-option :print-success true)
(set-option :produce-proofs true)
(declare-const a Real)
(declare-const b Real)
(assert (= a 1.0))
(assert (= b 1.0))
(assert
(exists
((c Real))
(=
(+
(* a a)
(* b b)
)
(* c c)
)
)
)
(check-sat)
(get-model)
The Question
Is there a way to get Microsoft Z3 to solve the Pythagorean Theorem if two values are given?
Or: Is there another theorem prover which is able to handle these case of non-linear arithmetic?
Thanks for your help concerning that - If anything is unclear, please comment.
Z3 has a new solver (nlsat) for nonlinear arithmetic. It is more efficient than other solvers (see this article). The new solver is complete for quantifier-free problems.
However, the new solver does not support proof generation. If we disable proof generation, then Z3 will use nlsat and easily solve the problem. Based on your question, it seems you are really looking for solutions, thus disabling proof generation does not seem to be an issue.
Moreover, Z3 does not produce approximate solutions (like hand calculators).
It uses a precise representation for real algebraic numbers.
We can also ask Z3 to display the result in decimal notation (option :pp-decimal).
Here is your example online.
In this example, when precise representation is used, Z3 will display the following result for c.
(root-obj (+ (^ x 2) (- 2)) 1)
It is saying that c is the first root of the polynomial x^2 - 2.
When we use (set-option :pp-decimal true), it will display
(- 1.4142135623?)
The question mark is used to indicate the result is truncated.
Note that, the result is negative. However, it is indeed a solution for the problem you posted.
Since, you are looking for triangles, you should assert that the constants are all > 0.
BTW, you do not need the existential quantifier. We can simply use a constant c.
Here is an example (also available online at rise4fun):
(set-option :pp-decimal true)
(declare-const a Real)
(declare-const b Real)
(declare-const c Real)
(assert (= a 1.0))
(assert (= b 1.0))
(assert (> c 0))
(assert (= (+ (* a a) (* b b)) (* c c)))
(check-sat)
(get-model)
Here is another example that does not have a solution (also available online at rise4fun):
(set-option :pp-decimal true)
(declare-const a Real)
(declare-const b Real)
(declare-const c Real)
(assert (> c 0))
(assert (> a c))
(assert (= (+ (* a a) (* b b)) (* c c)))
(check-sat)
BTW, you should consider the Python interface for Z3. It is much more user friendly. The tutorial that I linked has examples in Kinematics. They also use nonlinear arithmetic to encode simple high-school physics problems.

Equality for constants in Z3 SMT solver

I am using the Z3 SMT solver by Microsoft, and I am trying to define constants of a custom sort. It seems like such constants are not unequal by default. Suppose you have the following program:
(declare-sort S 0)
(declare-const x S)
(declare-const y S)
(assert (= x y))
(check-sat)
This will give "sat", because it is of course perfectly possible that two constants of the same sort are equal. Since I am making model in which constants have to be different from each other, this means that I would need to add an axiom of the form
(assert (not (= x y)))
for every pair of constants of the same sort. I was wondering if there is some way to do this generic, so that each constant of a sort is unique by default.
You can use datatypes to encode enumeration types found in many programming languages. In the following example, the sort S has three elements and they are different from each other.
(declare-datatypes () ((S a b c)))
Here is a complete example: http://rise4fun.com/Z3/ncPc
(declare-datatypes () ((S a b c)))
(echo "a and b are different")
(simplify (= a b))
; x must be equal to a, b or c
(declare-const x S)
; since x != a, then it must be b or c
(assert (not (= x a)))
(check-sat)
(get-model)
; in the next check-sat x must be c
(assert (not (= x b)))
(check-sat)
(get-model)
Another possibility is to use distinct.
(assert (distinct a b c d e))

Resources