Is there anything similar in C++ like Z3py interface's as_expr(). I'm trying to get the result of applying the tactics as a z3 expression, exp, not as type apply_result.
For example, in the below code
context c;
expr x = c.bool_const("x");
expr y = c.bool_const("y");
expr f = ( (x || y) && (x && y) );
solver s(c);
goal g(c);
g.add( f );
tactic t1(c, "simplify");
apply_result r = t1(g);
std::cout << r << "\n";
Also, is there any way to convert the apply_result into z3 expr?
In general, the result of a tactic application is a set of goals. Most tactics produce only one goal, but some produce more than one. For each of those subgoals, you can use as_expr() and then logical-or them together. We can add an as_expr(...) to class apply_result if that helps. (I'm busy with other stuff at the moment; if you add it yourself, submit a pull request, contributions very welcome!)
Related
I am trying to make a solver for nonlinear system of equations using the Z3 library in c++.
It will exists with multiple equations and variables. Depending on previous steps in my software, it could be that some variables are unknown.
When too many variables are unknown and the system does not have a single solution, I want to be notified about this.
I made a simple fictional system of equations for testing that looks as follows:
Ax = 1
Ay = 1
Bx = 3
By = 2
Cx = 7
Cy = Ay + (By - Ay) / (Bx - Ax) * (Cx - Ax)
I wrote the following code to solve the system, in this example fairly easy:
context ctx;
expr Ax = ctx.real_const("Ax");
expr Ay = ctx.real_const("Ay");
expr Bx = ctx.real_const("Bx");
expr By = ctx.real_const("By");
expr Cx = ctx.real_const("Cx");
expr Cy = ctx.real_const("Cy");
solver s(ctx);
s.add(Ax == 1);
s.add(Ay == 1);
s.add(Bx == 3);
s.add(By == 2);
s.add(Cx == 7);
s.add(Cy == Ay + (By - Ay) / (Bx - Ax) * (Cx - Ax));
std::cout << s.check() << "\n";
model m = s.get_model();
auto CySolution = m.eval(Cy, true);
std::cout << CySolution << "\n";
As output I get the following:
sat
4.0
When for example "Ax" would be unknown, this can be simulated using following code:
context ctx;
expr Ax = ctx.real_const("Ax");
expr Ay = ctx.real_const("Ay");
expr Bx = ctx.real_const("Bx");
expr By = ctx.real_const("By");
expr Cx = ctx.real_const("Cx");
expr Cy = ctx.real_const("Cy");
solver s(ctx);
//s.add(Ax == 1);
s.add(Ay == 1);
s.add(Bx == 3);
s.add(By == 2);
s.add(Cx == 7);
s.add(Cy == Ay + (By - Ay) / (Bx - Ax) * (Cx - Ax));
std::cout << s.check() << "\n";
model m = s.get_model();
auto CySolution = m.eval(Cy, true);
std::cout << CySolution << "\n";
Now the output is:
sat
(/ 78.0 23.0)
I have tried detect when this system of equations give an implicit solution using functions as "expr.get_sort()" or "expr.is_real", but there is never a difference between the complete solution and the implicit one.
Now I have two questions:
How can I interpret "(/ 78.0 23.0)"?
Is there a proper way to detect if the solution is an implicit function or not?
Thanks in advance for any help!
(/ 78.0 23.0) simply means 78/23, i.e., approx. 3.39. Z3 prints real-values in this format since they are infinitely precise; as the fraction might require an unbounded number of digits in general.
Your question regarding "proper way to detect is an implicit function" is a bit ambiguous. I assume what you mean is if there's a unique solution? That is, if a variable's value is "forced" by all the other equations or not?
If that's the case, i.e., to check that a solution is unique, you'd essentially get the first solution, then assert the negation of that solution and ask if there's some other solution with this additional constraint: If the solver comes back unsat then you know the solution was unique. See many questions on stack-overflow regarding how to get multiple solutions from the solver.
I am new to Standard ML. I am trying to compute x squared i, where x is a real and i is an non-negative integer. The function should take two parameters, x and i
Here is what I have so far:
fun square x i = if (i<0) then 1 else x*i;
The error that I am getting is that the case object and rules do not agree
The unary negation operator in SML is not - as it is in most languages, but instead ~. That is likely what is causing the specific error you cite.
That said, there are some other issues with this code. L is not bound in the example you post for instance.
I think you may want your function to look more like
fun square (x : real) 0 = 1
| square x i = x * (square x (i - 1))
You'll want to recurse in order to compute the square.
Given a vector v of length say 30, can auto differentiation tools in say theano or tensorflow be able to take the gradient of something like this:
x = np.random.rand(5, 1)
v = f(x, z)
w = v[0:25].reshape(5, 5)
y = g(np.matmul(w, x) + v[25:30])
minimize ( || y - x || )
Would this even make sense? The way I picture it in my mind I would have to do some multiplications by identity vectors/matrices with trailing 0's to convert v --> w
Slice and reshape operations fit into standard reverse mode AD framework in the same way as any other op. Below is a simple TensorFlow program that is similar to the example you gave (I had to change a couple of things to make dimensions match), and the resulting computation graph for the gradient
def f(x, z):
"""Adds values together, reshapes into vector"""
return tf.reshape(x+z, (5,))
x = tf.Variable(np.random.rand(5, 1))
z = tf.Variable(np.random.rand(5, 1))
v = f(x, z)
w = tf.slice(v, 0, 5)
w = tf.reshape(v, (5, 1))
y = tf.matmul(tf.reshape(w, (5, 1)), tf.transpose(x)) + tf.slice(v, 0, 5)
cost = tf.square(tf.reduce_sum(y-x))
print tf.gradients(cost, [x, z])
Let us take a look at the source code:
#ops.RegisterGradient("Reshape")
def _ReshapeGrad(op, grad):
return [array_ops.reshape(grad, array_ops.shape(op.inputs[0])), None]
This is how tensorflow automatically differentiates.
I am wondering if there is a C/C++ library or Matlab code technique to determine real and complex numbers using a minimization solver. Here is a code snippet showing what I would like to do. For example, suppose that I know Utilde, but not x and U variables. I want to use optimization (fminsearch) to determine x and U, given Utilde. Note that Utilde is a complex number.
x = 1.5;
U = 50 + 1i*25;
x0 = [1 20]; % starting values
Utilde = U * (1 / exp(2 * x)) * exp( 1i * 2 * x);
xout = fminsearch(#(v)optim(v, Utilde), x0);
function diff = optim(v, Utilde)
x = v(1);
U = v(2);
diff = abs( -(Utilde/U) + (1 / exp(2 * x)) * exp( 1i * 2 * x ) );
The code above does not converge to the proper values, and xout = 1.7318 88.8760. However, if U = 50, which is not a complex number, then xout = 1.5000 50.0000, which are the proper values.
Is there a way in Matlab or C/C++ to ensure proper convergence, given Utilde as a complex number? Maybe I have to change the code above?
If there isn't a way to do this natively in Matlab, then perhaps one
gist of the question is this: Is there a multivariate (i.e.
Nelder-Mead or similar algorithm) optimization library that is able
to work with real and complex inputs and outputs?
Yet another question is whether the function is convergent or not. I
don't know if it is the algorithm or the function. Might I need to change something in the Utilde = U * (1 / exp(2 * x)) * exp( 1i * 2 * x) expression to make it convergent?
The main problem here is that there is no unique solution to this optimization or parameter fitting problem. For example, looking at the expected and actual results above, Utilde is equivalent (ignoring round-off differences) for the two (x, U) pairs, i.e.
Utilde(x = 1.5, U = 50 + 25i) = Utilde(x = 1.7318, U = 88.8760)
Although I have not examined it in depth, I even suspect that for any value of x, you can find an U that computes to Utilde(x, U) = Utilde(x = 1.5, U = 50 + 25i).
The solution here would thus be to further constrain the parameter fitting problem so that the solver yields any solution that can be considered acceptable. Alternatively, reformulate Utilde to have a unique value for any (x, U) pair.
UPDATE, AUG 1
Given reasonable starting values, it actually seems like it is sufficient to restrict x to be real-valued. Performing unconstrained non-linear optimization using the diff function formulated above, I get the following result:
x = 1.50462926953244
U = 50.6977768845879 + 24.7676554234729i
diff = 3.18731710515855E-06
However, changing the starting guess to values more distant from the desired values does yield different solutions, so restricting x to be real-values does not alone provide a unique solution to the problem.
I have implemented this in C#, using the BOBYQA optimizer, but the numerics should be the same as above. If you want to try outside of Matlab, it should also be relatively simple to turn the C# code below into C++ code using the std::complex class and an (unconstrained) nonlinear C++ optimizer of your own choice. You could find some C++ compatible codes that do not require gradient computation here, and there is also various implementations available in Numerical Recipes. For example, you could access the C version of NR online here.
For reference, here are the relevant parts of my C# code:
class Program
{
private static readonly Complex Coeff = new Complex(-2.0, 2.0);
private static readonly Complex UTilde0 = GetUTilde(1.5, new Complex(50.0, 25.0));
static void Main(string[] args)
{
double[] vars = new[] {1.0, 25.0, 0.0}; // xstart = 1.0, Ustart = 25.0
BobyqaExitStatus status = Bobyqa.FindMinimum(GetObjfnValue, vars.Length, vars);
}
public static Complex GetUTilde(double x, Complex U)
{
return U * Complex.Exp(Coeff * x);
}
public static double GetObjfnValue(int n, double[] vars)
{
double x = vars[0];
Complex U = new Complex(vars[1], vars[2]);
return Complex.Abs(-UTilde0 / U + Complex.Exp(Coeff * x));
}
}
The documentation for fminsearch says how to deal with complex numbers in the limitations section:
fminsearch only minimizes over the real numbers, that is, x must only consist of real numbers and f(x) must only return real numbers. When x has complex variables, they must be split into real and imaginary parts.
You can use the functions real and imag to extract the real and imaginary parts, respectively.
It appears that there is no easy way to do this, even if both x and U are real numbers. The equation for Utilde is not well-posed for an optimization problem, and so it must be modified.
I've tried to code up my own version of the Nelder-Mead optimization algorithm, as well as tried Powell's method. Neither seem to work well for this problem, even when I attempted to modify these methods.
Let's say we have the following statement: s = 3 * a * b - 2 * c, where s, a, b and c are variables. Also, we used Shunting Yard algorithm to build RPN expression, so now we can assign values to variables a, b and c and calculate s value by using simple RPN evaluator.
But, the problem is that I should be able to calculate a value of any variable a, b or c when values of all other variables are set.
So, I need to transform existing expression somehow to get a set of expressions:
a = (s + 2 * c) / (3 * b)
b = (s + 2 * c) / (3 * a)
c = (3 * a * b - s) / 2
How can I generate such expressions on basis of one original statement? Is there any standard approaches for solving such problems?
Constraints:
A set of available operators: +, -, *, /, including unary + and -
operators *, / and = can't have the same variable on both sides (e.g. s = a * a, or s = a + s are not acceptable)
Thanks
See this first: Postfix notation to expression tree to convert your RPN into a tree.
Once you have the equation left expression = right expression change this to left expression - right expression = 0 and create a tree of left expression - right expression via Shunting Yard and the above answer. Thus when you evaluate the tree, you must get the answer as 0.
Now based on your restrictions, observe that if a variable (say x) is unknown, the resulting expression will always be of the form
(ax + b)/(cx + d) where a,b,c,d will depend on the other variables.
You can now recursively compute the expression as a tuple (a,b,c,d).
In the end, you will end up solving the linear equation
(ax + b)/(cx + d) = 0 giving x = -b/a
This way you don't have to compute separate expressions for each variable. One expression tree is enough. And given the other variables, you just recursively compute the tuple (a,b,c,d) and solve the linear equation in the end.
The (incomplete) pseudocode will be
TupleOrValue Eval (Tree t) {
if (!t.ContainsVariable) {
blah;
return value;
}
Tuple result;
if (t.Left.ContainsVariable) {
result = Eval(t.Left);
value = Eval(t.Right);
return Compose(t.Operator, result, value);
} else {
result = Eval(t.Right);
value = Eval(t.Left);
return Compose(t.Operator, result, value);
}
}
Tuple Compose(Operator op, Tuple t, Value v) {
switch (op) {
case 'PLUS': return new Tuple(t.a + v*t.c, t.b + v*t.d, t.c, t.d);
// (ax+b)/(cx+d) + v = ( (a + vc)x + b + dv)/(cx + d)
// blah
}
}
For an example, if the expression is x+y-z = 0. The tree will be
+
/ \
x -
/ \
y z
For y=5 and z=2.
Eval (t.Right) will return y-z = 3 as that subtree does not contain x.
Eval(t.Left) will return (1,0,0,1) which corresponds to (1x + 0)/(0x + 1). Note: the above pseudo-code is incomplete.
Now Compose of (1,0,0,1) with the value 3 will give (1 + 3*0, 0 + 3*1, 0, 1) = (1,3,0,1) which corresponds to (x + 3)/(0x + 1).
Now if you want to solve this you take x to be -b/a = -3/1 = -3
I will leave the original answer:
In general it will be impossible.
For instance consider the expression
x*x*x*x*x + a*x*x*x*x + b*x*x*x + c*x*x + d*x = e
Getting an expression for x basically corresponds to find the roots of the polynomial
x5 + ax4 + bx3 + cx2 + dx -e
which has been proven to be impossible in general, if you want to use +,-,/,* and nth roots. See Abel Ruffini Theorem.
Are there are some restrictions you forgot to mention, which might simplify the problem?
The basic answer is you have to apply algebra to the set of equations you have, to produce equations that you want.
In general, if you start with this symbolic equation:
s = 3 * a * b - 2 * c
and you add constraints for s, a, and c:
s = ...
a = ...
c = ...
you need to apply standard laws of algebra to rearrange the set of equations to produce what you want, in this case, a formula for b:
b = ...
If you add different constraints, you need the same laws of algebra, applied in different ways.
If your equations are all of the form (as your example is not) of
left_hand_side_variable_n = combination_of_variables
then you can use rules for solving simultaneous equations. For linear combinations, this is pretty straightforward (you learned how to do this high school). And you can even set up a standard matrix and solve using a standard solver package without doing algebra.
If the equations are not linear, then you may not be able to find a solution no matter how good your math is (see other answers for examples). To the extent it is possible to do so, you can use a computer algebra system (CAS) to manipulate formulas. They do so by representing the formulas essentially as [math] abstract syntax trees, not as RPN, and apply source-to-source transformation rules (you would call these "algebra rules" from high school). They usually have a pretty big set of built-in rules ("knowledge") already. Some CAS will attempt to solve such systems of equations for you using the built-in rules; others, you have to tell what sequence of algebraic laws to apply in what order.
You may also use a constraint solver, which is a special kind of computer algebra system focused only on answering the kind of question you've posed, e.g., "with this set of constraints, and specific values for variables, what is the value of other variables?". These are pretty good if your equations follows the forms they are designed to solve; otherwise no gaurantee but that's not surprising.
One can also use a program transformation system, which manipulate arbitrary "syntax trees", because algrebra trees are just a special case of syntax trees. To use such a system, you define the langauge to be manipulated (e.g., conventional algebra) and the rules by which it can be manipulated, and the order in which to apply the rules. [The teacher did exactly this for you in your intro algebra class, but not in such a formal way] Here's an example of a my program transformation system manipulating algebra. For equation solving, you want much the same rules, but a different order of application.
Finally, if you want to do this in a C++ program, either you have to simulate one of the above more general mechanisms (which is a huge amount of work), or you have narrow what you are willing to solve significantly (e.g., "linear combinations") so that you can take advantage of a much simpler algorithm.
There is a quite straight-forward one for very basic expressions (like in your example) where each variable occurs mostly once and every operator is binary. The algorithm is mostly what you would do by hand.
The variable we are looking for will be x in the following lines. Transform your expression into the form f(...,x,...) == g(...). Either variable x is already on the left hand side or you just switch both sides.
You now have two functions consisting of applications of binary operators to sub-expressions, i.e. f = o_1(e_1,e_2) where each e_i is either a variable, a number or another function e_i = o_i(e_j, e_k). Think of this as the binary tree representation where nodes are operators and leafs are variables or numbers. Same applies for g.
Yyou can apply the following algorithm (our goal is to transform the tree into one representing the expression x == h(...):
while f != x:
// note: f is not a variable but x is a subexpression of f
// and thus f has to be of the form binop(e_1, e_2)
if x is within e_1:
case f = e_1 + e_2: // i.e. e_1 + e_2 = g
g <- g - e_2
case f = e_1 - e_2: // i.e. e_1 - e_2 = g
g <- g + e_2
case f = e_1 * e_2: // i.e. e_1 * e_2 = g
g <- g / e_2
case f = e_1 / e_2: // i.e. e_1 / e_2 = g
g <- g * e_2
f <- e_1
else if x is within e_2:
case f = e_1 + e_2: // i.e. e_1 + e_2 = g
g <- g - e_2
case f = e_1 - e_2: // i.e. e_1 - e_2 = g
g <- g + e_2
case f = e_1 * e_2: // i.e. e_1 * e_2 = g
g <- g / e_2
case f = e_1 / e_2: // i.e. e_1 / e_2 = g
g <- g * e_2
f <- e_1
Now that f = x and f = g was saved during all steps we have x = g as solution.
In each step you ensure that x remains on the lhs and at the same time you reduce the depth of the lhs by one. Thus this algorithm will terminate after a finite amount of steps.
In your example (solve for b):
f = 3a*b*2c*- and g = s
f = 3a*b* and g = s2c*+
f = b and g = s2c*+3a*/
and thus b = (s + 2*c)/(3*a).
If you have more operators you can extend the algorithm but you might run into problems if they are not invertible.