rat: Name expressions
We want to be able to give expressions a name. For instance when building the derived-term automaton for the following expression:
exp = vcsn.B.expression
f = exp('(!(!a&!b))* a [ab]{2}')
g = exp('!(a*ba*)')
e = f & g
e
we get a nice automaton, cluttered with long formulas. It would be much nicer if we could use names to denote parts of the expression. To get an example of a better rendering, consider this:
a = e.derived_term()
gv2 = a.dot('dot').replace(str(f), 'F').replace(str(g), 'G').replace('(a+b)', 'Σ').replace('a+b', 'Σ').replace('ΣΣ', 'Σ²')
from vcsn.dot import _dot_to_svg, _dot_pretty
from IPython.display import SVG
SVG(_dot_to_svg(_dot_pretty(gv2, 'pretty')))
The result is really much cuter.
There is a branch, ad/rat/named-expressions, that attempts to implement this decently. It relies on a new node in the AST for expressions, name
, that gives a name to the expression below it.
exp = vcsn.B.expression
s = exp('(?<Σ>[ab])')
f = (exp('(!(!a&!b))* a') * s ** 2).name('F')
g = exp('!(a*ba*)').name('G')
e = f & g
e
the result is not so bad, but not as good either. The reasons why it's not cute include the simple case of
A = exp('a*').name('A')
A.expansion()
which, in an initial version, returned
\e + a.a*
instead of
\e + a.A
A trick in to-expansion.hh addresses this, but then in the case of
>>> A = exp('!a*').name('A')
>>> A.expansion()
a⊙[a*c]
Again, we lost the association of the name A
for a*{c}
, because we actually reconstructed the expression a*{c}
, it is not just "forwarded". But then we lost its name.
Another possible implementation, instead of this "local" implementation, is to provide a table somewhere of expression -> name
, and use that name when printing the expression. This is less local: the expression does not name its parts. In particular, this prevents having two equal components have different names and follow their evolution. But it definitely allows to cope with all the cases. And it becomes very easy to do if we have hashconsing of our expressions.