From e9a865a14a22eb36232cd810c7adbe5dbb5ad25c Mon Sep 17 00:00:00 2001 From: Bertrand Benjamin Date: Mon, 1 Oct 2018 16:14:04 +0200 Subject: [PATCH] Feat(API): use balance before computing to optimize calculus --- mapytex/calculus/API/expression.py | 143 ++++++++++++++++++++++++++++- mapytex/calculus/core/__init__.py | 2 +- 2 files changed, 141 insertions(+), 4 deletions(-) diff --git a/mapytex/calculus/API/expression.py b/mapytex/calculus/API/expression.py index b44953c..3a921a7 100644 --- a/mapytex/calculus/API/expression.py +++ b/mapytex/calculus/API/expression.py @@ -10,7 +10,7 @@ Expression """ -from ..core import Tree, compute, typing +from ..core import AssocialTree, Tree, compute, typing from .renders import renders class Expression(object): @@ -88,9 +88,99 @@ class Expression(object): def __repr__(self): return f"" - def simplify(self): + def balance(self): + """ Balance selt._tree in order to optimize end tree number + + # TODO: their will be issue with / which is not commutative |lun. oct. 1 15:03:21 CEST 2018 + + :return: optmized version of self + + :example: + >>> t = Expression.from_str("1+2+3+4+5+6+7+8+9") + >>> print(t._tree) + + + > + + | > + + | | > + + | | | > + + | | | | > + + | | | | | > + + | | | | | | > + + | | | | | | | > 1 + | | | | | | | > 2 + | | | | | | > 3 + | | | | | > 4 + | | | | > 5 + | | | > 6 + | | > 7 + | > 8 + > 9 + >>> t.balance() + >>> print(t._tree) + + + > + + | > + + | | > 1 + | | > 2 + | > + + | | > 3 + | | > 4 + > + + | > + + | | > 5 + | | > 6 + | > + + | | > 7 + | | > + + | | | > 8 + | | | > 9 + >>> t = Expression.from_str("1+2+3+4+5*6*7*8*9") + >>> print(t._tree) + + + > + + | > + + | | > + + | | | > 1 + | | | > 2 + | | > 3 + | > 4 + > * + | > * + | | > * + | | | > * + | | | | > 5 + | | | | > 6 + | | | > 7 + | | > 8 + | > 9 + >>> t.balance() + >>> print(t._tree) + + + > + + | > 1 + | > 2 + > + + | > 3 + | > + + | | > 4 + | | > * + | | | > * + | | | | > 5 + | | | | > 6 + | | | > * + | | | | > 7 + | | | | > * + | | | | | > 8 + | | | | | > 9 + + """ + self._tree = AssocialTree.from_any_tree(self._tree).balance() + + + def simplify(self, optimize=True): """ Compute as much as possible the expression + :param optimize: bool to optimize tree when it's possible :return: an expression :example: @@ -103,6 +193,11 @@ class Expression(object): >>> f._ancestor """ + if optimize: + try: + self.balance() + except AttributeError: + pass try: t = self._tree.apply_on_last_level(compute, typing) except AttributeError: @@ -111,7 +206,7 @@ class Expression(object): return self else: e = Expression(t, ancestor=self) - return e.simplify() + return e.simplify(optimize=optimize) def explain(self): """ Yield every calculus step which have lead to self @@ -124,6 +219,48 @@ class Expression(object): 2 + 3 * 4 2 + 12 14 + >>> e = Expression.from_str("1+2+3+4+5+6+7+8+9") + >>> f = e.simplify() + >>> for s in f.explain(): + ... print(s) + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 3 + 7 + 11 + 7 + 17 + 10 + 11 + 24 + 10 + 35 + 45 + >>> e = Expression.from_str("1+2+3+4+5+6+7+8+9") + >>> f_no_balance = e.simplify(optimize=False) + >>> for s in f_no_balance.explain(): + ... print(s) + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 3 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 6 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 5 + 6 + 7 + 8 + 9 + 15 + 6 + 7 + 8 + 9 + 21 + 7 + 8 + 9 + 28 + 8 + 9 + 36 + 9 + 45 + >>> e = Expression.from_str("1+2+3+4+5*6*7*8*9") + >>> f = e.simplify() + >>> for s in f.explain(): + ... print(s) + 1 + 2 + 3 + 4 + 5 * 6 * 7 * 8 * 9 + 3 + 3 + 4 + 30 * 7 * 72 + 6 + 4 + 30 * 504 + 6 + 4 + 15120 + 6 + 15124 + 15130 + >>> e = Expression.from_str("1+2+3+4+5*6*7*8*9") + >>> f_no_balance = e.simplify(optimize=False) + >>> for s in f_no_balance.explain(): + ... print(s) + 1 + 2 + 3 + 4 + 5 * 6 * 7 * 8 * 9 + 3 + 3 + 4 + 30 * 7 * 8 * 9 + 6 + 4 + 210 * 8 * 9 + 10 + 1680 * 9 + 10 + 15120 + 15130 """ try: yield from self._ancestor.explain() diff --git a/mapytex/calculus/core/__init__.py b/mapytex/calculus/core/__init__.py index 4028601..a83b987 100644 --- a/mapytex/calculus/core/__init__.py +++ b/mapytex/calculus/core/__init__.py @@ -54,7 +54,7 @@ Abstracts tools for calculs manipulations """ -from .tree import Tree +from .tree import Tree, AssocialTree from .compute import compute from .typing import typing from .renders import tree2txt, tree2tex