123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- """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)
|