Refactor expression string descriptions.
I have started uncommited work on this on the robust
branch to give more meaningful __repr__
descriptions to different kinds of Perturbation
instances but I realized this is a larger change if done properly and it is not really necessary to have in the robust release, so I'll do it later.
I want to get rid of all Expression.__init__(self, typeStr, symStr)
calls when intializing expressions and implement the type string and the symbolic string in an abstract _get_type_string
and _get_symbolic_string
method, respectively. This should make the __init__
method of many expressions significantly shorter and more readable. The string computation would also be skipped if the string is never used or overwritten (see next paragraph).
Often PICOS internally assigns a new string to a freshly created (!) expression, like so:
result = self.__mul__(other)
# NOTE: __mul__ always creates a fresh expression.
result._symbStr = glyphs.clever_mul(other.string, self.string)
In the future this would be done by assigning to e.g. Expression._assigned_string
. Expression.string
would then return this assigned string instead of the one computed by _get_symbolic_string
. The latter would not be overwritten any more but would remain accessible via the cached Expression.creation_string
property, which can help with debugging.
Note that freshness of expressions is important due to our assumption that expressions are immutable (except for the value
of variables and parameters), more precisely because we make use this assumption when caching results. For instance changing the string of a.T.T
would also change that of a
as they are the same object. This is why I do not plan to allow the user to assign a new string at all. (We can't stop them from writing to _assigned_string
but as with any private property this is done at their own risk.) However, BiaffineExpression
already has a renamed
method that returns a shallow copy of the expression with a new string and it would be possible to offer this method for every expression type. I'm undecided on this point because it would require a shallow copy method with every expression type.