Z3 Forall with array - arrays

Z3 provides unknown for the simple problem:
(assert
(forall ((y (Array Int Int)))
(= (select y 1) 0))
)
(check-sat)
I've found that it becomes sat if negate the forall, but this seems like a particularly simple thing to be unable to solve.
This is causing issues because the class of problems I want to solve are more like,
(declare-fun u () Int)
(assert
(forall ((y (Array Int Int)) )
(=>
(= u 0) (<= (select y 1) 0))
)
)
(check-sat)
Where negating the forall alone is not the same problem, so that cannot be done here. Is there some way to pose this style of problem to Z3 to get an un/sat result?

Problems with quantifiers are always problematic with SMT solvers, especially if they involve arrays and alternating quantifiers like in your example. You essentially have exits u. forall y. P(u, y). Z3, or any other SMT solver, will have hard time dealing with these sorts of problems.
When you have a quantified assertion like you do where you have forall's either at the top-level or nested with exists, the logic becomes semi-decidable. Z3 uses MBQI (model-based quantifier instantiation) to heuristically solve such problems, but it more often than not fails to do so. The issue isn't merely that z3 is not capable: There's no decision procedure for such problems, and z3 does its best.
You can try giving quantifier patterns for such problems to help z3, but I don't see an easy way to apply that in your problem. (Quantifier patterns apply when you have uninterpreted functions and quantified axioms. See https://rise4fun.com/z3/tutorialcontent/guide#h28). So, I don't think it'll work for you. Even if it did, patterns are very finicky to program with, and not robust with respect to changes in your specification that might otherwise look innocuous.
If you're dealing with such quantifiers, SMT solvers are probably just not a good fit. Look into semi-automated theorem provers such as Lean, Isabelle, Coq, etc., which are designed to deal with quantifiers in a much more disciplined way. Of course, you lose full automation, but most of these tools can use an SMT solver to discharge subgoals that are "easy" enough. That way, you still do the "heavy-lifting" manually, but most subgoals are automatically handled by z3. (Especially in the case of Lean, see here: https://leanprover.github.io/)

There's one extra closing (right) parentheses, which needs to be removed. Also, add assert before the forall statement.
(assert ( forall ( (y (Array Int Int) ) )
(= (select y 1) 0)
))
(check-sat)
Run the above code and you should get unsat as the answer.
For the second program, alias' answer may be useful to you.

Related

Constrain variable to be in array

The problem I'm working on involves making sure that certain variables be perfect squares.
As far as I understood, there is no native support for sqrt in z3 (yet). My idea was to simply have an array with the first say 300 squares and check if the variable is included. How would I go about that?
As I'm frankly not extremely proficient in z3, there might be better suggestions on how to approach the problem, open for anything!
Without knowing exactly what you are trying to do it is hard to come up with good advice here. But, perhaps you don't need sqrt? If all you want are numbers that are perfect squares, then you can go the other way around:
(declare-fun sqrtx () Int)
(declare-fun x () Int)
; this will make sure x is a perfect square:
(assert (and (>= sqrtx 0) (= x (* sqrtx sqrtx))))
; make it interesting:
(assert (> x 10))
(check-sat)
(get-value (x sqrtx))
This prints:
sat
((x 16)
(sqrtx 4))
In essence, for each "perfect-square" you want, you can declare a ghost variable and assert the required relation.
Note that this gives rise to nonlinearity (since you're multiplying two symbolic values), so the solver might have a hard time handling all your constraints. But without seeing what you're actually trying to do, I think this would be the simplest approach to having perfect squares and reasoning with them.

How to get maximum value of matrix containing linear expressions?

I hope that someone can help me.
For the solution of an optimisation problem I have to get the maximum of a Matrix containing linear expressions to minimize this value in a second step.
For example I have the unbounded decision variables x and y
x.append(m.addVar(vtype=GRB.CONTINUOUS, lb=-GRB.INFINITY, ub=+GRB.INFINITY, name="x")))
y.append(m.addVar(vtype=GRB.CONTINUOUS, lb=-GRB.INFINITY, ub=+GRB.INFINITY, name="y")))
and the Matrix M = [0.25*x,0.25*x+y].
The maximum of the Matrix should be saved as M_max. Later the objective is to minimize M_max --> m.setObjective( M_max , GRB.MINIMIZE)
When I try it by typing in M_max = amax(M) I always get back the first element, here 0.25x. What operation returns the "real" maximum value? (Of Course my model is more complicated but I hope that you can understand my problem)
Thanks a lot for your help!
The manual approach would be:
introduce aux-var z (-inf, inf, cont)
add constraints
0.25*x <= z
0.25*x+y <= z
minimize (z)
Not sure if gurobi nowadays provide some automatic way.
Edit It seems newer gurobi-versions provide this functionality (of automatic reformulation) like explained here (python-docs; you need to check if those are available for your interface too; which could be python)
max_ ( variables )
Used to set a decision variable equal to the maximum of a list of decision variables (or constants). You can pass the arguments as a Python list or as a comma-separated list.
# example probably based on the assumption:
# import: from gurobipy import *
m.addConstr(z == max_(x, y, 3))
m.addConstr(z == max_([x, y, 3]))
You did not show what amax is you used. If it's numpy's amax or anything outside of gurobi, you cannot use it! Gurobi-vars don't behave as classic fp-variables and every operation on those variable-objects need to be backed by gurobi (often hidden through operator-overloading) or else gurobi can't make sure it's formalizing a valid mathematical-model.

Preconditioning of a linear system

I have a large sparse linear system generated as a part of PDE solution for flows in the form Ax=b. The condition number of matrix A is very bad - of the order 3000!. But I get expected solutions with direct solvers. So, now I want to precondition the matrix so that I can use iterative solvers and use the sparseness. I have tried Jacobi preconditioner, but it does not work well as the matrix is not diagonally dominant. I need some help in proceeding further:
1) Imagine I get an approximate solution for x (generated by one run of biconjugate gradient solver). Now can I get "inverse of A" (for preconditioning) from this, seems like it must be possible but I am unable to figure out how! i.e knowing x and b can I calculate the A inverse (which may be used as preconditioner!).
2) Any other way of preconditioning which you feel would be worth a try?
3) Any way to circumvent pre-conditioning for iterative schemes for bad condition number systems?
Thanks a lot in advance for any help. Any comments are welcome.

Cross between "dotimes" and "for" functionality?

I frequently find myself wanting to efficiently run a Clojure function multiple times with an integer index (like "dotimes") but also get the results out as a ready-made sequence/list (like "for").
i.e. I'd like to do something like this:
(fortimes [i 10] (* i i))
=> (0 1 4 9 16 25 36 49 64 81)
Clearly it would be possible to do:
(for [i (range 10)] (* i i))
But I'd like to avoid creating and throwing away the temporary range list if at all possible.
What's the best way to achieve this in Clojure?
Generating a range in a for loop, as you show in your second example, is the idiomatic solution for solving this problem in Clojure.
Since Clojure is grounded in the functional paradigm, programming in Clojure, by default, will generate temporary data structures like this. However, since both the "range" and the "for" command operate with lazy sequences, writing this code does not force the entire temporary range data structure to exist in memory at once. If used properly, there is therefore a very low memory overhead for lazy seqs as used in this example. Also, the computational overhead for your example is modest and should only grow linearly with the size of the range. This is considered an acceptable overhead for typical Clojure code.
The appropriate way to completely avoid this overhead, if the temporary range list is absolutely, positively unacceptable for your situation, is to write your code using atoms or transients: http://clojure.org/transients. It you do this, however, you will give up many of the advantages of the Clojure programming model in exchange for slightly better performance.
I've written an iteration macro that can do this and other types of iteration very efficiently. The package is called clj-iterate, both on github and clojars. For example:
user> (iter {for i from 0 to 10} {collect (* i i)})
(0 1 4 9 16 25 36 49 64 81 100)
This will not create a temporary list.
I'm not sure why you're concerned with "creating and throwing away" the lazy sequence created by the range function. The bounded iteration done by dotimes is likely more efficient, it being an inline increment and compare with each step, but you may pay an additional cost to express your own list concatenation there.
The typical Lisp solution is to prepend new elements to a list that you build as you go, then reverse that built-up list destructively to yield the return value. Other techniques to allow appending to a list in constant time are well known, but they do not always prove to be more efficient than the prepend-then-reverse approach.
In Clojure, you can use transients to get there, relying on the destructive behavior of the conj! function:
(let [r (transient [])]
(dotimes [i 10]
(conj! r (* i i))) ;; destructive
(persistent! r))
That seems to work, but the documentation on transients warns that one should not use conj! to "bash values in place"—that is, to count on destructive behavior in lieu of catching the return value. Hence, that form needs to be rewritten.
In order to rebind r above to the new value yielded by each call to conj!, we'd need to use an atom to introduce one more level of indirection. At that point, though, we're just fighting against dotimes, and it would be better to write your own form using loop and recur.
It would be nice to be able to preallocate the vector to be of the same size as the iteration bound. I don't see a way to do so.
(defmacro fortimes [[i end] & code]
`(let [finish# ~end]
(loop [~i 0 results# '()]
(if (< ~i finish#)
(recur (inc ~i) (cons ~#code results#))
(reverse results#)))))
example:
(fortimes [x 10] (* x x))
gives:
(0 1 4 9 16 25 36 49 64 81)
Hmm, can't seem to answer your comment because I wasn't registered. However, clj-iterate uses a PersistentQueue, which is part of the runtime library, but not exposed through the reader.
It's basically a list on which you can conj to the end.

what to do with a flawed C++ skills test

In the following gcc.gnu.org post, Nathan Myers says that a C++ skills test at SANS Consulting Services contained three errors in nine questions:
Looking around, one of fthe first on-line C++ skills tests I ran across was:
http://www.geekinterview.com/question_details/13090
I looked at question 1...
find(int x,int y)
{ return ((x<y)?0:(x-y)):}
call find(a,find(a,b)) use to find
(a) maximum of a,b
(b) minimum of a,b
(c) positive difference of a,b
(d) sum of a,b
... immediately wondering why would anyone write anything so obtuse. Getting past the absurdity, I didn't really like any of the answers, immediately eliminating (a) and (b) because you can get back zero (which is neither a nor b) in a variety of circumstances. Sum or difference seemed more likely, except that you could also get zero regardless of the magnitudes of a and b. So... I put Matlab to work (code below) and found: when either a or b is negative you get zero; when b > a you get a; otherwise you get b, so the answer is (b) min(a,b), if a and b are positive, though strictly speaking the answer should be none of the above because there are no range restrictions on either variable. That forces test takers into a dilemma - choose the best available answer and be wrong in 3 of 4 quadrants, or don't answer, leaving the door open to the conclusion that the grader thinks you couldn't figure it out.
The solution for test givers is to fix the test, but in the interim, what's the right course of action for test takers? Complain about the questions?
function z = findfunc(x,y)
for i=1:length(x)
if x(i) < y(i)
z(i) = 0;
else
z(i) = x(i) - y(i);
end
end
end
function [b,d1,z] = plotstuff()
k = 50;
a = [-k:1:k];
b = (2*k+1) * rand(length(a),1) - k;
d1 = findfunc(a,b);
z = findfunc(a,d1);
plot( a, b, 'r.', a, d1, 'g-', a, z, 'b-');
end
Why are you wasting your time taking tests such as the online one you linked to? That one is so bad that words are not enough to describe the horror.
What you're supposed to do in this case is wash your eyes with soap, get drunk and hope you won't remember anything in the morning...
I had the same issue on a test a few years ago.
The options were A, B, C, or D.
I wrote in option E with my answer and then clearly explained why the other four were wrong.
The test was taken remotely and got a call for an on-site interview the same day.
...you can take it for what it's worth.
I prefer to write notes on the test explaining where the test is invalid. I am also willing to discuss these items with interviewers.
I like to stand by my convictions against horrible code and especially code fragments on tests that are never used or very seldom used in the real world.

Resources