/
repr.py
171 lines (131 loc) · 5.93 KB
/
repr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
"""
A Printer for generating executable code.
The most important function here is srepr (that is an exact equivalent of
builtin repr, except for optional arguments) that returns a string so that the
relation eval(srepr(expr))=expr holds in an appropriate environment.
"""
from mpmath.libmp import prec_to_dps, repr_dps, to_str
from ..core.function import AppliedUndef
from ..utilities import default_sort_key
from .defaults import DefaultPrinting
from .printer import Printer
class ReprPrinter(Printer):
"""Repr printer."""
printmethod = '_diofantrepr'
_default_settings = {
'order': None
}
def reprify(self, args, sep):
"""Prints each item in `args` and joins them with `sep`."""
return sep.join([self.doprint(item) for item in args])
def emptyPrinter(self, expr):
"""The fallback printer."""
if hasattr(expr, 'args') and hasattr(expr.args, '__iter__'):
l = []
for o in expr.args:
l.append(self._print(o))
return expr.__class__.__name__ + f"({', '.join(l)})"
if hasattr(expr, '__repr__') and not issubclass(expr.__class__,
DefaultPrinting):
return repr(expr)
return object.__repr__(expr)
def _print_Dict(self, expr):
l = []
for o in sorted(expr.args, key=default_sort_key):
l.append(self._print(o))
return expr.__class__.__name__ + f"({', '.join(l)})"
def _print_Add(self, expr, order=None):
args = expr.as_ordered_terms(order=order or self.order)
args = map(self._print, args)
return f"Add({', '.join(args)})"
def _print_Function(self, expr):
r = self._print(expr.func)
r += f"({', '.join([self._print(a) for a in expr.args])})"
return r
def _print_FunctionClass(self, expr):
if issubclass(expr, AppliedUndef):
return f'Function({expr.__name__!r})'
return expr.__name__
def _print_RationalConstant(self, expr):
return f'Rational({expr.numerator}, {expr.denominator})'
def _print_AtomicExpr(self, expr):
return str(expr)
def _print_NumberSymbol(self, expr):
return str(expr)
def _print_Integer(self, expr):
return f'Integer({expr.numerator})'
def _print_list(self, expr):
return f"[{self.reprify(expr, ', ')}]"
def _print_MatrixBase(self, expr):
# special case for some empty matrices
if (expr.rows == 0) ^ (expr.cols == 0):
return f'{expr.__class__.__name__}({self._print(expr.rows)}, {self._print(expr.cols)}, {self._print([])})'
l = []
for i in range(expr.rows):
l.append([])
for j in range(expr.cols):
l[-1].append(expr[i, j])
return f'{expr.__class__.__name__}({self._print(l)})'
def _print_BooleanTrue(self, expr):
return 'true'
def _print_BooleanFalse(self, expr):
return 'false'
def _print_NaN(self, expr):
return 'nan'
def _print_Mul(self, expr, order=None):
terms = expr.args
args = expr._new_rawargs(*terms).as_ordered_factors()
args = map(self._print, args)
return f"Mul({', '.join(args)})"
def _print_Rational(self, expr):
return f'Rational({self._print(int(expr.numerator))}, {self._print(int(expr.denominator))})'
def _print_Float(self, expr):
dps = prec_to_dps(expr._prec)
r = to_str(expr._mpf_, repr_dps(expr._prec))
return f"{expr.__class__.__name__}('{r}', dps={dps:d})"
def _print_BaseSymbol(self, expr):
d = expr._assumptions.generator
if d == {}:
return f'{expr.__class__.__name__}({self._print(expr.name)})'
attr = [f'{k}={v}' for k, v in d.items()]
return f"{expr.__class__.__name__}({self._print(expr.name)}, {', '.join(attr)})"
def _print_str(self, expr):
return repr(expr)
def _print_tuple(self, expr):
if len(expr) == 1:
return f'({self._print(expr[0])},)'
return f"({self.reprify(expr, ', ')})"
def _print_WildFunction(self, expr):
return f"{expr.__class__.__name__}('{expr.name}')"
def _print_PolynomialRing(self, ring):
return f'{ring.__class__.__name__}({self._print(ring.domain)}, {self._print(ring.symbols)}, {self._print(ring.order)})'
def _print_GMPYIntegerRing(self, expr):
return f'{expr.__class__.__name__}()'
_print_GMPYRationalField = _print_GMPYIntegerRing
_print_PythonIntegerRing = _print_GMPYIntegerRing
_print_PythonRationalField = _print_GMPYIntegerRing
_print_LexOrder = _print_GMPYIntegerRing
_print_GradedLexOrder = _print_LexOrder
def _print_FractionField(self, field):
return f'{field.__class__.__name__}({self._print(field.domain)}, {self._print(field.symbols)}, {self._print(field.order)})'
def _print_PolyElement(self, poly):
terms = list(poly.items())
terms.sort(key=poly.ring.order, reverse=True)
return f'{poly.__class__.__name__}({self._print(poly.ring)}, {self._print(terms)})'
def _print_FracElement(self, frac):
numer_terms = list(frac.numerator.items())
numer_terms.sort(key=frac.field.order, reverse=True)
denom_terms = list(frac.denominator.items())
denom_terms.sort(key=frac.field.order, reverse=True)
numer = self._print(numer_terms)
denom = self._print(denom_terms)
return f'{frac.__class__.__name__}({self._print(frac.field)}, {numer}, {denom})'
def _print_AlgebraicField(self, expr):
return f'AlgebraicField({self._print(expr.domain)}, {self._print(expr.ext.as_expr())})'
def _print_AlgebraicElement(self, expr):
return f'{self._print(expr.parent)}({self._print(list(map(expr.domain.domain.to_expr, expr.rep.all_coeffs())))})'
def _print_Domain(self, expr):
return expr.rep
def srepr(expr, **settings):
"""Return expr in repr form."""
return ReprPrinter(settings).doprint(expr)