I have a formlua in DNF form, say:
abcx + abcy + abz
Is there any way to take out the common variables, to get the follwing formula:
ab (cx + cy + z)
A followup question, can it be done recursively, like
ab ( c(x+y) + z)
Sure.. Here's one way:
from z3 import *
a, b, c, x, y, z = Ints('a b c x y z')
print simplify(a*b*c*x + a*b*c*y + a*b*z, hoist_mul=True)
This prints:
a*b*(c*(x + y) + z)
which is exactly what you're looking for.
And for your next question, how did I find about hoist_cmul=True argument? Simply run:
help_simplify()
at your Python prompt, and it'll list you all the options simplify takes.
Note that you should in general not count on what the simplifier will give you. It's mostly heuristic driven, and in the presence of other terms what you get may not match what you expected. (It'll of course still be an equivalent expression.) There's no notion of "simplest" when it comes to arithmetic expressions, and what you consider simple and what z3 considers simple may not necessarily match.
Related
In Z3-Py, I am performing quantifier elimination (QE) over the following formulae:
Exists y. Forall x. (x>=2) => ((y>1) /\ (y<=x))
Forall x. Exists y. (x>=2) => ((y>1) /\ (y<=x)),
where both x and y are Integers. I did QE in the following way:
x, y = Ints('x, y')
t = Tactic("qe")
negS0= (x >= 2)
s1 = (y > 1)
s2 = (y <= x)
#EA
ea = Goal()
ea.add(Exists([y],Implies(negS0, (ForAll([x], And(s1,s2))))))
ea_qe = t(ea)
print(ea_qe)
#AE
ae = Goal()
ae.add(ForAll([x],Implies(negS0, (Exists([y], And(s1,s2))))))
ae_qe = t(ae)
print(ae_qe)
Result QE for ae is as expected: [[]] (i.e., True). However, as for ea, QE outputs: [[Not(x, >= 2)]], which is a results that I do not know how to interpret since (1) it has not really performed QE (note the resulting formula still contains x and indeed does not contain y which is the outermost quantified variable) and (2) I do not understand the meaning of the comma in x, >=. I cannot get the model either:
phi = Exists([y],Implies(negS0, (ForAll([x], And(s1,s2)))))
s_def = Solver()
s_def.add(phi)
print(s_def.model())
This results in the error Z3Exception: model is not available.
I think the point is as follows: since (x>=2) is an implication, there are two ways to satisfy the formula; by making the antecedent False or by satisfying the consequent. In the second case, the model would be y=2. But in the first case, the result of QE would be True, thus we cannot get a single model (as it happens with a universal model):
phi = ForAll([x],Implies(negS0, (Exists([y], And(s1,s2)))))
s_def = Solver()
s_def.add(phi)
print(s_def.model())
In any case, I cannot 'philosophically' understand the meaning of a QE of x where x is part of the (quantifier-eliminated) answer.
Any help?
There are two separate issues here, I'll address them separately.
The mysterious comma This is a common gotcha. You declared:
x, y = Ints('x, y')
That is, you gave x the name "x," and y the name "y". Note the comma after the x in the name. This should be
x, y = Ints('x y')
I guess you can see the difference: The name you gave to the variable x is "x," when you do the first; i.e., comma is part of the name. Simply skip the comma on the right hand side, which isn't what you intended anyhow. And the results will start being more meaningful. To be fair, this is a common mistake, and I wish the z3 developers ignored the commas and other punctuation in the string you give; but that's just not the case. They simply break at whitespace.
Quantification
This is another common gotcha. When you write:
ea.add(Exists([y],Implies(negS0, (ForAll([x], And(s1,s2))))))
the x that exists in negS0 is not quantified over by your ForAll, since it's not in the scope. Perhaps you meant:
ea.add(Exists([y],ForAll([x], Implies(negS0, And(s1,s2)))))
It's hard to guess what you were trying to do, but I hope the above makes it clear that the x wasn't quantified. Also, remember that a top-level exist quantifier in a formula is more or less irrelevant. It's equivalent to a top-level declaration for all practical purposes.
Once you make this fix, I think things will become more clear. If not, please ask further clarifying questions. (As a separate question on Stack-overflow; as edits to existing questions only complicate the matters.)
The Z3 input format is an extension of the one defined by SMT-LIB 2.0 standard. The input expressions need to write in prefix form. As for example rise4fun,
x + (y * 2) = 20 needs to be given input in the form of " (= (+ x (* 2 y)) 20)) ".
Z3 supports JAVA API. As for example, let us consider the below code which evaluates and checks satisfiability expressions: x+y = 500 and x + (y * 2) = 20.
final Context ctx = new Context();
final Solver solver = ctx.mkSimpleSolver();
IntExpr x = ctx.mkIntConst("x");
IntExpr y = ctx.mkIntConst("y");
IntExpr th = ctx.mkInt(500);
IntExpr th1 = ctx.mkInt(2);
IntExpr th2 = ctx.mkInt(20);
BoolExpr t1 = ctx.mkEq(ctx.mkAdd(x,y), th);
BoolExpr t2 = ctx.mkEq(ctx.mkAdd(x,ctx.mkMul(th1, y)), th2);
solver.add(t1);
solver.add(t2);
solver.check()
The problem is if an external user wants to give input to the solver, he cannot give it in the form of the general formula as " x+y = 500, x + (y * 2) = 20 ".
The input needs to be parsed and then should be written manually using JAVA API in prefix form (Note BoolExpr t2 in above code) to give the final expressions to Solver.
Is there any parser/library/API (Preferably JAVA or in any other language) which parses the general expressions with arithmetic operators(+, -, <, >, =), propositional logic connectors (And, OR), Quantifiers(ForAll, Exists) and then gives input to the Z3 Solvers ?
Please suggest and help.
This is precisely why people build high-level interfaces to SMT solvers. There are many choices here for z3:
Official Python interface to z3: https://ericpony.github.io/z3py-tutorial/guide-examples.htm This is supported by Microsoft directly, and is probably the easiest to use.
PySMT, which aims to cover as many SMT solvers as they can: https://github.com/pysmt/pysmt
Scala bindings: https://github.com/epfl-lara/ScalaZ3
Haskell SBV: http://hackage.haskell.org/package/sbv
Many others at various maturity levels for Racket, Go, Lisp.. You name it. You can find many of them on github.
The goal of these "wrappers" is to precisely save the end-user from all the details of intricate bindings, and provide something much easier and less-error prone to use. On the flip side, they require you to learn yet another library. In my experience, if the host language of your choice has such an implementation, it'd pay off nicely to use it. If not, you should build one!
I need to make tons of simple computations and present each step in my report with predefined manner:
(for ex i got B=2, C=3):
A=B+12-6/C^2; A=2+12-6/3^2=13.333;
I can get 1st block and answer like this:
B:2$ C:3$
A:'(B+12-6/C^2)$
print("A=",A,"; ","A= ??? =",ev(A, numer) );
and get:
6
A= (- --) + B + 12 ; A= ??? = 13.33333333333333
2
C
What i need instead of '???' to get desired output?
Maxima distinguishes two parts of figuring out a result: evaluation and simplification. Evaluation = substituting one thing (the value) for another thing (a variable or a function). Simplification = applying mathematical identities to get a "simpler", equivalent result.
In your problem, it appears you want to postpone simplification. You can say simp: false to do that. Here's one possible approach. I'll disable simplification, substitute values into the expression, print the substituted expression, and then re-enable simplification to get the final result.
(%i2) expr: A=B+12-6/C^2;
6
(%o2) A = (- --) + B + 12
2
C
(%i3) simp: false $
(%i4) subst ([B = 2, C = 3], expr);
- 2
(%o4) A = 12 + 2 + (- 6) 3
(%i5) simp: true $
(%i6) %o4;
40
(%o6) A = --
3
Note that many operations in Maxima happen by simplification (e.g. adding numbers together), so in general, Maxima will act noticeably different when simp is false. But in this case that's what you want.
EDIT: OP points out that the result after substitution is displayed in a somewhat different from. The reason for this has to do with some obscure implementation details of Maxima. Be that as it may, it's possible to work around that behavior by using the Lisp substitution function SUBST (referenced in Maxima as ?subst) instead of Maxima subst. SUBST is a little different than Maxima subst; the syntax is ?subst(new_thing, old_thing, some_expression). After substituting via SUBST, it's necessary to resimplify explicitly; one way to do that is to say expand(..., 0, 0) (which doesn't expand anything, the only effect is to resimplify).
(%i2) expr: A=B+12-6/C^2;
6
(%o2) A = (- --) + B + 12
2
C
(%i3) simp: false $
(%i4) ?subst (3, C, ?subst (2, B, expr));
6
(%o4) A = (- --) + 2 + 12
2
3
(%i5) simp: true $
(%i6) expand (%o4, 0, 0);
40
(%o6) A = --
3
Since SUBST is has a different effect on the internal representation, it is possible you could create an invalid expression, for some choices of new_thing, old_thing, and some_expression. I won't try to sort that out here.
I am trying to prove commutative property for agda. I tried to explore the standard library but there is lot of complex thing which i could not understand.
I tried in this way --
comm : (a b : Q) -> (a + b) === (b + a)
the problem here is + which is not defined over Q in library. Can't we proof this without defining + over Q.
Please guide me.
You cannot prove this without first defining +.
If you get confused exploring the standard library I suggest you try to prove something easier first, in order to become more acquainted with Agda, before tackling this.
Of course you can't prove commutativity of an undefined function _+_; as a stupid counter-example, would you expect to be able to prove (a - b) == (b - a)? If not, why not? _-_ is just as much of an undefined function as _+_ at this point; it just has a different name...
Note that you can define addition for ℚ using elementary school math:
n ÷ p + m ÷ q = (n * q + m * p) ÷ (p * q)
and simplifying it by dividing both n * q + m * p and p * q with their GCD. I have already explained the details of this last step in this answer.
I have 2 formulas F1 and F2. These two formulas share most variables, except some 'temporary' (or I call them 'free') variables having different names, that are there for some reasons.
Now I want to prove F1 == F2, but prove() method of Z3 always takes into account all the variables. How can I tell prove() to ignore those 'free' variables, and focuses only on a list of variables I really care about?
I mean with all the same input to the list of my variables, if at the output time, F1 and F2 have the same value of all these variables (regardless the values of 'free' variables), then I consider them 'equivalence'
I believe this problem has been solved in other researches before, but I dont know where to look for the information.
Thanks so much.
We can use existential quantifiers to capture 'temporary'/'free' variables.
For example, in the following example, the formulas F and G are not equivalent.
x, y, z, w = Ints('x y z w')
F = And(x >= y, y >= z)
G = And(x > z - 1, w < z)
prove(F == G)
The script will produce the counterexample [z = 0, y = -1, x = 0, w = -1].
If we consider y and w as 'temporary' variables, we may try to prove:
prove(Exists([y], F) == Exists([w], G))
Now, Z3 will return proved. Z3 is essentially showing that for all x and z, there is a y that makes F true if and only if there is a w that makes G true.
Here is the full example.
Remark: when we add quantifiers, we are making the problem much harder for Z3. It may return unknown for problems containing quantifiers.
Apparently, I cannot comment, so I have to add another answer. The process of "disregarding" certain variables is typically called "projection" or "forgetting". I am not familiar with it in contexts going beyond propositional logic, but if direct existential quantification is possible (which Leo described), it is conceptually the simplest way to do it.