Feat(API): integrate Token to Expression simplify
This commit is contained in:
parent
5938cc7875
commit
5bf23a4793
@ -11,6 +11,7 @@ Expression
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
from ..core import AssocialTree, Tree, compute, typing, TypingError
|
from ..core import AssocialTree, Tree, compute, typing, TypingError
|
||||||
|
from .tokens import factory
|
||||||
from .renders import renders
|
from .renders import renders
|
||||||
|
|
||||||
class Expression(object):
|
class Expression(object):
|
||||||
@ -79,6 +80,7 @@ class Expression(object):
|
|||||||
'tex'
|
'tex'
|
||||||
>>> print(e)
|
>>> print(e)
|
||||||
2 + 3 \\times 4
|
2 + 3 \\times 4
|
||||||
|
>>> Expression.set_render('txt')
|
||||||
"""
|
"""
|
||||||
cls.RENDER = render
|
cls.RENDER = render
|
||||||
|
|
||||||
@ -218,7 +220,7 @@ class Expression(object):
|
|||||||
""" Set ancestor """
|
""" Set ancestor """
|
||||||
self._ancestor = ancestor
|
self._ancestor = ancestor
|
||||||
|
|
||||||
def simplify(self, optimize=True):
|
def _simplify(self, optimize=True):
|
||||||
""" Compute as much as possible the expression
|
""" Compute as much as possible the expression
|
||||||
|
|
||||||
:param optimize: bool to optimize tree when it's possible
|
:param optimize: bool to optimize tree when it's possible
|
||||||
@ -227,8 +229,8 @@ class Expression(object):
|
|||||||
:example:
|
:example:
|
||||||
>>> e = Expression.from_str("2+3*4")
|
>>> e = Expression.from_str("2+3*4")
|
||||||
>>> e
|
>>> e
|
||||||
<Exp: 2 + 3 \\times 4>
|
<Exp: 2 + 3 * 4>
|
||||||
>>> f = e.simplify()
|
>>> f = e._simplify()
|
||||||
>>> f
|
>>> f
|
||||||
<Exp: 14>
|
<Exp: 14>
|
||||||
>>> f._ancestor
|
>>> f._ancestor
|
||||||
@ -249,7 +251,26 @@ class Expression(object):
|
|||||||
return typed_exp
|
return typed_exp
|
||||||
else:
|
else:
|
||||||
comp_exp.set_ancestor(self)
|
comp_exp.set_ancestor(self)
|
||||||
return comp_exp.simplify(optimize=optimize)
|
return comp_exp._simplify(optimize=optimize)
|
||||||
|
|
||||||
|
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:
|
||||||
|
>>> e = Expression.from_str("2+3*4")
|
||||||
|
>>> e
|
||||||
|
<Exp: 2 + 3 * 4>
|
||||||
|
>>> f = e.simplify()
|
||||||
|
>>> f
|
||||||
|
<Integer 14>
|
||||||
|
>>> f._ancestor
|
||||||
|
<Exp: 2 + 12>
|
||||||
|
"""
|
||||||
|
self._child = self._simplify(optimize=optimize)
|
||||||
|
return factory(self._child, ancestor=self._child._ancestor)
|
||||||
|
|
||||||
def explain(self):
|
def explain(self):
|
||||||
""" Yield every calculus step which have lead to self
|
""" Yield every calculus step which have lead to self
|
||||||
|
53
mapytex/calculus/API/tokens/__init__.py
Normal file
53
mapytex/calculus/API/tokens/__init__.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#! /usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim:fenc=utf-8
|
||||||
|
#
|
||||||
|
# Copyright © 2017 lafrite <lafrite@Poivre>
|
||||||
|
#
|
||||||
|
# Distributed under terms of the MIT license.
|
||||||
|
|
||||||
|
"""
|
||||||
|
Tokens represents MathObject at API level
|
||||||
|
|
||||||
|
"""
|
||||||
|
from ...core.MO.mo import MO, MOnumber, MOstr
|
||||||
|
from ...core.MO.fraction import MOFraction
|
||||||
|
from ...core.MO.monomial import MOstrPower, MOMonomial
|
||||||
|
from ...core.MO.polynomial import MOpolynomial
|
||||||
|
from decimal import Decimal as _Decimal
|
||||||
|
|
||||||
|
from .number import Integer, Decimal, Fraction
|
||||||
|
from .polynomial import Polynomial, Linear, Quadratic
|
||||||
|
|
||||||
|
__all__ = ["factory"]
|
||||||
|
|
||||||
|
def factory(exp, name="", ancestor=None):
|
||||||
|
""" Transform a Expression with on MathObject (from core) to a appropriate token (from API)
|
||||||
|
"""
|
||||||
|
mo = exp._tree
|
||||||
|
if not isinstance(mo, MO):
|
||||||
|
raise TypeError(f"Can't build Token from not computed Expression (got {mo})")
|
||||||
|
if isinstance(mo, MOnumber):
|
||||||
|
if isinstance(mo.value, int):
|
||||||
|
return Integer(mo, name, ancestor)
|
||||||
|
elif isinstance(mo.value, _Decimal):
|
||||||
|
return Decimal(mo, name, ancestor)
|
||||||
|
else:
|
||||||
|
raise TypeError(f"Can't build from MOnumber ({mo}) neither int nor decimal")
|
||||||
|
|
||||||
|
elif isinstance(mo, MOFraction):
|
||||||
|
if isinstance(mo._denominator, MOnumber) and \
|
||||||
|
isinstance(mo._numerator, MOnumber):
|
||||||
|
return Fraction(mo, name, ancestor)
|
||||||
|
else:
|
||||||
|
raise TypeError(f"Can't build from MOFraction ({mo}) numerator and denominator are not MOnumber")
|
||||||
|
|
||||||
|
elif isinstance(mo, (MOstr, MOstrPower, MOMonomial, MOpolynomial)):
|
||||||
|
raise TypeError(f"Can't build Polynom yet")
|
||||||
|
else:
|
||||||
|
raise TypeError(f"{type(mo)} is unknown MathObject")
|
||||||
|
|
||||||
|
# -----------------------------
|
||||||
|
# Reglages pour 'vim'
|
||||||
|
# vim:set autoindent expandtab tabstop=4 shiftwidth=4:
|
||||||
|
# cursor: 16 del
|
@ -11,7 +11,8 @@ Tokens representing interger and decimal
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
from .token import Token
|
from .token import Token
|
||||||
from ...core.MO import MOnumber, MOFraction
|
from ...core.MO.mo import MOnumber
|
||||||
|
from ...core.MO.fraction import MOFraction
|
||||||
from decimal import Decimal as _Decimal
|
from decimal import Decimal as _Decimal
|
||||||
|
|
||||||
__all__ = ["Integer", "Decimal"]
|
__all__ = ["Integer", "Decimal"]
|
||||||
@ -20,13 +21,13 @@ class Integer(Token):
|
|||||||
|
|
||||||
""" Token representing a integer """
|
""" Token representing a integer """
|
||||||
|
|
||||||
def __init__(self, mo, name=""):
|
def __init__(self, mo, name="", ancestor=None):
|
||||||
if not isinstance(mo, MOnumber):
|
if not isinstance(mo, MOnumber):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
if not isinstance(mo.value, int):
|
if not isinstance(mo.value, int):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
Token.__init__(self, mo, name)
|
Token.__init__(self, mo, name, ancestor)
|
||||||
self._mathtype = 'entier'
|
self._mathtype = 'entier'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -37,13 +38,13 @@ class Decimal(Token):
|
|||||||
|
|
||||||
""" Token representing a decimal """
|
""" Token representing a decimal """
|
||||||
|
|
||||||
def __init__(self, mo, name=""):
|
def __init__(self, mo, name="", ancestor=None):
|
||||||
if not isinstance(mo, MOnumber):
|
if not isinstance(mo, MOnumber):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
if not isinstance(mo.value, _Decimal):
|
if not isinstance(mo.value, _Decimal):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
Token.__init__(self, mo, name)
|
Token.__init__(self, mo, name, ancestor)
|
||||||
self._mathtype = 'décimal'
|
self._mathtype = 'décimal'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -54,7 +55,7 @@ class Fraction(Token):
|
|||||||
|
|
||||||
""" Token representing a fraction """
|
""" Token representing a fraction """
|
||||||
|
|
||||||
def __init__(self, mo, name=""):
|
def __init__(self, mo, name="", ancestor=None):
|
||||||
if not isinstance(mo, MOFraction):
|
if not isinstance(mo, MOFraction):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
if not isinstance(mo._numerator, MOnumber):
|
if not isinstance(mo._numerator, MOnumber):
|
||||||
@ -62,7 +63,7 @@ class Fraction(Token):
|
|||||||
if not isinstance(mo._denominator, MOnumber):
|
if not isinstance(mo._denominator, MOnumber):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
Token.__init__(self, mo, name)
|
Token.__init__(self, mo, name, ancestor)
|
||||||
self._mathtype = 'fraction'
|
self._mathtype = 'fraction'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
# Distributed under terms of the MIT license.
|
# Distributed under terms of the MIT license.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Tokens representing interger and decimal
|
Tokens representing polynomials functions
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from .token import Token
|
from .token import Token
|
||||||
@ -18,13 +18,13 @@ class Polynomial(Token):
|
|||||||
|
|
||||||
""" Token representing a polynomial """
|
""" Token representing a polynomial """
|
||||||
|
|
||||||
def __init__(self, mo, name=""):
|
def __init__(self, mo, name="", ancestor=None):
|
||||||
if not isinstance(mo, MOpolynomial):
|
if not isinstance(mo, MOpolynomial):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
if not isinstance(mo.value, int):
|
if not isinstance(mo.value, int):
|
||||||
raise TypeError
|
raise TypeError
|
||||||
|
|
||||||
Token.__init__(self, mo, name)
|
Token.__init__(self, mo, name, ancestor)
|
||||||
self._mathtype = 'polynome'
|
self._mathtype = 'polynome'
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -43,6 +43,40 @@ class Polynomial(Token):
|
|||||||
""" Call a Polynomial to evaluate itself on value """
|
""" Call a Polynomial to evaluate itself on value """
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class Linear(Token):
|
||||||
|
|
||||||
|
""" Token representing a linear """
|
||||||
|
|
||||||
|
def __init__(self, mo, name="", ancestor=None):
|
||||||
|
if not isinstance(mo, MOpolynomial):
|
||||||
|
raise TypeError
|
||||||
|
if not isinstance(mo.value, int):
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
|
Token.__init__(self, mo, name, ancestor)
|
||||||
|
self._mathtype = 'affine'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def random(cls):
|
||||||
|
raise NotImplemented
|
||||||
|
|
||||||
|
class Quadratic(Token):
|
||||||
|
|
||||||
|
""" Token representing a quadratic """
|
||||||
|
|
||||||
|
def __init__(self, mo, name="", ancestor=None):
|
||||||
|
if not isinstance(mo, MOpolynomial):
|
||||||
|
raise TypeError
|
||||||
|
if not isinstance(mo.value, int):
|
||||||
|
raise TypeError
|
||||||
|
|
||||||
|
Token.__init__(self, mo, name, ancestor)
|
||||||
|
self._mathtype = 'polynome du 2nd degré'
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def random(cls):
|
||||||
|
raise NotImplemented
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
# Reglages pour 'vim'
|
# Reglages pour 'vim'
|
||||||
|
@ -10,20 +10,61 @@
|
|||||||
Tokens: practical envelop of math object
|
Tokens: practical envelop of math object
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
from ..renders import renders
|
||||||
|
|
||||||
class Token(object):
|
class Token(object):
|
||||||
|
|
||||||
""" Token: practical envelop of an math object """
|
""" Token: practical envelop of an math object """
|
||||||
|
|
||||||
def __init__(self, mo, name=""):
|
RENDER = 'txt'
|
||||||
|
|
||||||
|
def __init__(self, mo, name="", ancestor = None):
|
||||||
self._mo = mo
|
self._mo = mo
|
||||||
self.name = name
|
self.name = name
|
||||||
self._mathtype = None
|
self._mathtype = None
|
||||||
|
self._ancestor = ancestor
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def random(cls):
|
def random(cls):
|
||||||
raise NotImplemented
|
raise NotImplemented
|
||||||
|
|
||||||
|
def explain(self):
|
||||||
|
""" Yield every calculus step which have lead to self
|
||||||
|
|
||||||
|
:example:
|
||||||
|
>>> from mapytex.calculus.API import Expression
|
||||||
|
>>> e = Expression.from_str("2+3*4")
|
||||||
|
>>> f = e.simplify()
|
||||||
|
>>> f
|
||||||
|
<Integer 14>
|
||||||
|
>>> for s in f.explain():
|
||||||
|
... print(s)
|
||||||
|
2 + 3 * 4
|
||||||
|
2 + 12
|
||||||
|
14
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
yield from self._ancestor.explain()
|
||||||
|
yield self
|
||||||
|
except AttributeError:
|
||||||
|
yield self
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return f"<{self.__class__.__name__} {self.__txt__}>"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return renders[self.RENDER](self._mo)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __txt__(self):
|
||||||
|
return self._mo.__txt__
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __tex__(self):
|
||||||
|
return self._mo.__tex__
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------
|
# -----------------------------
|
||||||
|
Loading…
Reference in New Issue
Block a user