-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expression utility class for C++ solvers #582
Merged
Merged
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
- Accepts a Python statement string - Contains static class `ValidationVisitor` to validate parsed expression
- Static method `map_operator` for mapping strings to actual AST operators - Modify `with_*` methods to create a duplicate expression rather than mutating - Updated `validate` method for validating any expression against the given state
Processes the parsed AST into a Python string, accessible with `.getexpr()`. - New `PythonConverter` class, member of `Expression` class - Base wrapper with `Expression#getexpr_python` method
- Adds `**` and `^` as mapped operators - Adds `convert` method to convert Xor to `**` - C++ transformer for converting Python-exclusive operators to C++ function calls
- Move converter classes out of base `Expression` class - Implement base `Converter` class for both Python and C++ converters to inherit from - Implement logical and/or expressions
- Add comparison operators to visitor class - Call `get_str()` from `Expression` class for C++ expressions
- Performs substitution on statement strings if requested - Additional operators are now supported
- Remove call to `Reaction#sanitized_propensity_function` - Remove circular import caused by `import log`
- Add `Num`, `Str`, `Bytes`, `NameConstant`, and `Ellipsis` visitor methods - These are deprecated in favor of `Constant` in 3.8, but are required in 3.7 - Remove random print statement
…o Python. - Test case added to `test_c_solvers.py` - Converts C++ strings with complex operations, compiles to C, asserts the results - Could use additional tests for boolean operators, blacklists, etc.
- Test suite now includes `comparisons` list for asserting booleans and comparators - FIX: bug where multiple boolean operators would be overridden by the outermost one - Discovered because of the above boolean expression tests!
…llesPy2 into feature/expression-validation
- Added `ExpressionResults` class, acts as "struct" for validation - Contains any invalid names/operators found - Updated `blacklist` to accept both lists and dict - Stored as a dictionary mapping AST operators to their strings - Lets us print the actual operator symbol when logging
This was referenced Jul 26, 2021
- Allows for unary subtract, for constants like `-1.0`
Merged
ethangreen-dev
approved these changes
Aug 2, 2021
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Upcoming SBML features (function definitions and events, especially) will require more advanced conversions from Python expressions to C++ expressions, in particular for language constructs like boolean operators. This utility class is used to convert a valid Python expression into a valid C++ expression, within reason.
Expression
ClassCreate an expression context with
namespace
(dictionary of mappings, the keys of which are expected to be valid names in the namespace) andblacklist
(a list of operators which are not allowed). Once created, theExpression#getexpr_cpp
andExpression#getexpr_python
can be called to extract C++ and Python expressions, respectively. IfExpression
is constructed withsanitize=True
, then the identifiers in the expression will be substituted with the identifiers provided in thenamespace
dict.Additionally, the
Expression#validate
method may be used to verify that the provided expression is, indeed, a valid Python expression, given the provided namespace and blacklist. A standardSyntaxError
will be raised if the expression cannot be parsed.Intended Use
The
template_gen
methods have been updated to use the newExpression
class for sanitizing and validating expressions. This allows us to inform the user of syntax errors prior to the solver's compile step. The user will see a friendlier Python error message, instead of a massive C++ compiler exception.Additionally, this will be used to create a variety of C++ expressions to be used for upcoming SBML features, many of which require different syntax for Python and C++ solvers. For example, the boolean expression
x > 0 and y**2 < 10
is valid in Python, but must be converted tox > 0 && pow(y, 2) < 10
for C.Supported Operators
Currently, only basic operators are supported: arithmetic operators, boolean operators (
and
andor
), and comparison operators. It doesn't seem like there's much point in implementing more than that at the moment, as this will likely be limited to propensity functions and basic SBML features.However, if for any reason additional operations are to be supported, they can be added simply by implementing the parser logic using that operator's corresponding
visit_*
method (such asvisit_Add
for the+
operator), and adding that operator to theoperator_map
along with its corresponding AST class.Note that the use of unsupported operators is currently undefined behavior, likely resulting in a failure to compile or bizarre output.