Refact(API): Split simplify into _optimize, _typing, _compute

This commit is contained in:
Bertrand Benjamin 2018-11-21 08:54:37 +01:00
parent b4f9ced8a9
commit f53aa26542
1 changed files with 75 additions and 23 deletions

View File

@ -88,6 +88,73 @@ class Expression(object):
def __repr__(self):
return f"<Exp: {renders[self.RENDER](self._tree)}>"
def _optimize(self, exclude_nodes=["\\", "**"]):
""" Return a copy of self with an optimize tree
"""
try:
# TODO: need to test exclude_nodes |ven. oct. 5 08:51:02 CEST 2018
return Expression(self._tree.balance(exclude_nodes=exclude_nodes))
except AttributeError:
return self
def _typing(self):
""" Build a copy of self with as much typing as possible
:example:
>>> e = Expression.from_str("2x")
>>> print(e._tree.map_on_leaf(type))
*
> <class 'mapytex.calculus.core.MO.mo.MOnumber'>
> <class 'mapytex.calculus.core.MO.mo.MOstr'>
>>> typed_e = e._typing()
>>> print(type(typed_e._tree))
<class 'mapytex.calculus.core.MO.monomial.MOMonomial'>
>>> typed_e = e._typing()
>>> print(type(typed_e._tree))
<class 'mapytex.calculus.core.MO.monomial.MOMonomial'>
>>> e = Expression.from_str("2x+3+4/5")
>>> print(e._tree.map_on_leaf(type))
+
> +
| > *
| | > <class 'mapytex.calculus.core.MO.mo.MOnumber'>
| | > <class 'mapytex.calculus.core.MO.mo.MOstr'>
| > <class 'mapytex.calculus.core.MO.mo.MOnumber'>
> /
| > <class 'mapytex.calculus.core.MO.mo.MOnumber'>
| > <class 'mapytex.calculus.core.MO.mo.MOnumber'>
>>> typed_e = e._typing()
>>> print(typed_e._tree.map_on_leaf(type))
+
> <class 'mapytex.calculus.core.MO.polynomial.MOpolynomial'>
> <class 'mapytex.calculus.core.MO.fraction.MOFraction'>
"""
try:
t = self._tree.apply_on_last_level(typing)
except TypingError:
return self
except NotImplementedError:
return self
except AttributeError:
return self
else:
return Expression(t)._typing()
def _compute(self):
"""" Compute one step of self
"""
try:
return Expression(self._tree.apply_on_last_level(compute))
except AttributeError:
return self
def set_ancestor(self, ancestor):
""" Set ancestor """
self._ancestor = ancestor
def simplify(self, optimize=True):
""" Compute as much as possible the expression
@ -104,34 +171,19 @@ class Expression(object):
>>> f._ancestor
<Exp: 2 + 12>
"""
t = self._tree
if optimize:
try:
# TODO: need to test exclude_nodes |ven. oct. 5 08:51:02 CEST 2018
t = t.balance(
exclude_nodes=["\\", "**"]
)
except AttributeError:
pass
opt_exp = self._optimize()
else:
opt_exp = self
more_typing = 1
while more_typing:
try:
t = t.apply_on_last_level(typing)
except TypingError:
more_typing = 0
except NotImplementedError:
more_typing = 0
except AttributeError:
more_typing = 0
typed_exp = opt_exp._typing()
comp_exp = typed_exp._compute()
try:
t = t.apply_on_last_level(compute)
except AttributeError:
if typed_exp == comp_exp:
return self
else:
e = Expression(t, ancestor=self)
return e.simplify(optimize=optimize)
comp_exp.set_ancestor(self)
return comp_exp.simplify(optimize=optimize)
def explain(self):
""" Yield every calculus step which have lead to self