|
|
"""A module providing information about the necessity of brackets"""
# Default precedence values for some basic types PRECEDENCE = { "Lambda": 1, "Xor": 10, "Or": 20, "And": 30, "Relational": 35, "Add": 40, "Mul": 50, "Pow": 60, "Func": 70, "Not": 100, "Atom": 1000, "BitwiseOr": 36, "BitwiseXor": 37, "BitwiseAnd": 38 }
# A dictionary assigning precedence values to certain classes. These values are # treated like they were inherited, so not every single class has to be named # here. # Do not use this with printers other than StrPrinter PRECEDENCE_VALUES = { "Equivalent": PRECEDENCE["Xor"], "Xor": PRECEDENCE["Xor"], "Implies": PRECEDENCE["Xor"], "Or": PRECEDENCE["Or"], "And": PRECEDENCE["And"], "Add": PRECEDENCE["Add"], "Pow": PRECEDENCE["Pow"], "Relational": PRECEDENCE["Relational"], "Sub": PRECEDENCE["Add"], "Not": PRECEDENCE["Not"], "Function" : PRECEDENCE["Func"], "NegativeInfinity": PRECEDENCE["Add"], "MatAdd": PRECEDENCE["Add"], "MatPow": PRECEDENCE["Pow"], "MatrixSolve": PRECEDENCE["Mul"], "Mod": PRECEDENCE["Mul"], "TensAdd": PRECEDENCE["Add"], # As soon as `TensMul` is a subclass of `Mul`, remove this: "TensMul": PRECEDENCE["Mul"], "HadamardProduct": PRECEDENCE["Mul"], "HadamardPower": PRECEDENCE["Pow"], "KroneckerProduct": PRECEDENCE["Mul"], "Equality": PRECEDENCE["Mul"], "Unequality": PRECEDENCE["Mul"], }
# Sometimes it's not enough to assign a fixed precedence value to a # class. Then a function can be inserted in this dictionary that takes # an instance of this class as argument and returns the appropriate # precedence value.
# Precedence functions
def precedence_Mul(item): if item.could_extract_minus_sign(): return PRECEDENCE["Add"] return PRECEDENCE["Mul"]
def precedence_Rational(item): if item.p < 0: return PRECEDENCE["Add"] return PRECEDENCE["Mul"]
def precedence_Integer(item): if item.p < 0: return PRECEDENCE["Add"] return PRECEDENCE["Atom"]
def precedence_Float(item): if item < 0: return PRECEDENCE["Add"] return PRECEDENCE["Atom"]
def precedence_PolyElement(item): if item.is_generator: return PRECEDENCE["Atom"] elif item.is_ground: return precedence(item.coeff(1)) elif item.is_term: return PRECEDENCE["Mul"] else: return PRECEDENCE["Add"]
def precedence_FracElement(item): if item.denom == 1: return precedence_PolyElement(item.numer) else: return PRECEDENCE["Mul"]
def precedence_UnevaluatedExpr(item): return precedence(item.args[0]) - 0.5
PRECEDENCE_FUNCTIONS = { "Integer": precedence_Integer, "Mul": precedence_Mul, "Rational": precedence_Rational, "Float": precedence_Float, "PolyElement": precedence_PolyElement, "FracElement": precedence_FracElement, "UnevaluatedExpr": precedence_UnevaluatedExpr, }
def precedence(item): """Returns the precedence of a given object.
This is the precedence for StrPrinter. """
if hasattr(item, "precedence"): return item.precedence try: mro = item.__class__.__mro__ except AttributeError: return PRECEDENCE["Atom"] for i in mro: n = i.__name__ if n in PRECEDENCE_FUNCTIONS: return PRECEDENCE_FUNCTIONS[n](item) elif n in PRECEDENCE_VALUES: return PRECEDENCE_VALUES[n] return PRECEDENCE["Atom"]
PRECEDENCE_TRADITIONAL = PRECEDENCE.copy() PRECEDENCE_TRADITIONAL['Integral'] = PRECEDENCE["Mul"] PRECEDENCE_TRADITIONAL['Sum'] = PRECEDENCE["Mul"] PRECEDENCE_TRADITIONAL['Product'] = PRECEDENCE["Mul"] PRECEDENCE_TRADITIONAL['Limit'] = PRECEDENCE["Mul"] PRECEDENCE_TRADITIONAL['Derivative'] = PRECEDENCE["Mul"] PRECEDENCE_TRADITIONAL['TensorProduct'] = PRECEDENCE["Mul"] PRECEDENCE_TRADITIONAL['Transpose'] = PRECEDENCE["Pow"] PRECEDENCE_TRADITIONAL['Adjoint'] = PRECEDENCE["Pow"] PRECEDENCE_TRADITIONAL['Dot'] = PRECEDENCE["Mul"] - 1 PRECEDENCE_TRADITIONAL['Cross'] = PRECEDENCE["Mul"] - 1 PRECEDENCE_TRADITIONAL['Gradient'] = PRECEDENCE["Mul"] - 1 PRECEDENCE_TRADITIONAL['Divergence'] = PRECEDENCE["Mul"] - 1 PRECEDENCE_TRADITIONAL['Curl'] = PRECEDENCE["Mul"] - 1 PRECEDENCE_TRADITIONAL['Laplacian'] = PRECEDENCE["Mul"] - 1 PRECEDENCE_TRADITIONAL['Union'] = PRECEDENCE['Xor'] PRECEDENCE_TRADITIONAL['Intersection'] = PRECEDENCE['Xor'] PRECEDENCE_TRADITIONAL['Complement'] = PRECEDENCE['Xor'] PRECEDENCE_TRADITIONAL['SymmetricDifference'] = PRECEDENCE['Xor'] PRECEDENCE_TRADITIONAL['ProductSet'] = PRECEDENCE['Xor']
def precedence_traditional(item): """Returns the precedence of a given object according to the
traditional rules of mathematics.
This is the precedence for the LaTeX and pretty printer. """
# Integral, Sum, Product, Limit have the precedence of Mul in LaTeX, # the precedence of Atom for other printers: from sympy.core.expr import UnevaluatedExpr
if isinstance(item, UnevaluatedExpr): return precedence_traditional(item.args[0])
n = item.__class__.__name__ if n in PRECEDENCE_TRADITIONAL: return PRECEDENCE_TRADITIONAL[n]
return precedence(item)
|