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.
Related
I'm trying to write a max function that operates on Seq Int.
It should return the index with maximal value. Here is what I have:
(declare-fun max ((Seq Int)) Int)
(assert (forall ((A (Seq Int)))
(=>
(> (seq.len A) 0)
(and
(<= 0 (max A))
(< (max A) (seq.len A))
(forall ((i Int))
(=>
(and
(<= 0 i)
(< i (seq.len A)))
(<= (seq.nth A i) (seq.nth A (max A))))))))
)
(assert (= (max (seq.++ (seq.unit 8) (seq.unit 3))) 0))
;(assert (= (max (seq.++ (seq.unit 8) (seq.unit 3))) 1))
(check-sat)
When I run it like this, Z3 gets stuck. If I use the commented line instead, Z3 immediately answers unsat (like it should). Am I missing something here? Is there a way to define max properly?
This sort of quantified problems are just not a good match for z3. (Or any other SMT solver.) To prove properties of such recursive predicates, you need induction. Traditional SMT solvers have no induction capabilities.
Having said that, you can help z3 by making your quantified assertions separated out, like this:
(declare-fun max ((Seq Int)) Int)
(assert (forall ((A (Seq Int))) (=> (> (seq.len A) 0) (<= 0 (max A)))))
(assert (forall ((A (Seq Int))) (=> (> (seq.len A) 0) (< (max A) (seq.len A)))))
(assert (forall ((A (Seq Int)) (i Int)) (=> (and (> (seq.len A) 0) (<= 0 i) (< i (seq.len A)))
(<= (seq.nth A i) (seq.nth A (max A))))))
(assert (= (max (seq.++ (seq.unit 8) (seq.unit 3))) 0))
;(assert (= (max (seq.++ (seq.unit 8) (seq.unit 3))) 1))
(check-sat)
If you run this, it succesfully says:
sat
While this is correct, don't be fooled into thinking you've completely specified how max should work or z3 can handle all such problems. To wit, let's add (get-model) and see what it says:
sat
(model
(define-fun max ((x!0 (Seq Int))) Int
(ite (= x!0 (seq.++ (seq.unit 7718) (seq.++ (seq.unit 15) (seq.unit 7719))))
2
0))
)
Oh look, it simply found an interpretation of max that doesn't even satisfy the quantified axioms you've given. Looks like this is a z3 bug and should probably be reported. But the moral of the story is the same: Sequence logic and quantifiers are a soft spot, and I wouldn't count on the solver response even if you got a sat answer.
Long story short Recursion requires induction, and if that's what your specification requires, use a tool that understands induction. Isabelle, HOL, Coq, Agda, Lean; to name a few. There are many choices. And most of those tools automatically call z3 (or other SMT solvers) under the hood to establish properties as necessary (or as guided by the user) anyhow; so you have the best of both worlds.
I'm having trouble figuring out how to sort out the 2 biggest numbers and return them into the sum of squares procedure. I am struggling to write the code out in Scheme's syntax. I'm trying to write it as cleanly as possible, and I keep running circles in my head and on paper trying to do so. the book describes thinking "procedurally" and I think I'm having trouble with that aspect.
The book provides code for the sum-of-squares and square procedures. I would include my pseudo code but I'm severely lost. Here is the code the book provides:
(define (square x) (* x x))
(define (sum-of-squares x y)
(+ (square x) (square y)))
How to define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers?
How to define a procedure that takes three numbers as arguments and returns the sum of the squares of the two larger numbers?
First you need a name for the procedure. Let's called it sum-of-squares-two-largest.
(define (sum-of-squares-two-largest x y z)
...)
It can make use of the sum-of-squares function, but it needs to find the two largest numbers out of x,y,z first.
One way to do this would be to get rid of the smallest number. You could define a helper procedure smallest? a b c that checks that a is the smallest of the 3 numbers by doing (and (<= a b) (<= a c)).
(define (sum-of-squares-two-largest x y z)
(if (smallest? x y z)
(sum-of-squares y z)
(if (smallest? y x z)
...]
Write the code for min-of-three. Its negative (as in photography) is what you need:
(define (negative-min-of-three a b c)
(if (<= a b)
(if (<= a c)
(..... b ... c .....)
(..... a ... b .....))
(if (<=
..........
You can complete the code, and rename it. The clock is ticking!
I created two methods to get the largest and the one in the middle for the time being.
(define (largest x y z)
(cond ((and (> x y) (> x z)) x)
((and (> y x) (> y z)) y)
(else z))
)
(define (mid x y z)
(cond ((and (> x y) (< x z)) x)
((and (> y x) (< y z)) y)
(else z))
)
(define (square a)
(* a a)
)
(define (sum-of-two-largest x y z)
(+ (square (largest x y z)) (square (mid x y z)))
)
(sum-of-two-largest -12 -4 1)
The hard part of this is, if you're reading SICP book, finding the 2nd largest number of the three. You can observe, if we let c < b < a, that:
a = max(a, b) gives the largest of the two numbers
b = max(c, b) gives the largest of the two smaller numbers
But how do we get the variable b on the second line. It can so happen that a is the smaller of the two? We can observe that:
b = min(a, b)
If we substitute min(a, b) for b in the max function on the third line, we get:
b = max(c, min(a, b))
This strategy is implemented in the following code, using only the constructs introduced in the book so far:
(define (square x) (* x x))
(define (max a b) (if (> a b) a b))
(define (min a b) (if (< a b) a b))
(define (sum-of-squares-two-largest a b c)
(+ (square (max a b)) (square (max c (min a b)))))
(sum-of-squares-two-largest 1 2 3)
(sum-of-squares-two-largest 1 2 1)
. I am trying to teach my self some computer science skills independently. The problem I am working on wants me to create a way to choose the two biggest numbers out of three then find the sum of squares for the two numbers.
(define (pro x y z)
(cond( (and (< x y) (< x z)) (define a y)(define b z))
( (and(< y x) (< y z)) (define a x) (define b z))
( else ((define a x )(define b y))))
(+ (* a a) (* b b))
When I run the function with z being the smallest or tied for the smallest number I get the following error:
Error: #<undef> is not a function [pro, (anon)]
Why am I getting this error and how do I fix it?
I have been using repl.it to run this program, if that matters.
First, using define's that way is totally bizarre for Scheme code.
After that, I see two problems with the code. The first, the one that's creating the error you're getting, is that you have an extra layer of parens in the else clause. The following
((define a x) (define b y))
is going to evaluate the first define and try to apply it as a procedure. The evaluation of (define ...) returns the #undef which is the source of your error messsage.
If you fixed that problem, your next problem is that your sum of squares code is outside the scope of the defines in your cond and you'll find that a and b are not defined out there.
You should do something like this:
(define (max-of-3 x y z)
(cond
((and (< x y) (< x z)) (values y z))
((and (< y x) (< y z)) (values x z))
(else (values x y))))
(define (pro x y z)
(let-values (((a b) (max-of-3 x y z)))
(+ (* a a) (* b b))))
or even
(define (pro x y z)
(let-values
(((a b) (cond
((and (< x y) (< x z)) (values y z))
((and (< y x) (< y z)) (values x z))
(else (values x y)))))
(+ (* a a) (* b b))))
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.
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.