I'm trying to find the solutions of a function that contains a logical expression, but with no success so far.
First, I defined several functions:
isPlant(x) := is ((x = "tree") or (x = "grass"));
isAnimal(x) := is ((x = "cat") or (x = "dog"));
isLiving(x) := is (isAnimal(x) or isPlant(x));
Next, I tried to find all solutions of an equation with these functions, but none of the solutions were obtained:
solve([Living(x) = true], [x]); //this returns an empty list instead of [x = "cat", x = "dog", x = "tree", x = "grass"]
Is is possible to obtain solutions of these functions in Maxima?
The solve function assumes that the domain is a set of numbers. If we first specify the domain
(%i) domain : {"tree","grass","cat","dog"};
(%o) {cat, dog, grass, tree}
then we can use the subset function to find the solutions of the equations.
(%i) subset(domain,lambda([x], is(isPlant(x)=true)));
(%o) {grass, tree}
The functions you've defined are predicates, and so return the values true and false, which means that the equations predicate(x)=true are equivalent to predicate(x). For example, IsLiving(x)=true if and only if IsLiving(x). So rather than finding the elements of the domain which are solutions of the equation predicate(x)=true, we can find the elements of the domain which satisfy the predicate, which is more concise.
(%i) subset(domain,isLiving);
(%o) {cat, dog, grass, tree}
(%i) subset(domain,isPlant);
(%o) {grass, tree}
Related
I have a finite set of pairs of type (int a, int b). The exact values of the pairs are explicitly present in the knowledge base. For example it could be represented by a function (int a, int b) -> (bool exists) which is fully defined on a finite domain.
I would like to write a function f with signature (int b) -> (int count), representing the number of pairs containing the specified b value as its second member. I would like to do this in z3 python, though it would also be useful to know how to do this in the z3 language
For example, my pairs could be:
(0, 0)
(0, 1)
(1, 1)
(1, 2)
(2, 1)
then f(0) = 1, f(1) = 3, f(2) = 1
This is a bit of an odd thing to do in z3: If the exact values of the pairs are in your knowledge base, then why do you need an SMT solver? You can just search and count using your regular programming techniques, whichever language you are in.
But perhaps you have some other constraints that come into play, and want a generic answer. Here's how one would code this problem in z3py:
from z3 import *
pairs = [(0, 0), (0, 1), (1, 1), (1, 2), (2, 1)]
def count(snd):
return sum([If(snd == p[1], 1, 0) for p in pairs])
s = Solver()
searchFor = Int('searchFor')
result = Int('result')
s.add(Or(*[searchFor == d[0] for d in pairs]))
s.add(result == count(searchFor))
while s.check() == sat:
m = s.model()
print("f(" + str(m[searchFor]) + ") = " + str(m[result]))
s.add(searchFor != m[searchFor])
When run, this prints:
f(0) = 1
f(1) = 3
f(2) = 1
as you predicted.
Again; if your pairs are exactly known (i.e., they are concrete numbers), don't use z3 for this problem: Simply write a program to count as needed. If the database values, however, are not necessarily concrete but have other constraints, then above would be the way to go.
To find out how this is coded in SMTLib (the native language z3 speaks), you can insert print(s.sexpr()) in the program before the while loop starts. That's one way. Of course, if you were writing this by hand, you might want to code it differently in SMTLib; but I'd strongly recommend sticking to higher-level languages instead of SMTLib as it tends to be hard to read/write for anyone except machines.
I have problem by writing quadratic constraints by docplex in python
This is my constraint:
A[i,j,k]=Z[i,j,k] *h[i,j,k]+Q[i,j,k]*d[i,j,k] ∀i,j,k
I wrote the constraint as below:
mdl.add_quadratic_constraints(z_qsd[i,j,k]*h_qsd[i,j,k]+Q_qsd[i,j,k]*d_qsd[i,j,k]==A_qsd[i,j,k] for i in q_ualification for j in s_hift for k in d_ay)
when I solve the model, I get this message:
Model is non-convex
The multiplication operator '*' has been overloaded in DOcplex to write quadratic expression. In other terms, you can multiply two variables.
Forgetting about indices, and assuming you have only four variables A,z,h,Q
the constraint can be written as:
mdl.add(A == Z *h + Q *d)
Now, for three-dimensional variables, you should use a variation of Model.continuous_var_cube (change the type), for example:
As = mdl.continous_var_cube(3,5,7, "A")
which builds a Python dictionary of variables, indexed by tuples of indices in the cartesian product of the
three ranges (1..3)x(1..5)x(1..7), that is 3x5x7 = 85 variables.
Each variable can be accessed by a collection of indices,
as in
a123 = As[1,2,3]
Here is a small quadratic-objective
problem example, inspired by the famous "zoo" examples from Alex Fleischer
(see https://www.linkedin.com/pulse/making-optimization-simple-python-alex-fleischer/ for more)
mdl = Model(name='buses')
nbbus40 = mdl.integer_var(name='nbBus40')
nbbus30 = mdl.integer_var(name='nbBus30')
mdl.add_constraint(nbbus40*40 + nbbus30*30 >= 300, 'kids')
# X**2 is the square of variable X
mdl.minimize(500 * nbbus40**2 + 400 * nbbus30**2)
mdl.solve()
for v in mdl.iter_integer_vars():
print(v," = ",v.solution_value)
F(x1) > a;
F(x2) < b;
∀t, F'(x) >= 0 (derivative) ;
F(x) = ∑ ci*x^i; (i∈[0,n] ; c is a constant)
Your question is quite ambiguous, and stack-overflow works the best if you show what you tried and what problems you ran into.
Nevertheless, here's how one can code your problem for a specific function F = 2x^3 + 3x + 4, using the Python interface to z3:
from z3 import *
# Represent F as a function. Here we have 2x^3 + 3x + 4
def F(x):
return 2*x*x*x + 3*x + 4
# Similarly, derivative of F: 6x^2 + 3
def dF(x):
return 6*x*x + 3
x1, x2, a, b = Ints('x1 x2 a b')
s = Solver()
s.add(F(x1) > a)
s.add(F(x2) < b)
t = Int('t')
s.add(ForAll([t], dF(t) >= 0))
r = s.check()
if r == sat:
print s.model()
else:
print ("Solver said: %s" % r)
Note that I translated your ∀t, F'(x) >= 0 condition as ∀t. F'(t) >= 0. I assume you had a typo there in the bound variable.
When I run this, I get:
[x1 = 0, x2 = 0, b = 5, a = 3]
This method can be generalized to arbitrary polynomials with constant coefficients in the obvious way, but that's mostly about programming and not z3. (Note that doing so in SMTLib is much harder. This is where the facilities of host languages like Python and others come into play.)
Note that this problem is essentially non-linear. (Variables are being multiplied with variables.) So, SMT solvers may not be the best choice here, as they don't deal all that well with non-linear operations. But you can deal with those problems as they arise later on. Hope this gets you started!
I am trying to solve a problem that consists of n actions (n >= 8). A path consists k (k == 4 for now) actions. I would like to check if there exists any path, which satisfies the set of constraints I defined.
I have made two attempts to solve this problem:
Attempt 1: Brute force, try all permutations
Attempt 2: Code a path selection matrix M [k x n], such that each row contains one and only one element greater than 0, and all other elements equal to 0.
For instance if k == 2, n == 2, M = [[0.9, 0], [0, 0.7]] represents perform action 1 first, then action 2.
Then my state transition was coded as:
S1 = a2(a1(S0, M[1][1]), M[1][2]) = a2(a1(S0, 0.9), 0)
S2 = a2(a1(S1, M[2][1]), M[2][2]) = a2(a1(S1, 0), 0.7)
Note: I made sure that S == a(S,0), so that in each step only one action is executed.
Then constraints were checked on S2
I was hoping this to be faster than the permutation way of doing it. Unfortunately, this turns out to be slower. Just wondering if there is any better way to solve this problem?
Code:
_path = [[Real(f'step_{_i}_action_{_j}') for _j in range(len(actions))] for _i in range(number_of_steps)]
_states: List[State] = [self.s0]
for _i in range(number_of_steps):
_new_state = copy.deepcopy(_states[-1])
for _a, _p in zip(actions, _path[_i]):
self.solver.add(_a.constraints(_states[-1], _p))
_new_state = _a.execute(_new_state, _p)
_states.append(_new_state)
I am trying to understand how the bound variables are indexed in z3.
Here in a snippet in z3py and the corresponding output. ( http://rise4fun.com/Z3Py/plVw1 )
x, y = Ints('x y')
f1 = ForAll(x, And(x == 0, Exists(y, x == y)))
f2 = ForAll(x, Exists(y, And(x == 0, x == y)))
print f1.body()
print f2.body()
Output:
ν0 = 0 ∧ (∃y : ν1 = y)
y : ν1 = 0 ∧ ν1 = y
In f1, why is the same bound variable x has different index.(0 and 1). If I modify the f1 and bring out the Exists, then x has the same index(0).
Reason I want to understand the indexing mechanism:
I have a FOL formula represented in a DSL in scala that I want to send to z3. Now ScalaZ3 has a mkBound api for creating bound variables that takes index and sort as arguments. I am not sure what value should I pass to the index argument. So, I would like to know the following:
If I have two formulas phi1 and phi2 with maximum bound variable indexes n1 and n2, what would be the index of x in ForAll(x, And(phi1, phi2))
Also, is there a way to show all the variables in an indexed form? f1.body() just shows me x in indexed form and not y. (I think the reason is that y is still bound in f1.body())
Z3 encodes bound variables using de Bruijn indices.
The following wikipedia article describes de Bruijn indices in detail:
http://en.wikipedia.org/wiki/De_Bruijn_index
Remark: in the article above the indices start at 1, in Z3, they start at 0.
Regarding your second question, you can change the Z3 pretty printer.
The Z3 distribution contains the source code of the Python API. The pretty printer is implemented in the file python\z3printer.py.
You just need to replace the method:
def pp_var(self, a, d, xs):
idx = z3.get_var_index(a)
sz = len(xs)
if idx >= sz:
return seq1('Var', (to_format(idx),))
else:
return to_format(xs[sz - idx - 1])
with
def pp_var(self, a, d, xs):
idx = z3.get_var_index(a)
return seq1('Var', (to_format(idx),))
If you want to redefine the HTML pretty printer, you should also replace.
def pp_var(self, a, d, xs):
idx = z3.get_var_index(a)
sz = len(xs)
if idx >= sz:
# 957 is the greek letter nu
return to_format('ν<sub>%s</sub>' % idx, 1)
else:
return to_format(xs[sz - idx - 1])
with
def pp_var(self, a, d, xs):
idx = z3.get_var_index(a)
return to_format('ν<sub>%s</sub>' % idx, 1)