mathai 0.2.7__py3-none-any.whl → 0.2.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mathai/__init__.py +16 -16
- mathai/apart.py +103 -103
- mathai/base.py +355 -354
- mathai/console.py +84 -84
- mathai/diff.py +65 -65
- mathai/expand.py +58 -58
- mathai/factor.py +125 -125
- mathai/fraction.py +59 -59
- mathai/integrate.py +346 -346
- mathai/inverse.py +65 -65
- mathai/limit.py +130 -130
- mathai/linear.py +152 -152
- mathai/logic.py +224 -224
- mathai/parser.py +154 -154
- mathai/printeq.py +34 -34
- mathai/simplify.py +358 -358
- mathai/structure.py +103 -103
- mathai/tool.py +35 -35
- mathai/trig.py +169 -169
- mathai/univariate_inequality.py +410 -414
- {mathai-0.2.7.dist-info → mathai-0.2.9.dist-info}/METADATA +231 -231
- mathai-0.2.9.dist-info/RECORD +24 -0
- {mathai-0.2.7.dist-info → mathai-0.2.9.dist-info}/WHEEL +1 -1
- mathai-0.2.7.dist-info/RECORD +0 -24
- {mathai-0.2.7.dist-info → mathai-0.2.9.dist-info}/top_level.txt +0 -0
mathai/base.py
CHANGED
@@ -1,354 +1,355 @@
|
|
1
|
-
import copy
|
2
|
-
from fractions import Fraction
|
3
|
-
|
4
|
-
class TreeNode:
|
5
|
-
def __init__(self, name, children=[]):
|
6
|
-
children = copy.deepcopy(children)
|
7
|
-
self.name = name
|
8
|
-
if name in ["f_add", "f_mul"]:
|
9
|
-
self.children = sorted(children, key=lambda x: str_form(x))
|
10
|
-
else:
|
11
|
-
self.children = children
|
12
|
-
|
13
|
-
def fx(self, fxname):
|
14
|
-
return TreeNode("f_" + fxname, [self])
|
15
|
-
|
16
|
-
def __repr__(self):
|
17
|
-
return string_equation(str_form(self))
|
18
|
-
|
19
|
-
def __eq__(self, other):
|
20
|
-
if isinstance(other, int):
|
21
|
-
other = tree_form("d_" + str(other))
|
22
|
-
elif not isinstance(other, TreeNode):
|
23
|
-
return NotImplemented
|
24
|
-
return str_form(self) == str_form(other)
|
25
|
-
|
26
|
-
def __add__(self, other):
|
27
|
-
if isinstance(other, int):
|
28
|
-
other = tree_form("d_" + str(other))
|
29
|
-
return TreeNode("f_add", [self, other])
|
30
|
-
|
31
|
-
def __radd__(self, other):
|
32
|
-
return self.__add__(other)
|
33
|
-
|
34
|
-
def __mul__(self, other):
|
35
|
-
if isinstance(other, int):
|
36
|
-
other = tree_form("d_" + str(other))
|
37
|
-
return TreeNode("f_mul", [self, other])
|
38
|
-
|
39
|
-
def __rmul__(self, other):
|
40
|
-
return self.__mul__(other)
|
41
|
-
|
42
|
-
def __sub__(self, other):
|
43
|
-
if isinstance(other, int):
|
44
|
-
other = tree_form("d_" + str(other))
|
45
|
-
return self + (tree_form("d_-1") * other)
|
46
|
-
|
47
|
-
def __rsub__(self, other):
|
48
|
-
if isinstance(other, int):
|
49
|
-
other = tree_form("d_" + str(other))
|
50
|
-
return other + (tree_form("d_-1") * self)
|
51
|
-
|
52
|
-
def __pow__(self, other):
|
53
|
-
if isinstance(other, int):
|
54
|
-
other = tree_form("d_" + str(other))
|
55
|
-
return TreeNode("f_pow", [self, other])
|
56
|
-
|
57
|
-
def __rpow__(self, other):
|
58
|
-
if isinstance(other, int):
|
59
|
-
other = tree_form("d_" + str(other))
|
60
|
-
return TreeNode("f_pow", [other, self])
|
61
|
-
|
62
|
-
def __truediv__(self, other):
|
63
|
-
if isinstance(other, int):
|
64
|
-
other = tree_form("d_" + str(other))
|
65
|
-
return self * (other ** tree_form("d_-1"))
|
66
|
-
|
67
|
-
def __rtruediv__(self, other):
|
68
|
-
if isinstance(other, int):
|
69
|
-
other = tree_form("d_" + str(other))
|
70
|
-
return other * (self ** tree_form("d_-1"))
|
71
|
-
|
72
|
-
def __and__(self, other):
|
73
|
-
if isinstance(other, int):
|
74
|
-
other = tree_form("d_" + str(other))
|
75
|
-
return TreeNode("f_and", [self, other])
|
76
|
-
|
77
|
-
def __rand__(self, other):
|
78
|
-
return self.__and__(other)
|
79
|
-
|
80
|
-
def __or__(self, other):
|
81
|
-
if isinstance(other, int):
|
82
|
-
other = tree_form("d_" + str(other))
|
83
|
-
return TreeNode("f_or", [self, other])
|
84
|
-
|
85
|
-
def __ror__(self, other):
|
86
|
-
return self.__or__(other)
|
87
|
-
|
88
|
-
def __neg__(self):
|
89
|
-
return tree_form("d_-1") * self
|
90
|
-
|
91
|
-
def __hash__(self):
|
92
|
-
return hash(str_form(self))
|
93
|
-
|
94
|
-
def str_form(node):
|
95
|
-
def recursive_str(node, depth=0):
|
96
|
-
result = "{}{}".format(' ' * depth, node.name)
|
97
|
-
for child in node.children:
|
98
|
-
result += "\n" + recursive_str(child, depth + 1)
|
99
|
-
return result
|
100
|
-
if not isinstance(node, TreeNode):
|
101
|
-
return "d_"+str(node)
|
102
|
-
return recursive_str(node)
|
103
|
-
def replace(equation, find, r):
|
104
|
-
if str_form(equation) == str_form(find):
|
105
|
-
return r
|
106
|
-
col = TreeNode(equation.name, [])
|
107
|
-
for child in equation.children:
|
108
|
-
col.children.append(replace(child, find, r))
|
109
|
-
return col
|
110
|
-
|
111
|
-
def contain(equation, what):
|
112
|
-
if equation == what:
|
113
|
-
return True
|
114
|
-
if equation.children == []:
|
115
|
-
return False
|
116
|
-
return any(contain(child, what) for child in equation.children)
|
117
|
-
def remove_duplicates_custom(lst, rcustom):
|
118
|
-
result = []
|
119
|
-
for item in lst:
|
120
|
-
if not any(rcustom(item, x) for x in result):
|
121
|
-
result.append(item)
|
122
|
-
return result
|
123
|
-
def frac(eq):
|
124
|
-
if eq.name[:2] == "d_":
|
125
|
-
return Fraction(int(eq.name[2:]))
|
126
|
-
if eq.name == "f_add":
|
127
|
-
p = frac(eq.children[0])
|
128
|
-
for child in eq.children[1:]:
|
129
|
-
tmp = frac(child)
|
130
|
-
if isinstance(tmp, Fraction):
|
131
|
-
p+= tmp
|
132
|
-
else:
|
133
|
-
return None
|
134
|
-
return p
|
135
|
-
if eq.name == "f_mul":
|
136
|
-
p = frac(eq.children[0])
|
137
|
-
for child in eq.children[1:]:
|
138
|
-
tmp = frac(child)
|
139
|
-
if isinstance(tmp, Fraction):
|
140
|
-
p*= tmp
|
141
|
-
else:
|
142
|
-
return None
|
143
|
-
return p
|
144
|
-
if eq.name == "f_pow":
|
145
|
-
a = frac(eq.children[0])
|
146
|
-
b = frac(eq.children[1])
|
147
|
-
if isinstance(a, Fraction) and isinstance(b, Fraction) and b.denominator==1:
|
148
|
-
if a == 0 and b <= 0:
|
149
|
-
return None
|
150
|
-
return a**b
|
151
|
-
else:
|
152
|
-
return None
|
153
|
-
return None
|
154
|
-
def factor_generation(eq):
|
155
|
-
output = []
|
156
|
-
if eq.name != "f_mul":
|
157
|
-
eq = TreeNode("f_mul", [eq])
|
158
|
-
if eq.name == "f_mul":
|
159
|
-
for child in eq.children:
|
160
|
-
if child.name == "f_pow":
|
161
|
-
if child.children[0].name[:2] == "s_":
|
162
|
-
output.append(child)
|
163
|
-
continue
|
164
|
-
if child.children[1].name[:2] != "d_":
|
165
|
-
output.append(child)
|
166
|
-
continue
|
167
|
-
if child.children[1].
|
168
|
-
n = int(child.children[1].name[2:])
|
169
|
-
if n < 0:
|
170
|
-
for i in range(-n):
|
171
|
-
output.append(child.children[0]**-1)
|
172
|
-
else:
|
173
|
-
for i in range(n):
|
174
|
-
output.append(child.children[0])
|
175
|
-
else:
|
176
|
-
output.append(child)
|
177
|
-
else:
|
178
|
-
output.append(child)
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
parent_node
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
eq = eq.replace("
|
349
|
-
eq = eq.replace("
|
350
|
-
eq = eq.replace("
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
1
|
+
import copy
|
2
|
+
from fractions import Fraction
|
3
|
+
|
4
|
+
class TreeNode:
|
5
|
+
def __init__(self, name, children=[]):
|
6
|
+
children = copy.deepcopy(children)
|
7
|
+
self.name = name
|
8
|
+
if name in ["f_add", "f_mul"]:
|
9
|
+
self.children = sorted(children, key=lambda x: str_form(x))
|
10
|
+
else:
|
11
|
+
self.children = children
|
12
|
+
|
13
|
+
def fx(self, fxname):
|
14
|
+
return TreeNode("f_" + fxname, [self])
|
15
|
+
|
16
|
+
def __repr__(self):
|
17
|
+
return string_equation(str_form(self))
|
18
|
+
|
19
|
+
def __eq__(self, other):
|
20
|
+
if isinstance(other, int):
|
21
|
+
other = tree_form("d_" + str(other))
|
22
|
+
elif not isinstance(other, TreeNode):
|
23
|
+
return NotImplemented
|
24
|
+
return str_form(self) == str_form(other)
|
25
|
+
|
26
|
+
def __add__(self, other):
|
27
|
+
if isinstance(other, int):
|
28
|
+
other = tree_form("d_" + str(other))
|
29
|
+
return TreeNode("f_add", [self, other])
|
30
|
+
|
31
|
+
def __radd__(self, other):
|
32
|
+
return self.__add__(other)
|
33
|
+
|
34
|
+
def __mul__(self, other):
|
35
|
+
if isinstance(other, int):
|
36
|
+
other = tree_form("d_" + str(other))
|
37
|
+
return TreeNode("f_mul", [self, other])
|
38
|
+
|
39
|
+
def __rmul__(self, other):
|
40
|
+
return self.__mul__(other)
|
41
|
+
|
42
|
+
def __sub__(self, other):
|
43
|
+
if isinstance(other, int):
|
44
|
+
other = tree_form("d_" + str(other))
|
45
|
+
return self + (tree_form("d_-1") * other)
|
46
|
+
|
47
|
+
def __rsub__(self, other):
|
48
|
+
if isinstance(other, int):
|
49
|
+
other = tree_form("d_" + str(other))
|
50
|
+
return other + (tree_form("d_-1") * self)
|
51
|
+
|
52
|
+
def __pow__(self, other):
|
53
|
+
if isinstance(other, int):
|
54
|
+
other = tree_form("d_" + str(other))
|
55
|
+
return TreeNode("f_pow", [self, other])
|
56
|
+
|
57
|
+
def __rpow__(self, other):
|
58
|
+
if isinstance(other, int):
|
59
|
+
other = tree_form("d_" + str(other))
|
60
|
+
return TreeNode("f_pow", [other, self])
|
61
|
+
|
62
|
+
def __truediv__(self, other):
|
63
|
+
if isinstance(other, int):
|
64
|
+
other = tree_form("d_" + str(other))
|
65
|
+
return self * (other ** tree_form("d_-1"))
|
66
|
+
|
67
|
+
def __rtruediv__(self, other):
|
68
|
+
if isinstance(other, int):
|
69
|
+
other = tree_form("d_" + str(other))
|
70
|
+
return other * (self ** tree_form("d_-1"))
|
71
|
+
|
72
|
+
def __and__(self, other):
|
73
|
+
if isinstance(other, int):
|
74
|
+
other = tree_form("d_" + str(other))
|
75
|
+
return TreeNode("f_and", [self, other])
|
76
|
+
|
77
|
+
def __rand__(self, other):
|
78
|
+
return self.__and__(other)
|
79
|
+
|
80
|
+
def __or__(self, other):
|
81
|
+
if isinstance(other, int):
|
82
|
+
other = tree_form("d_" + str(other))
|
83
|
+
return TreeNode("f_or", [self, other])
|
84
|
+
|
85
|
+
def __ror__(self, other):
|
86
|
+
return self.__or__(other)
|
87
|
+
|
88
|
+
def __neg__(self):
|
89
|
+
return tree_form("d_-1") * self
|
90
|
+
|
91
|
+
def __hash__(self):
|
92
|
+
return hash(str_form(self))
|
93
|
+
|
94
|
+
def str_form(node):
|
95
|
+
def recursive_str(node, depth=0):
|
96
|
+
result = "{}{}".format(' ' * depth, node.name)
|
97
|
+
for child in node.children:
|
98
|
+
result += "\n" + recursive_str(child, depth + 1)
|
99
|
+
return result
|
100
|
+
if not isinstance(node, TreeNode):
|
101
|
+
return "d_"+str(node)
|
102
|
+
return recursive_str(node)
|
103
|
+
def replace(equation, find, r):
|
104
|
+
if str_form(equation) == str_form(find):
|
105
|
+
return r
|
106
|
+
col = TreeNode(equation.name, [])
|
107
|
+
for child in equation.children:
|
108
|
+
col.children.append(replace(child, find, r))
|
109
|
+
return col
|
110
|
+
|
111
|
+
def contain(equation, what):
|
112
|
+
if equation == what:
|
113
|
+
return True
|
114
|
+
if equation.children == []:
|
115
|
+
return False
|
116
|
+
return any(contain(child, what) for child in equation.children)
|
117
|
+
def remove_duplicates_custom(lst, rcustom):
|
118
|
+
result = []
|
119
|
+
for item in lst:
|
120
|
+
if not any(rcustom(item, x) for x in result):
|
121
|
+
result.append(item)
|
122
|
+
return result
|
123
|
+
def frac(eq):
|
124
|
+
if eq.name[:2] == "d_":
|
125
|
+
return Fraction(int(eq.name[2:]))
|
126
|
+
if eq.name == "f_add":
|
127
|
+
p = frac(eq.children[0])
|
128
|
+
for child in eq.children[1:]:
|
129
|
+
tmp = frac(child)
|
130
|
+
if isinstance(tmp, Fraction):
|
131
|
+
p+= tmp
|
132
|
+
else:
|
133
|
+
return None
|
134
|
+
return p
|
135
|
+
if eq.name == "f_mul":
|
136
|
+
p = frac(eq.children[0])
|
137
|
+
for child in eq.children[1:]:
|
138
|
+
tmp = frac(child)
|
139
|
+
if isinstance(tmp, Fraction):
|
140
|
+
p*= tmp
|
141
|
+
else:
|
142
|
+
return None
|
143
|
+
return p
|
144
|
+
if eq.name == "f_pow":
|
145
|
+
a = frac(eq.children[0])
|
146
|
+
b = frac(eq.children[1])
|
147
|
+
if isinstance(a, Fraction) and isinstance(b, Fraction) and b.denominator==1:
|
148
|
+
if a == 0 and b <= 0:
|
149
|
+
return None
|
150
|
+
return a**b
|
151
|
+
else:
|
152
|
+
return None
|
153
|
+
return None
|
154
|
+
def factor_generation(eq):
|
155
|
+
output = []
|
156
|
+
if eq.name != "f_mul":
|
157
|
+
eq = TreeNode("f_mul", [eq])
|
158
|
+
if eq.name == "f_mul":
|
159
|
+
for child in eq.children:
|
160
|
+
if child.name == "f_pow":
|
161
|
+
if child.children[0].name[:2] == "s_":
|
162
|
+
output.append(child)
|
163
|
+
continue
|
164
|
+
if child.children[1].name[:2] != "d_":
|
165
|
+
output.append(child)
|
166
|
+
continue
|
167
|
+
if frac(child.children[1]) is not None and frac(child.children[1]).denominator == 1:
|
168
|
+
n = int(child.children[1].name[2:])
|
169
|
+
if n < 0:
|
170
|
+
for i in range(-n):
|
171
|
+
output.append(child.children[0]**-1)
|
172
|
+
else:
|
173
|
+
for i in range(n):
|
174
|
+
output.append(child.children[0])
|
175
|
+
else:
|
176
|
+
output.append(child)
|
177
|
+
else:
|
178
|
+
output.append(child)
|
179
|
+
|
180
|
+
return output
|
181
|
+
import math
|
182
|
+
|
183
|
+
def compute(eq):
|
184
|
+
# Base case: leaf node
|
185
|
+
if eq.children == []:
|
186
|
+
if eq.name == "s_e":
|
187
|
+
return math.e
|
188
|
+
elif eq.name == "s_pi":
|
189
|
+
return math.pi
|
190
|
+
elif eq.name.startswith("d_"):
|
191
|
+
return float(eq.name[2:])
|
192
|
+
else:
|
193
|
+
return None
|
194
|
+
|
195
|
+
# Recursive case: compute child values
|
196
|
+
values = [compute(child) for child in eq.children]
|
197
|
+
if None in values:
|
198
|
+
return None
|
199
|
+
# Evaluate based on node type
|
200
|
+
if eq.name == "f_add":
|
201
|
+
return sum(values)
|
202
|
+
elif eq.name == "f_sub":
|
203
|
+
return values[0] - values[1]
|
204
|
+
elif eq.name == "f_rad":
|
205
|
+
return values[0] * math.pi / 180
|
206
|
+
elif eq.name == "f_mul":
|
207
|
+
result = 1.0
|
208
|
+
for v in values:
|
209
|
+
result *= v
|
210
|
+
return result
|
211
|
+
elif eq.name == "f_neg":
|
212
|
+
return -values[0]
|
213
|
+
elif eq.name == "f_div":
|
214
|
+
return values[0] / values[1]
|
215
|
+
elif eq.name == "f_pow":
|
216
|
+
return values[0] ** values[1]
|
217
|
+
elif eq.name == "f_sin":
|
218
|
+
return math.sin(values[0])
|
219
|
+
elif eq.name == "f_cos":
|
220
|
+
return math.cos(values[0])
|
221
|
+
elif eq.name == "f_tan":
|
222
|
+
return math.tan(values[0])
|
223
|
+
elif eq.name == "f_arcsin":
|
224
|
+
return math.asin(values[0])
|
225
|
+
elif eq.name == "f_arccos":
|
226
|
+
return math.acos(values[0])
|
227
|
+
elif eq.name == "f_arctan":
|
228
|
+
return math.atan(values[0])
|
229
|
+
elif eq.name == "f_log":
|
230
|
+
return math.log(values[0])
|
231
|
+
else:
|
232
|
+
return None
|
233
|
+
|
234
|
+
def num_dem(equation):
|
235
|
+
num = tree_form("d_1")
|
236
|
+
den = tree_form("d_1")
|
237
|
+
for item in factor_generation(equation):
|
238
|
+
|
239
|
+
t = item
|
240
|
+
if t.name == "f_pow" and "v_" not in str_form(t.children[1]) and compute(t.children[1]) < 0:
|
241
|
+
|
242
|
+
den = den*item
|
243
|
+
else:
|
244
|
+
num = num*item
|
245
|
+
return [num, tree_form("d_1")/den]
|
246
|
+
def summation(lst):
|
247
|
+
if lst == []:
|
248
|
+
return tree_form("d_0")
|
249
|
+
s = lst[0]
|
250
|
+
for item in lst[1:]:
|
251
|
+
s += item
|
252
|
+
return s
|
253
|
+
def vlist(eq):
|
254
|
+
out = []
|
255
|
+
if eq.name[:2] == "v_":
|
256
|
+
out.append(eq.name)
|
257
|
+
for child in eq.children:
|
258
|
+
out += vlist(child)
|
259
|
+
return sorted(list(set(out)), key=lambda x: int(x[2:]))
|
260
|
+
def product(lst):
|
261
|
+
if lst == []:
|
262
|
+
return tree_form("d_1")
|
263
|
+
s = lst[0]
|
264
|
+
for item in lst[1:]:
|
265
|
+
s *= item
|
266
|
+
return s
|
267
|
+
def flatten_tree(node):
|
268
|
+
if not node.children:
|
269
|
+
return node
|
270
|
+
if node.name in ("f_add", "f_mul", "f_and", "f_or"):
|
271
|
+
merged_children = []
|
272
|
+
for child in node.children:
|
273
|
+
flattened_child = flatten_tree(child)
|
274
|
+
if flattened_child.name == node.name:
|
275
|
+
merged_children.extend(flattened_child.children)
|
276
|
+
else:
|
277
|
+
merged_children.append(flattened_child)
|
278
|
+
return TreeNode(node.name, merged_children)
|
279
|
+
else:
|
280
|
+
node.children = [flatten_tree(child) for child in node.children]
|
281
|
+
return node
|
282
|
+
def dowhile(eq, fx):
|
283
|
+
while True:
|
284
|
+
orig = copy.deepcopy(eq)
|
285
|
+
eq = copy.deepcopy(fx(eq))
|
286
|
+
if eq is None:
|
287
|
+
return None
|
288
|
+
if eq == orig:
|
289
|
+
return orig
|
290
|
+
def tree_form(tabbed_strings):
|
291
|
+
lines = tabbed_strings.split("\n")
|
292
|
+
root = TreeNode("Root")
|
293
|
+
current_level_nodes = {0: root}
|
294
|
+
stack = [root]
|
295
|
+
for line in lines:
|
296
|
+
level = line.count(' ')
|
297
|
+
node_name = line.strip()
|
298
|
+
node = TreeNode(node_name)
|
299
|
+
while len(stack) > level + 1:
|
300
|
+
stack.pop()
|
301
|
+
parent_node = stack[-1]
|
302
|
+
parent_node.children.append(node)
|
303
|
+
current_level_nodes[level] = node
|
304
|
+
stack.append(node)
|
305
|
+
return root.children[0]
|
306
|
+
def string_equation_helper(equation_tree):
|
307
|
+
if equation_tree.children == []:
|
308
|
+
if equation_tree.name[:2]=="g_":
|
309
|
+
return '"'+equation_tree.name[2:]+'"'
|
310
|
+
return equation_tree.name
|
311
|
+
extra = ""
|
312
|
+
if equation_tree.name == "f_neg":
|
313
|
+
return "-"+string_equation_helper(equation_tree.children[0])
|
314
|
+
if equation_tree.name == "f_not":
|
315
|
+
return "~"+string_equation_helper(equation_tree.children[0])
|
316
|
+
if equation_tree.name == "f_list":
|
317
|
+
return "["+",".join([string_equation_helper(child) for child in equation_tree.children])+"]"
|
318
|
+
if equation_tree.name == "f_index":
|
319
|
+
return string_equation_helper(equation_tree.children[0])+"["+",".join([string_equation_helper(child) for child in equation_tree.children[1:]])+"]"
|
320
|
+
s = "("
|
321
|
+
if len(equation_tree.children) == 1 or equation_tree.name[2:] in [chr(ord("A")+i) for i in range(26)]+["exist", "forall", "sum2", "int", "pdif", "dif", "A", "B", "C", "covariance", "sum"]:
|
322
|
+
s = equation_tree.name[2:] + s
|
323
|
+
sign = {"f_not":"~", "f_addw":"+", "f_mulw":"*", "f_intersection":"&", "f_union":"|", "f_sum2":",", "f_exist":",", "f_forall":",", "f_sum":",","f_covariance": ",", "f_B":",", "f_imply":"->", "f_ge":">=", "f_le":"<=", "f_gt":">", "f_lt":"<", "f_cosec":"?" , "f_equiv": "<->", "f_sec":"?", "f_cot": "?", "f_dot": ".", "f_circumcenter":"?", "f_transpose":"?", "f_exp":"?", "f_abs":"?", "f_log":"?", "f_and":"&", "f_or":"|", "f_sub":"-", "f_neg":"?", "f_inv":"?", "f_add": "+", "f_mul": "*", "f_pow": "^", "f_poly": ",", "f_div": "/", "f_sub": "-", "f_dif": ",", "f_sin": "?", "f_cos": "?", "f_tan": "?", "f_eq": "=", "f_sqrt": "?"}
|
324
|
+
arr = []
|
325
|
+
k = None
|
326
|
+
if equation_tree.name not in sign.keys():
|
327
|
+
k = ","
|
328
|
+
else:
|
329
|
+
k = sign[equation_tree.name]
|
330
|
+
for child in equation_tree.children:
|
331
|
+
arr.append(string_equation_helper(copy.deepcopy(child)))
|
332
|
+
outfinal = s + k.join(arr) + ")"+extra
|
333
|
+
|
334
|
+
return outfinal.replace("+-", "-")
|
335
|
+
def string_equation(eq):
|
336
|
+
alpha = ["x", "y", "z"]+[chr(x+ord("a")) for x in range(0,23)]
|
337
|
+
beta = [chr(x+ord("A")) for x in range(0,26)]
|
338
|
+
eq = tree_form(eq)
|
339
|
+
|
340
|
+
for i, letter in enumerate(alpha):
|
341
|
+
eq = replace(eq, tree_form("v_"+str(i)), tree_form(letter))
|
342
|
+
for i, letter in enumerate(beta):
|
343
|
+
eq = replace(eq, tree_form("v_-"+str(i+1)), tree_form(letter))
|
344
|
+
for i in range(100, 150):
|
345
|
+
eq = replace(eq, tree_form("v_"+str(i)), tree_form("c"+str(i-100)))
|
346
|
+
eq = str_form(eq)
|
347
|
+
|
348
|
+
eq = eq.replace("d_", "")
|
349
|
+
eq = eq.replace("s_", "")
|
350
|
+
eq = eq.replace("v_", "")
|
351
|
+
eq = eq.replace("'", "")
|
352
|
+
outfinal = string_equation_helper(tree_form(eq))
|
353
|
+
if outfinal[0] == "(" and outfinal[-1] == ")":
|
354
|
+
return outfinal[1:-1]
|
355
|
+
return outfinal
|