Whether two boolexpr are equal - z3

Given two boolexpr b1,b2
say
b1=x1>=4&&x2>=5
b2=x2>=5&&x1>=4
Can we use .net API for Z3 to know whether b1 and b2 are actually the same constraint? )(meaning that the value of x1 and x2 allowed by b1 and b2 are the same)

Yes. You want to prove that b1 equals b2, which you can do by showing the negation of b1 == b2 is unsatisfiable. Here's an example showing how to do this in Z3Py, and you can use basically the same steps in the .NET API: http://rise4fun.com/Z3Py/M4R1
x1, x2 = Reals('x1 x2')
b1=And(x1>=4, x2>=5)
b2=And(x2>=5, x1>=4)
s = Solver()
proposition = b1 == b2 # assertion is whether b1 and b2 are equal
s.add(Not(proposition))
# proposition proved if negation of proposition is unsat
print s.check() # unsat
b1=And(x1>=3, x2>=5) # note difference
b2=And(x2>=5, x1>=4)
s = Solver()
proposition = b1 == b2
s.add(Not(proposition))
print s.check() # sat

Related

Reducing Unrestricted SAT (USAT) into 3-SAT

I know the procedure simply by transforming each clause l1 ∨ ⋯ ∨ ln to a conjunction of n − 2 clauses .
I try to show the values satisfying the original and the final formula with Z3 to show that they are equisatisfiable as an SMT file.
For clarify can you give any example about this procedure . Thank you.
Equivalence checking is done by asking the solver if there's an assignment that can distinguish two formulas. If there's no such assignment, then you can conclude the formulas are equivalent, or in the SAT context, equi-satisfiable.
Here's a simple example:
from z3 import *
a, b, c = Bools('a b c')
fml1 = Or(And(a, b), And(a, c))
fml2 = And(a, Or(b, c))
s = Solver()
s.add(Distinct(fml1, fml2))
print(s.check())
Now if fml1 is an arbitrary SAT formula, and fml2 is a 3-SAT converted version (I'm not saying the above are SAT and 3-SAT conversions, but substitute the result of your algorithm here), then we'd expect that the SAT solver cannot distinguish them, i.e., the formula Distinct(fml1, fml2) would be unsatisfiable. Indeed, we get:
unsat
establishing that they are the same.
If you are using SMTLib only, then the template to use is:
(declare-fun a () Bool)
(declare-fun b () Bool)
(declare-fun c () Bool)
(assert (distinct (or (and a b) (and a c))
(and a (or b c))))
(check-sat)

Figuring out attribute value combinations from regression model

I have a regression related question, but I am not sure how to proceed. Consider the following dataset, with A, B, C, and D as the attributes (features) and a decision variable Dec for each row:
A B C D Dec
a1 b1 c1 d1 Y
a1 b2 c2 d2 N
a2 b2 c3 d2 N
a2 b1 c3 d1 N
a1 b3 c2 d3 Y
a1 b1 c1 d2 N
a1 b1 c4 d1 Y
Given such data, I want to figure out most compact rules for which Dec evaluates to Y.
For example, A=a1 AND B=b1 AND D=d1 => Y.
I would prefer specifying the thresholds for the Precision of these rules, so that I can filter them out as per my requirement. For example, I would like to see all rules which provide at least 90% precision. This can provide me better compaction of the rules. The above mentioned rule provides 100% precision, whereas B=b1 AND D=d1 => Y has 66% precision (it errs on the 4th row).
Vaguely, I can see that this is similar to building a decision tree and finding out paths which end in Y. If I understand correctly, building a regression model would provide me the attributes which matter the most, but I need combinations of actual values from the attributes which lead to Y.
The attribute values are multi-valued, but that is not a hard constraint. I can even assume them to be boolean.
Is there any library in existing tools such as Weka or R that can help me?
Regards
I don't think this is a regression problem. This seems like a classification problem where you are trying to classify Y or N. You could build ensemble learners like Adaboost and see how the decisions vary from tree to tree or you could do something like elastic net logistic regression and see what the final weights are.

eliminating forall using unsat

We know that, we can prove validity of a theorem by saying :
let Demorgan(x, y) = formula1(x,y) iff formula2(x,y)
assert ( forall (x,y) . Demorgan(x,y) )
Alternatively we can eliminate the forall quantifier by saying that :
let Demorgan(x, y) = formula1(x,y) iff formula2(x,y)
( assert (not Demorgan(x,y) ) )
So if it returns unsat, then we can say the above formula is valid.
Now I want to use this idea to eliminate the forall quantifier from the following assertion:
assert ( exists x1,x2,x3 st .( forall y . formula1(x1,y) iff
formula2(x2,y) iff
formula3(x3,y) ) )
So is there any way in Z3(using C++ API or SMT-LIB2.0) that I can assert something like the following :
assert (exists x1,x2,x3 st. ( and ((not ( formula1(x1,y) iff formula2(x2,y) )) == unsat)
((not ( formula2(x2,y) iff formula3(x3,y) )) == unsat)))
Yes, when we can prove the validity of a formula by showing its negation to be unsatisfiable.
For example, to show that Forall X. F(X) is valid, we just have to show that not (Forall X. F(X)) is unsatisfiable. The formula not (Forall X. F(X)) is equivalent to (Exists X. not F(X)). The formula (Exists X. not F(X)) is equisatisfiable to the formula not F(X) where the bound variable X is replaced by a fresh constant X. By equisatisfiable, I mean that the first one is satisfiable iff the second one is. This step that removes existential quantifiers is usually called skolemization.
Note that these last two formulas are not equivalent.
For example, consider the interpretation { X -> 2 } that assigns X to 2. The formula Exists X. not (X = 2) still evaluates to true in this interpretation because we can choose X to be 3. On the other hand, the formula not (X = 2) evaluates to false in this interpretation.
We usually use the term quantifier elimination procedure for a procedure that given a formula F produces an equivalent quantifier-free formula F'. So, skolemization is not considered a quantifier elimination procedure because the result is not an equivalent formula.
That being said, we don't have to apply the skolemization step by hand. Z3 can do it for us. Here is an example (also available online here).
(declare-sort S)
(declare-fun F (S) Bool)
(declare-fun G (S) Bool)
(define-fun Conjecture () Bool
(forall ((x S)) (= (and (F x) (G x)) (not (or (not (F x)) (not (G x)))))))
(assert (not Conjecture))
(check-sat)
Now, let us consider a formula of the form Exists X. Forall Y. F(X, Y). To prove the validity of this formula, we can show the negation not Exists X. Forall Y. F(X, Y) to be unsatisfiable. The negation is equivalent to Forall X. Exists Y. not F(X, Y). Now, if apply skolemization to this formula, we obtain Forall X. not F(X, Y(X)). In this case, the bound variable Y was replaced with Y(X), where Y is a fresh function symbol in the resultant formula. The intuition is that the function Y is the "choice function". For each X, we can choose a different value to satisfy the formula F. Z3 performs all these steps automatically for us. We don't need to apply skolemization by hand. However, in this case, the resultant formula is usually harder to solve because it contains a universal quantifier after the skolemization step.

Z3Py is not able to make certain proof?

I am trying to prove that
4*n^3*m+4*n*m^3 <= n^4+6*n^2*m^2+m^4
for all n, m reals; using Z3Py online.
I am using the code:
n, m = Reals('n m')
s = Solver()
s.add(ForAll([n, m], n**4+6*n**2*m**2+m**4 >= 4*n**3*m+4*n*m**3))
print s.check()
and the output is : unknown.
Please can you tell why Z3 does not obtain "sat".
Note that Z3 checks for "satisfiability" and not "validity".
A formula is valid if and only if the negation is not satisfiable (unsat).
So to prove validity of your inequality, you can add the negation of it to Z3 and see if it is able to reason about it.
n, m = Reals('n m')
s = Solver()
s.add(Not(n**4+6*n**2*m**2+m**4 >= 4*n**3*m+4*n*m**3))
print s.check()
It turns out that Z3 does establish that the inequality is unsat using the default Solver.

Boolean Comparison

I'm doing a few exercises from HtDP (How to Design Programs) and I am kind of stuck on the Boolean comparison question. It goes like this.
(define b1 true)
(define b2 false)
Write an expression that computes whether b1 is false and b2 is true. If false produce No and vice versa.
Right now this is all I have come up with:
(and b1 true) => true
(Shameless. I know but I am new at this and I am really slow to catch on)
Any help you could give me would be match appreciated.
Thanks
It's pretty straightforward to translate the question into code. As a first approach, let's copy the question verbatim in pseudocode:
(b1 == false) AND (b2 == true)
Now, how would you write the above in Scheme? remember, Scheme uses prefix notation
(<???> (<???> b1 false) (<???> b2 true))
With a bit more of practice, the same code can be written more compactly like this (again, first in pseudocode):
NOT b1 AND b2
Which should be simple enough to write in Scheme:
(<???> (<???> b1) b2)
Not sure if this is the HtDP way of writing expressions, but you can write a simple truth table and find the boolean expression:
b1 | b2 | Y
0 | 0 | 0
0 | 1 | 1
1 | 0 | 0
1 | 1 | 0
hence Y = (NOT b1) AND b2 => TRUE

Resources