Declaring a finite sort in z3 - python

Let us assume I have a finite set {e1, e2, e3}. I want to be able to distinguish transitive constraints so I can handle this behavior:
from z3 import *
solver = Solver()
A = DeclareSort('A')
x = Const('x', A)
y = Const('y', A)
z = Const('z', A)
solver.add(x!=y)
solver.add(y!=z)
solver.add(x==z)
assert solver.check() != z3.sat
The only way I found to solve it is changing the last constraint with this one:
solver.add(ForAll([x,z],x==z))
Is this the way to model it? Is there any finite sort available? Should I need to add all the constraints declaring the elements different from each other?
Some clarification: Maybe is not a variable what I need, because {x == y, y == z, x == z } is clearly sat, but the behavior I want to model is more like this {x == 1, 2 == z, x == z } that is obviously unsat (assuming some finite sort like {1,2,3,4}).

What I was looking for was the EnumSort:
from z3 import *
solver = Solver()
S, (a, b, c) = EnumSort('round', ['a','b','c'])
x = Const("x", S)
z = Const("z", S)
solver.add(x==a)
solver.add(z==b)
solver.add(x==z)
assert solver.check() != z3.sat

Related

z3py: Symbolic expressions cannot be cast to concrete Boolean values?

from z3 import *
x = Real('x')
s = Solver()
s.add(x > 1 or x < -1)
print(s.check())
if s.check() == sat:
print(s.model())
I want to solve a or expressions , how can i do it?
when z3 told me "Symbolic expressions cannot be cast to concrete Boolean values"
Python's or is not symbolic aware. Instead, use z3py's Or:
from z3 import *
x = Real('x')
s = Solver()
s.add(Or(x > 1, x < -1))
r = s.check()
print(r)
if r == sat:
print(s.model())
This prints:
sat
[x = -2]
Note that I'd also avoid two separate calls to check, by storing the result in a variable first. (Which I called r above.) In general, the second call to check will be cheap since you haven't added any constraints after the first, but this makes the intention clearer.

Python sympy symbols

When I use "x" and "z" as symbols, I have no problem with this code:
from sympy import *
x, z = symbols('x z')
y = -6*x**2 + 2*x*z**0.5 + 50*x - z
solve((diff(y, x), diff(y, z)))
y.subs({x: 5, z: 25})
But when I use "q" and "a", solve does not give me any solution.
q, a = symbols('q a')
y = -6*q**2 + 2*q*a**0.5 + 50*q - a
solve((diff(y, q), diff(y, a)))
y.subs({q: 5, a: 25})
As you can see I use "subs" to check that there is no typo in the objective function.
UPDATE: I used "Symbol" to set each variable individually, but again using "q" and "a" does not work.
# This works
x = Symbol('x')
z = Symbol('z')
y = -6*x**2 + 2*x*z**0.5 + 50*x - z
solve((diff(y, x), diff(y, z)))
# This does not work
q = Symbol('q')
a = Symbol('a')
y = -6*q**2 + 2*q*a**0.5 + 50*q-a
solve((diff(y, q), diff(y, a)))
Thank you.
Got it!
It all depends on an alphabetic order of your variables.
If you substitute x for z and z for x in your first example it will also stop working.
Internally solve sends the expression to the function _solve in sympy.solvers which then tries to solve your equation and fails many times.
Finally as a last effort what it does is it tries to solve -sqrt(a) + q or x - sqrt(z) by picking symbols from it through an internal function _ok_syms, with an argument that sorts those alphabetically (even without this argument it still would, but if wrapped with reversed it magically makes your examples works in the exactly opposite way).
And so it does solve x - sqrt(z) as x: sqrt(z) and -sqrt(a) + q as a: q**2.
While in the first case it ends up with an easily solvable 50 - 10*sqrt(z), in the second case it is lost on -12*q + 2*sqrt(q**2) + 50 as it is not able to simplify sqrt(q**2).
source:
a lot of testing on:
https://github.com/sympy/sympy/blob/master/sympy/solvers/solvers.py

'NoneType' object is not iterable - where is an error?

My aim is to take a triple (A, B, C), compute three "neighbours", and then output the maximum of each of those neighbours to a list.
For example, the neighbours of (sqrt(6), 4*sqrt(3), 9*sqrt(2)) are
(sqrt(3)*sqrt(2), 3*sqrt(2), 4*sqrt(3))
(4*sqrt(3), 35*sqrt(3)*sqrt(2), 9*sqrt(2))
(sqrt(3)*sqrt(2), 9*sqrt(2), 14*sqrt(3))
so the values 14*sqrt(3), 36*sqrt(6), 4*sqrt(3) would be the output.
When I try this:
A = 1*sqrt(6)
B = 4*sqrt(3)
C = 9*sqrt(2)
def nbhs_1(triple):
X = triple[0]
Y = triple[1]
Z = triple[2]
print((X.canonicalize_radical(), (X * Y - Z).canonicalize_radical(), Y.canonicalize_radical()))
def nbhs_2(triple):
X = triple[0]
Y = triple[1]
Z = triple[2]
print((Y.canonicalize_radical(), (Y * Z - X).canonicalize_radical(), Z.canonicalize_radical()))
def nbhs_3(triple):
X = triple[0]
Y = triple[1]
Z = triple[2]
print((X.canonicalize_radical(), Z.canonicalize_radical(), (X * Z - Y).canonicalize_radical()))
result_1 = nbhs_1((A, B, C))
result_2 = nbhs_2((A, B, C))
result_3 = nbhs_3((A, B, C))
print(result_1)
print(result_2)
print(result_3)
l = [max(result_1), max(result_2), max(result_3)]
I get 'NoneType' object is not iterable.
The main problem is that you are not structuring the function properly:
It is recommended that you expose your arguments within the function call. Don't def nbhs_1(triple), do instead def nbhs_1(X, Y, Z). In this way you can actually have one single function that does what you want (easier to maintain)
Return your result. At the moment you are printing the outcome of the function call but you are not returning those results.
I'm also not sure the canonicalize_radical() call is also done properly. Python is object-oriented and by writing var.canonicalize_radical() you are inferring that var should itself know about this function (e.g. the function is part of var) but that sounds wrong. The correct call may be canonicalize_radical(var)
Basically, this should be closer to a correct solution:
A=1*sqrt(6)
B=4*sqrt(3)
C=9*sqrt(2)
def nbhs(X, Y, Z):
out1 = canonicalize_radical(X)
out2 = canonicalize_radical(X*Y-Z)
out3 = canonicalize_radical(Y)
return out1, out2, out3
l = [max(nbhs(A, B, C)), max(nbhs(B, A, C)), max(nbhs(C, B, A))]
The problem is that you are not calling the functions nbhs_1, nbhs_2, and nbhs_3 and also the functions aren't returning any values
from math import sqrt
A=1*sqrt(6)
B=4*sqrt(3)
C=9*sqrt(2)
triple = (A, B, C)
def nbhs_1(triple):
X=triple[0]
Y=triple[1]
Z=triple[2]
return (X.canonicalize_radical(),(X*Y-Z).canonicalize_radical(),Y.canonicalize_radical())
def nbhs_2(triple):
X=triple[0]
Y=triple[1]
Z=triple[2]
return (Y.canonicalize_radical(),(Y*Z-X).canonicalize_radical(),Z.canonicalize_radical())
def nbhs_3(triple):
X=triple[0]
Y=triple[1]
Z=triple[2]
return (X.canonicalize_radical(),Z.canonicalize_radical(),(X*Z-Y).canonicalize_radical())
l=[max(nbhs_1(triple)),max(nbhs_2(triple)),max(nbhs_3(triple))]

How can make a axiom in Z3Py correctly?

I am working in this axiom ForAll X( f(x) > 0 -> b == True) .
How I could to do it in Z3Py? I try to do this:
from z3 import *
Z = IntSort()
f = Function('f', Z, Z)
g = Function('g', Z, Z)
a, n, x = Ints('a n x')
b = BoolSort()
solve(ForAll(x,Implies(f(x) > 0,b ==True)))
but Python return me AttributeError: 'bool' object has no attribute 'ast'
You can declare b as b = Bool('b'). Then it works.
By the way, you can replace b == True by just b as in
solve(ForAll(x,Implies(f(x) > 0, b ))).
BoolSort etc. are meant for parameters to Z3Py functions, not for variables.
What's your axiom trying to state? Note that in the formula ForAll X. (f(x) > 0 -> b == True), b is a free variable. So, this doesn't really seem to correspond to anything logical. But, if that's what you really want to say, this is how you'd code it:
from z3 import *
Z = IntSort()
f = Function('f', Z, Z)
g = Function('g', Z, Z)
a, n, x = Ints('a n x')
b = Bool('b')
solve(ForAll(x,Implies(f(x) > 0, b)))
And we get:
$ python a.py
[b = False, f = [else -> 0]]
What's z3 telling us? It says, OK, I'll pick f to be a function that maps everything to 0. So, your implication will have a antecedent 0 > 0, which is always false, and thus the implication is always true. (False implies anything.) The choice for False for b in the model is really irrelevant.
So, z3 did find you a model for f and b that satisfied your quantified assertion. Just like you asked. But I suspect this wasn't really the formula you were trying to assert. Axioms are typically closed: That is, they have no free variables, other than the uninterpreted functions symbols they include. Of course, this all depends on what exactly you're trying to do.

Equation solver in Python

Given a simple equation such as:
x = y + z
You can get the third variable if you bind the other two (ie: y = x - z and z = x - y). A straightforward way to put this in code:
def solve(args):
if 'x' not in args:
return args['y'] + args['z']
elif 'z' not in args:
return args['x'] - args['y']
elif 'y' not in args:
return args['x'] - args['z']
else:
raise SomeError
I obviously can take an equation, parse it and simplify it to achieve the same effect.
But I believe in doing so I would be re-inventing the wheel. So where's my ready-made wheel?
Consider using Sympy. It includes various tools to solve equations and a lot more.
The following is an excerpt from the docs:
>>> from sympy import I, solve
>>> from sympy.abc import x, y
>>> solve(x**4-1, x)
[1, -1, -I, I]

Categories

Resources