-
Notifications
You must be signed in to change notification settings - Fork 137
Description
When using sympy.sympify
without context, SymPy considers all names to be scalar symbols. This means that if you try to sympify, e.g., A[i, j, k]
, the following error will occur: TypeError: 'Symbol' object is not subscriptable
. However, SymPy has support for array expressions, as described here: https://docs.sympy.org/latest/modules/tensor/array_expressions.html
A minimal example is the following:
import sympy
from sympy.tensor.array.expressions import ArraySymbol
A = ArraySymbol("A", (3, 2, 4))
sym = sympy.sympify("A[i, j, k]", locals={'A': A})
In DaCe, a crucial utility method is dace.symbolic.pystr_to_symbolic
, which converts a Python-compatible string expression to a SymPy-compatible symbolic expression. To enable the parsing of strings that contain array subscripts without special context, we currently utilize the following hack. We replace brackets with parentheses, which makes SymPy think that the array names correspond to functions. Specifically, in dace/symbolic.py
and line 1327, we do the following:
try:
return sympy_to_dace(sympy.sympify(expr, locals, evaluate=simplify), symbol_map)
except (TypeError, sympy.SympifyError): # Symbol object is not subscriptable
# Replace subscript expressions with function calls
expr = expr.replace('[', '(')
expr = expr.replace(']', ')')
return sympy_to_dace(sympy.sympify(expr, locals, evaluate=simplify), symbol_map)
Although this works well for simple expressions, it may fail with indirect accesses or more complicated expressions, e.g., when the array subscript is nested inside a comparison.
To address those issues, we want to update pystr_to_symbolic
to use SymPy's ArraySymbols. We should amend the method to, when accepting a string as input, detect array subscripts, count the number of dimensions, create appropriate ArraySymbols, and pass the context to sympy.sympify
through the locals
dictionary parameter. To ensure that the updated method works properly, we should generate tests where the conditions in InterstateEdges or the branches of ConditionalBlocks are such complicated expressions, e.g., ztp1[tmp_index_224, tmp_index_225] - v_ydcst_var_1_rtt > 0.0
.