Z3 check python string satisfiability - python

Is there a way to check satisfiability of a python string like 'p or p -> p' in Z3 if you do not know the variable names before hand?
For example I have seen this:
p = Bool('p')
solve(Implies(Or(p, p), p))
However I cannot define the variables in Z3 in advance because the proposition is given to me as a string. How can I do this with z3?
I have also seen python's eval function but it seems I need to have the variable names defined in z3 of that prior too

Some questions to ponder: What would be the meaning of that string? What if it has syntax-errors in it? How do you discern what are the valid operators/variables? Do you allow just booleans, or other sorts as well? What about grouping, precedence, and associativity of operators?
Bottom line, if you want to go directly from a string, you really have no choice but to agree on a syntax and a semantics of what those strings mean. And the only way to do that is to write a parser for those strings, and "interpret" that result in the z3 context.
One choice is to "stick" to SMTLib, i.e., ask your input to be well-formatted SMTLib scripts. If you go with this choice, then z3 already have a built-in parser for them that you can readily use. See here: https://z3prover.github.io/api/html/namespacez3py.html#a09fe122cbfbc6d3fa30a79850b2a2414 But I'm pretty sure you'll find this rather ugly and not quite what you wanted. But this is the only "out-of-the-box" solution.
The proper way to handle this issue is to write a basic parser over boolean-expressions, whose syntax (and to some extent semantics) you'll have freedom to define however way you want. Also, this isn't a particularly difficult thing to do. If you're doing this in Python, you can use ply (https://www.dabeaz.com/ply/), or go with a hand-written recursive-descent parser (https://www.booleanworld.com/building-recursive-descent-parsers-definitive-guide/).
Feel free to explore and ask further questions; though make sure to tag them appropriately if it's about parsing strings in Python; which really have nothing to do with z3/z3py.

Related

Is there a way to convert a list containing arithmetic operations which is written as a string into an actual list?

I would like to convert a String like:
s = "[2-1,2,3]"
into a list, like:
a = [1,2,3]
I tried it with json:
s = "[2-1,2,3]"
a = json.loads(s)
but it can't handle 2-1.
Is there an easy method to convert strings into any kind of datatype?
Yes. And as much as it pains me to say it, eval is your friend here, as even ast.literal_eval cannot parse this.
Please read this first: eval: bad practice?, and please ensure you have complete control over the expressions being evaluated.
To help lessen the expressions being evaluated, I've wrapped this solution in regex, to extract only numbers and (in this case) the minus sign.
Obviously, this might need tweaking for your specific use case, this this should give you a boiler-plate (or at least an idea) from which to start.
Example code:
import re
s = "[2-1,2,3]"
rexp = re.compile('[\d-]+')
out = []
for exp in rexp.findall(s):
out.append(eval(exp))
Or, if you prefer a one-liner:
out = [eval(exp) for exp in rexp.findall(s)]
Output:
[1, 2, 3]
This is a common problem to tackle while writing compilers. Usually this comes under lexing.
A parser would usually have a list of tokens, watch for the tokens and then pass it to a parser and then the compiler.
Your problem cannot be completely solved with a lexer though since you also require the 2-1 to evaluate to 1. In this case, I would suggest using eval like #Daniel Hao suggested since it is a simple and clean way of achieving your goal. Remember about the caveats(both security and otherwise) while using it though. (especially, in production)
If you are interested in the parsing though, check this out:
https://craftinginterpreters.com/contents.html
https://tomassetti.me/parsing-in-python/

Python- stuck trying to create a "free hand" calculator

I'm trying to create a calculator program in which the user can type an equation and get an answer. I don't want the full code for this, I just need help with a specific part.
The approach I am trying to take is to have the user input the equation as a string (raw_input) and then I am trying to convert the numbers from their input to integers. After that I need to know how I can get the operands to do what I want them to do depending on which operand the user uses and where it is in the equation.
What are some methods I might use to accomplish this task?
Here is basically what I have right now:
equation_number = raw_input("\nEnter your equation now: ")
[int(d) for d in equation_number if d.isdigit()]
Those lines are just for collecting input and attempting to convert the numbers into integers. Unfortunately, it does not seem to be working very well and .isdigit will only work for positive numbers anyway.
Edit- aong152 mentioned recursive parsing, which I looked into, and it appears to have desirable results:
http://blog.erezsh.com/how-to-write-a-calculator-in-70-python-lines-by-writing-a-recursive-descent-parser/
However, I do not understand the code that the author of this post is using, could anyone familiarize me with the basics of recursive parsing?
The type of program you are trying to make is probably more complicated than you think
The first step would be separating the string into each argument.
Let's say that the user inputs:
1+2.0+3+4
Before you can even convert to ints, you are going to need to split the string up into its components:
1
+
2.0
+
3
+
4
This will require a recursive parser, which (seeing as you are new to python) maybe be a bit of a hurdle.
Assuming that you now have each part seperately as strings,
float("2.0") = 2.0
int(2.0) = 2
Here is a helper function
def num (s):
try:
return int(s)
except exceptions.ValueError:
return int(float(s))
instead of raw_input just use input because raw_input returns a string and input returns ints
This is a very simple calculator:
def calculate():
x = input("Equation: ")
print x
while True:
calculate()
the function takes the input and prints it then the while loop executes it again
im not sure if this is what you want but here you go and also you should make a way to end the loop
After using raw_input() you can use eval() on the result to compute the value of this string. eval() evaluates any valid Python expression and returns the outcome.
But I think this is not to your liking. You probably want to do more by yourself.
So I think you should have a look at the re module to split the input using regular expressions into tokens (sth like numbers and operators). After this you should write a parser which gets the token stream as input. You should decide whether this parser shall just return the computed value (e. g. a number) or maybe an abstract syntax tree, i. e. a data structure which represents the expression in an object-oriented (instead of character-oriented) way. Such an Absy could then be evaluated to get the final result.
Are you familiar with regular expressions? If not, it's probably a good idea to first learn about them. They are the weak, non-recursive cousin of parsing. Don't go deep, just understand the building blocks — A then B, A many times, A or B.
The blog post you found is hard because it implements the parsing by hand. It's using recursive descent, which is the only way to write a parser by hand and keep your sanity, but it's still tricky.
What people do most of the time is only write a high level grammar and use a library (or code generator) to do the hard work of parsing.
Indeed he had an earlier post where he uses a library:
http://blog.erezsh.com/how-to-write-a-calculator-in-50-python-lines-without-eval/
At least the beginning should be very easy. Things to pay attention to:
How precedence arises from the structure of the grammar — add consists of muls, not vice versa.
The moment he adds a rule for parentheses:
atom: neg | number | '(' add ')';
This is where it really becomes recursive!
6-2-1 should parse as (6-2)-1, not 6-(2-1). He doesn't discuss it, but if you look
carefully, it also arises from the structure of the grammar. Don't waste tome on this; just know for future reference that this is called associativity.
The result of parsing is a tree. You can then compute its value in a bottom-up manner.
In the "Calculating!" chapter he does that, but the in a sort of magic way.
Don't worry about that.
To build a calculator yourself, I suggest you strip the problem as much as possible.
Recognizing where numbers end etc. is a bit messy. It could be part of the grammar, or done by a separate pass called lexer or tokenizer.
I suggest you skip it — require the user to type spaces around all operators and parens. Or just assume you're already given a list of the form [2.0, "*", "(", 3.0, "+", -1.0, ")"].
Start with a trivial parser(tokens) function that only handles 3-element expressions — [number, op, number].
Return a single number, the result of the computation. (I previously said parsers output a tree which is processed later. Don't worry about that, returning a number is simpler.)
Write a function that expects either a number or parentheses — in the later case it calls parser().
>>> number_or_expr([1.0, "rest..."])
(1.0, ["rest..."])
>>> number_or_expr(["(", 2.0, "+", 2.0, ")", "rest..."])
(4.0, ["rest..."])
Note that I'm now returning a second value - the remaining part of the input. Change parser() to also use this convention.
Now Rewrite parser() to call number_or_expr() instead of directly assuming tokens[0] and tokens[2] are numbers.
Viola! You now have a (mutually) recursive calculator that can compute anything — it just has to be written in verbose style with parens around everything.
Now stop and admire your code, for at least a day :-) It's still simple but has the essential recursive nature of parsing. And the code structure reflects the grammar 1:1 (which is the nice property of recursive descent. You don't want to know how the other algorithms look).
From here there many improvements possible — support 2+2+2, allow (1), precedence... — but there are 2 ways to go about it:
Improve your code step by step. You'll have to refactor a lot.
Stop working hard and use a parsing library, e.g. pyparsing.
This will allow you to experiment with grammar changes faster.

Can I do math inside Python's string formatting "language"?

I would like to do some simple math while I'm doing string formatting. For example
N = {'number':3}
four = '{number:d + 1}'.format(**N)
This doesn't work (of course). Is there a way to accomplish this that I'm not aware of?
Thanks!
"Is there a way to accomplish this that I'm not aware of?" If by "this" you mean encoding some mathematical logic in the format string using str.format, then no -- not that I'm aware of. However if you use a templating language you can express all kinds of stuff like this.
There are a billion different options for templating languages in Python, so rather than try to say which is best, I'll let you decide. See this article from the Python wiki: http://wiki.python.org/moin/Templating
A favorite of mine is Jinja2, although it's probably overkill for what you're talking about.
Here's an example of how to accomplish what you're after with Jinja2:
N = { 'd' : 3 }
four = Template(u'number:{{ d + 1 }}').render(**N)
The main advantage to a templating system like Jinja2 is that it allows you store templates as files separate from your application control logic such that you can maintain the view/presentation logic for your program in a way that limits or prohibits side effects from presentation execution.
About as close as you can get is to use positional arguments instead of keyword arguments:
four='{0:d}'.format(N['number']+1)
or the shorter old-school:
four='%d'%(N['number']+1)
What's your goal here?

Reqular expression to separate equalities

Does anyone have some good resources on learning more advanced regular expressions
I keep having problems where I want to make sure something is not enclosed in quotation marks
i.e. I am trying to make an expression that will match lines in a python file containing an equality, i.e.
a = 4
which is easy enough, but I am having trouble devising an expression that would be able to separate out multiple terms or ones wrapped in quotes like these:
a, b = b, a
a,b = "You say yes, ", "i say no"
Parsing code with regular expressions is generally not a good idea, as the grammar of a programming language is not a regular language. I'm not much of a python programmer, but I think you would be a lot better off parsing python code with python modules such as this one or this one
A think that you have to tokenize the expression for correct evaluation but you can detect the pattern using the following regex
r'\s+(\w+)(\s*,\s*\w+)*\s*=\s*(.*?)(\s*,\s*.*?)*'
If group(2) and group(4) are not empty you have to tokenize the expression
Note that if you have
a,b = f(b,a), g(a,b)
It is hard to analyze
Python has an excellent Language Reference that also includes descriptions of the lexical analysis and syntax.
In your case both statements are assignments with a list of targets on the left hand side and and a list of expressions on the right hand side.
But since parts of that grammar part are context-free and not regular, you can’t use regular expressions (unless they support some kind of recursive patterns). So better use a proper parser as Jonas H suggested.

regular expression help with converting exp1^exp2 to pow(exp1, exp2)

I am converting some matlab code to C, currently I have some lines that have powers using the ^, which is rather easy to do with something along the lines \(?(\w*)\)?\^\(?(\w*)\)?
works fine for converting (glambda)^(galpha),using the sub routine in python pattern.sub(pow(\g<1>,\g<2>),'(glambda)^(galpha)')
My problem comes with nested parenthesis
So I have a string like:
glambdastar^(1-(1-gphi)*galpha)*(glambdaq)^(-(1-gphi)*galpha);
And I can not figure out how to convert that line to:
pow(glambdastar,(1-(1-gphi)*galpha))*pow(glambdaq,-(1-gphi)*galpha));
Unfortunately, regular expressions aren't the right tool for handling nested structures. There are some regular expressions engines (such as .NET) which have some support for recursion, but most — including the Python engine — do not, and can only handle as many levels of nesting as you build into the expression (which gets ugly fast).
What you really need for this is a simple parser. For example, iterate over the string counting parentheses and storing their locations in a list. When you find a ^ character, put the most recently closed parenthesis group into a "left" variable, then watch the group formed by the next opening parenthesis. When it closes, use it as the "right" value and print the pow(left, right) expression.
I think you can use recursion here.
Once you figure out the Left and Right parts, pass each of those to your function again.
The base case would be that no ^ operator is found, so you will not need to add the pow() function to your result string.
The function will return a string with all the correct pow()'s in place.
I'll come up with an example of this if you want.
Nested parenthesis cannot be described by a regexp and require a full parser (able to understand a grammar, which is something more powerful than a regexp). I do not think there is a solution.
See recent discussion function-parser-with-regex-in-python (one of many similar discussions). Then follow the suggestion to pyparsing.
An alternative would be to iterate until all ^ have been exhausted. no?.
Ruby code:
# assuming str contains the string of data with the expressions you wish to convert
while str.include?('^')
str!.gsub!(/(\w+)\^(\w+)/, 'pow(\1,\2)')
end

Categories