mathai 0.3.0__py3-none-any.whl → 0.3.2__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 +32 -2
- mathai/apart.py +17 -7
- mathai/base.py +13 -6
- mathai/console.py +1 -1
- mathai/diff.py +7 -4
- mathai/expand.py +86 -48
- mathai/factor.py +11 -3
- mathai/fraction.py +97 -53
- mathai/integrate.py +304 -251
- mathai/linear.py +3 -2
- mathai/parser.py +2 -2
- mathai/printeq.py +1 -1
- mathai/search.py +111 -0
- mathai/simplify.py +12 -8
- mathai/structure.py +1 -1
- mathai/tool.py +28 -1
- mathai/trig.py +55 -10
- {mathai-0.3.0.dist-info → mathai-0.3.2.dist-info}/METADATA +13 -13
- mathai-0.3.2.dist-info/RECORD +25 -0
- {mathai-0.3.0.dist-info → mathai-0.3.2.dist-info}/WHEEL +1 -1
- mathai-0.3.0.dist-info/RECORD +0 -24
- {mathai-0.3.0.dist-info → mathai-0.3.2.dist-info}/top_level.txt +0 -0
mathai/__init__.py
CHANGED
@@ -1,16 +1,46 @@
|
|
1
1
|
from .expand import expand
|
2
|
+
|
2
3
|
from .parser import parse
|
4
|
+
|
3
5
|
from .printeq import printeq, printeq_log, printeq_str
|
6
|
+
|
4
7
|
from .simplify import solve, simplify, solve2
|
5
|
-
|
8
|
+
|
9
|
+
from .integrate import ref as integrate_save
|
10
|
+
from .integrate import integrate_subs_main as integrate_subs
|
11
|
+
from .integrate import byparts as integrate_byparts
|
12
|
+
from .integrate import sqint as integrate_fraction
|
13
|
+
from .integrate import integrate_summation
|
14
|
+
from .integrate import rm_const as integrate_const
|
15
|
+
from .integrate import solve_integrate as integrate_clean
|
16
|
+
from .integrate import inteq as integrate_recursive
|
17
|
+
from .integrate import integrate_formula
|
18
|
+
|
6
19
|
from .diff import diff
|
7
|
-
|
20
|
+
|
21
|
+
from .factor import factor as factor1
|
22
|
+
from .factor import factor2
|
23
|
+
from .factor import factorconst as factor0
|
24
|
+
|
8
25
|
from .fraction import fraction
|
26
|
+
|
9
27
|
from .inverse import inverse
|
28
|
+
|
10
29
|
from .trig import trig0, trig1, trig2, trig3, trig4
|
30
|
+
|
11
31
|
from .logic import logic0, logic1, logic2, logic3
|
32
|
+
|
12
33
|
from .apart import apart
|
34
|
+
|
13
35
|
from .console import console
|
36
|
+
|
14
37
|
from .limit import limit
|
38
|
+
|
39
|
+
from .search import dfs_simplify as search0
|
40
|
+
|
15
41
|
from .univariate_inequality import wavycurvy, absolute, domain, handle_sqrt
|
42
|
+
|
16
43
|
from .base import *
|
44
|
+
|
45
|
+
from .tool import enclose_const
|
46
|
+
|
mathai/apart.py
CHANGED
@@ -5,16 +5,18 @@ from .diff import diff
|
|
5
5
|
from .inverse import inverse
|
6
6
|
from .base import *
|
7
7
|
import math
|
8
|
-
from .tool import poly
|
8
|
+
from .tool import poly, enclose_const
|
9
9
|
|
10
|
-
def
|
10
|
+
def _apart(eq, v="v_0"):
|
11
|
+
|
12
|
+
origv = vlist(eq)
|
11
13
|
eq = simplify(eq)
|
12
14
|
if eq.name != "f_mul":
|
13
15
|
return eq
|
14
16
|
if any("f_"+item in str_form(eq) for item in "sin cos tan log".split(" ")):
|
15
17
|
return eq
|
16
18
|
def exclude(eq):
|
17
|
-
if eq.name == "f_pow" and eq.children[1].
|
19
|
+
if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]).denominator != 1:
|
18
20
|
return False
|
19
21
|
if any(not exclude(child) for child in eq.children):
|
20
22
|
return False
|
@@ -47,6 +49,7 @@ def apart(eq, v="v_0"):
|
|
47
49
|
x = tree_form(v)
|
48
50
|
num = []
|
49
51
|
dem = []
|
52
|
+
|
50
53
|
for item in facd2:
|
51
54
|
|
52
55
|
g = countfac(facd, item)
|
@@ -94,10 +97,17 @@ def apart(eq, v="v_0"):
|
|
94
97
|
lst = poly(s.children[0], v)
|
95
98
|
|
96
99
|
lst = [TreeNode("f_eq", [item, tree_form("d_0")]) for item in lst if "v_" in str_form(item)]
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
+
lst2 = []
|
101
|
+
for item in lst:
|
102
|
+
lst2+=vlist(item)
|
103
|
+
origv = list(set(lst2)-set(origv))
|
104
|
+
out = linear_solve(TreeNode("f_and", lst), [tree_form(item) for item in origv])
|
100
105
|
for item in out.children:
|
101
106
|
|
102
|
-
final3 = replace(final3, tree_form(vlist(item)[0]), inverse(item.children[0], vlist(item)[0]))
|
107
|
+
final3 = replace(final3, tree_form(list(set(vlist(item))&set(origv))[0]), inverse(item.children[0], list(set(vlist(item))&set(origv))[0]))
|
103
108
|
return simplify(final3)
|
109
|
+
def apart(eq):
|
110
|
+
eq, fx = enclose_const(eq)
|
111
|
+
|
112
|
+
eq = _apart(eq)
|
113
|
+
return fx(eq)
|
mathai/base.py
CHANGED
@@ -3,7 +3,8 @@ from fractions import Fraction
|
|
3
3
|
|
4
4
|
class TreeNode:
|
5
5
|
def __init__(self, name, children=[]):
|
6
|
-
|
6
|
+
|
7
|
+
children = [child.copy_tree() for child in children]
|
7
8
|
self.name = name
|
8
9
|
if name in ["f_add", "f_mul"]:
|
9
10
|
self.children = sorted(children, key=lambda x: str_form(x))
|
@@ -12,6 +13,11 @@ class TreeNode:
|
|
12
13
|
|
13
14
|
def fx(self, fxname):
|
14
15
|
return TreeNode("f_" + fxname, [self])
|
16
|
+
def copy_tree(node):
|
17
|
+
if node is None:
|
18
|
+
return None
|
19
|
+
|
20
|
+
return tree_form(str_form(node))
|
15
21
|
|
16
22
|
def __repr__(self):
|
17
23
|
return string_equation(str_form(self))
|
@@ -281,10 +287,11 @@ def flatten_tree(node):
|
|
281
287
|
return node
|
282
288
|
def dowhile(eq, fx):
|
283
289
|
while True:
|
284
|
-
orig =
|
285
|
-
|
286
|
-
if
|
290
|
+
orig = eq.copy_tree()
|
291
|
+
eq2 = fx(eq)
|
292
|
+
if eq2 is None:
|
287
293
|
return None
|
294
|
+
eq = eq2.copy_tree()
|
288
295
|
if eq == orig:
|
289
296
|
return orig
|
290
297
|
def tree_form(tabbed_strings):
|
@@ -318,7 +325,7 @@ def string_equation_helper(equation_tree):
|
|
318
325
|
if equation_tree.name == "f_index":
|
319
326
|
return string_equation_helper(equation_tree.children[0])+"["+",".join([string_equation_helper(child) for child in equation_tree.children[1:]])+"]"
|
320
327
|
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"]:
|
328
|
+
if len(equation_tree.children) == 1 or equation_tree.name[2:] in [chr(ord("A")+i) for i in range(26)]+["subs", "try", "ref", "integrate", "exist", "forall", "sum2", "int", "pdif", "dif", "A", "B", "C", "covariance", "sum"]:
|
322
329
|
s = equation_tree.name[2:] + s
|
323
330
|
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
331
|
arr = []
|
@@ -328,7 +335,7 @@ def string_equation_helper(equation_tree):
|
|
328
335
|
else:
|
329
336
|
k = sign[equation_tree.name]
|
330
337
|
for child in equation_tree.children:
|
331
|
-
arr.append(string_equation_helper(
|
338
|
+
arr.append(string_equation_helper(child.copy_tree()))
|
332
339
|
outfinal = s + k.join(arr) + ")"+extra
|
333
340
|
|
334
341
|
return outfinal.replace("+-", "-")
|
mathai/console.py
CHANGED
@@ -3,7 +3,7 @@ from .expand import expand
|
|
3
3
|
from .parser import parse
|
4
4
|
from .printeq import printeq, printeq_log
|
5
5
|
from .simplify import solve, simplify
|
6
|
-
|
6
|
+
|
7
7
|
from .diff import diff
|
8
8
|
from .base import *
|
9
9
|
from .factor import _factorconst, factor
|
mathai/diff.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
from .simplify import solve
|
2
2
|
from .base import *
|
3
|
-
|
3
|
+
from .trig import trig0
|
4
4
|
def diff(equation, var="v_0"):
|
5
5
|
def diffeq(eq):
|
6
6
|
eq = solve(eq)
|
@@ -53,13 +53,16 @@ def diff(equation, var="v_0"):
|
|
53
53
|
b1 = power - tree_form("d_1")
|
54
54
|
bab1 = TreeNode("f_pow", [base, b1])
|
55
55
|
return power * bab1 * dbase
|
56
|
-
return
|
56
|
+
return TreeNode("f_dif", [eq, tree_form(var)])
|
57
57
|
def helper(equation, var="v_0"):
|
58
58
|
if equation.name == "f_dif":
|
59
59
|
if equation.children[0].name == var:
|
60
60
|
return tree_form("d_1")
|
61
|
-
|
61
|
+
if var not in str_form(equation.children[0]):
|
62
|
+
return tree_form("d_0")
|
63
|
+
else:
|
64
|
+
return equation
|
62
65
|
return TreeNode(equation.name, [helper(child, var) for child in equation.children])
|
63
|
-
equation = diffeq(equation)
|
66
|
+
equation = diffeq(trig0(equation))
|
64
67
|
equation = helper(equation, var)
|
65
68
|
return solve(equation)
|
mathai/expand.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
import itertools
|
3
2
|
from .base import *
|
4
3
|
from .simplify import solve, simplify
|
@@ -6,53 +5,92 @@ from .simplify import solve, simplify
|
|
6
5
|
def expand(eq):
|
7
6
|
if eq is None:
|
8
7
|
return None
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
8
|
+
|
9
|
+
stack = [(eq, 0)] # (node, stage)
|
10
|
+
result_map = {} # id(node) -> expanded TreeNode
|
11
|
+
|
12
|
+
while stack:
|
13
|
+
node, stage = stack.pop()
|
14
|
+
node_id = id(node)
|
15
|
+
|
16
|
+
# Leaf node
|
17
|
+
if not node.children and stage == 0:
|
18
|
+
result_map[node_id] = TreeNode(node.name, [])
|
19
|
+
continue
|
20
|
+
|
21
|
+
if stage == 0:
|
22
|
+
# Stage 0: push node back for stage 1 after children
|
23
|
+
stack.append((node, 1))
|
24
|
+
# Push children to stack
|
25
|
+
for child in reversed(node.children):
|
26
|
+
if id(child) not in result_map:
|
27
|
+
stack.append((child, 0))
|
28
|
+
else:
|
29
|
+
# Stage 1: all children processed
|
30
|
+
children_expanded = [result_map[id(child)] for child in node.children]
|
31
|
+
|
32
|
+
# Only f_mul or f_pow need special expansion
|
33
|
+
if node.name in ["f_mul", "f_pow"]:
|
34
|
+
current_eq = TreeNode(node.name, children_expanded)
|
35
|
+
|
36
|
+
if node.name == "f_pow":
|
37
|
+
current_eq = TreeNode("f_pow", [current_eq])
|
38
|
+
|
39
|
+
ac = []
|
40
|
+
addchild = []
|
41
|
+
|
42
|
+
for child in current_eq.children:
|
43
|
+
tmp5 = [solve(x) for x in factor_generation(child)]
|
44
|
+
ac += tmp5
|
45
|
+
|
46
|
+
tmp3 = []
|
47
|
+
for child in ac:
|
48
|
+
tmp2 = []
|
49
|
+
if child.name == "f_add":
|
50
|
+
if child.children != []:
|
51
|
+
tmp2.extend(child.children)
|
52
|
+
else:
|
53
|
+
tmp2 = [child]
|
54
|
+
else:
|
55
|
+
tmp3.append(child)
|
56
|
+
if tmp2 != []:
|
57
|
+
addchild.append(tmp2)
|
58
|
+
|
59
|
+
tmp4 = 1
|
60
|
+
for item in tmp3:
|
61
|
+
tmp4 = tmp4 * item
|
62
|
+
addchild.append([tmp4])
|
63
|
+
|
64
|
+
def flatten(lst):
|
65
|
+
flat_list = []
|
66
|
+
for item in lst:
|
67
|
+
if isinstance(item, list) and item == []:
|
68
|
+
continue
|
69
|
+
if isinstance(item, list):
|
70
|
+
flat_list.extend(flatten(item))
|
71
|
+
else:
|
72
|
+
flat_list.append(item)
|
73
|
+
return flat_list
|
74
|
+
|
75
|
+
if len(flatten(addchild)) > 0:
|
76
|
+
add = 0
|
77
|
+
for prod_items in itertools.product(*addchild):
|
78
|
+
mul = 1
|
79
|
+
for item2 in prod_items:
|
80
|
+
mul = mul * item2
|
81
|
+
mul = simplify(mul)
|
82
|
+
add = add + mul
|
83
|
+
add = simplify(add)
|
84
|
+
current_eq = simplify(add)
|
24
85
|
else:
|
25
|
-
|
86
|
+
current_eq = simplify(current_eq)
|
87
|
+
|
88
|
+
# Store expanded result
|
89
|
+
result_map[node_id] = current_eq
|
26
90
|
else:
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
tmp4 = tmp4 * item
|
33
|
-
addchild.append([tmp4])
|
34
|
-
def flatten(lst):
|
35
|
-
flat_list = []
|
36
|
-
for item in lst:
|
37
|
-
if isinstance(item, list) and item == []:
|
38
|
-
continue
|
39
|
-
if isinstance(item, list):
|
40
|
-
flat_list.extend(flatten(item))
|
41
|
-
else:
|
42
|
-
flat_list.append(item)
|
43
|
-
return flat_list
|
44
|
-
|
45
|
-
if isinstance(addchild, list) and len(flatten(addchild))>0:
|
46
|
-
add= 0
|
47
|
-
for item in itertools.product(*addchild):
|
48
|
-
mul = 1
|
49
|
-
for item2 in item:
|
50
|
-
mul = mul * item2
|
51
|
-
mul = simplify(mul)
|
52
|
-
add = add + mul
|
53
|
-
add = simplify(add)
|
54
|
-
eq = add
|
55
|
-
eq = simplify(eq)
|
56
|
-
|
57
|
-
return TreeNode(eq.name, [expand(child) for child in eq.children])
|
91
|
+
# Default: reconstruct node with children
|
92
|
+
result_map[node_id] = TreeNode(node.name, children_expanded)
|
93
|
+
|
94
|
+
# Return final expanded eq
|
95
|
+
return result_map[id(eq)]
|
58
96
|
|
mathai/factor.py
CHANGED
@@ -77,7 +77,12 @@ def factor_quad_formula_init():
|
|
77
77
|
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
78
78
|
expr = [[parse("A"), parse("1")], [parse("B"), parse("0"), parse("1")], [parse("C"), parse("0")]]
|
79
79
|
return [formula_list, var, expr]
|
80
|
-
|
80
|
+
def factor_quar_formula_init():
|
81
|
+
var = ""
|
82
|
+
formula_list = [(f"(A^4+B*A^2+C)", f"(A^2 + sqrt(2*sqrt(C) - B)*A + sqrt(C))*(A^2 - sqrt(2*sqrt(C) - B)*A + sqrt(C))")]
|
83
|
+
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
84
|
+
expr = [[parse("A")], [parse("B"), parse("0"), parse("1")], [parse("C"), parse("0")]]
|
85
|
+
return [formula_list, var, expr]
|
81
86
|
def factor_cube_formula_init():
|
82
87
|
var = ""
|
83
88
|
formula_list = [(f"D^3+E", f"(D+E^(1/3))*(D^2-D*E^(1/3)+E^(2/3))"), (f"D^3-E", f"(D-E^(1/3))*(D^2+D*E^(1/3)+E^(2/3))"),\
|
@@ -87,8 +92,9 @@ def factor_cube_formula_init():
|
|
87
92
|
return [formula_list, var, expr]
|
88
93
|
formula_gen2 = factor_quad_formula_init()
|
89
94
|
formula_gen3 = factor_cube_formula_init()
|
95
|
+
formula_gen9 = factor_quar_formula_init()
|
90
96
|
def factor_helper(equation, complexnum, power=2):
|
91
|
-
global formula_gen2, formula_gen3
|
97
|
+
global formula_gen2, formula_gen3, formula_gen9
|
92
98
|
maxnum = 1
|
93
99
|
def high(eq):
|
94
100
|
nonlocal maxnum
|
@@ -114,6 +120,8 @@ def factor_helper(equation, complexnum, power=2):
|
|
114
120
|
out = transform_formula(helper(equation), "v_0", formula_gen2[0], formula_gen2[1], formula_gen2[2])
|
115
121
|
elif power == 3:
|
116
122
|
out = transform_formula(helper(equation), "v_0", formula_gen3[0], formula_gen3[1], formula_gen3[2])
|
123
|
+
elif power == 4:
|
124
|
+
out = transform_formula(helper(equation), "v_0", formula_gen9[0], formula_gen9[1], formula_gen9[2])
|
117
125
|
if out is not None:
|
118
126
|
out = simplify(solve(out))
|
119
127
|
if out is not None and (complexnum or (not complexnum and not contain(out, tree_form("s_i")))):
|
@@ -122,4 +130,4 @@ def factor_helper(equation, complexnum, power=2):
|
|
122
130
|
def factor(equation, complexnum=False):
|
123
131
|
return solve(take_common2(simplify(factor_helper(simplify(equation), complexnum, 2))))
|
124
132
|
def factor2(equation, complexnum=False):
|
125
|
-
return solve(factor_helper(simplify(factor_helper(simplify(equation), complexnum, 2)), complexnum, 3))
|
133
|
+
return solve(factor_helper(solve(factor_helper(simplify(factor_helper(simplify(equation), complexnum, 2)), complexnum, 3)), complexnum, 4))
|
mathai/fraction.py
CHANGED
@@ -1,59 +1,103 @@
|
|
1
1
|
from .base import *
|
2
|
-
from .simplify import solve
|
2
|
+
from .simplify import solve, simplify
|
3
3
|
from .expand import expand
|
4
|
+
|
4
5
|
def fraction(eq):
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
6
|
+
stack = [(eq, None)] # (current_node, parent_processed_children)
|
7
|
+
result_map = {} # Map original nodes to their processed TreeNode
|
8
|
+
|
9
|
+
while stack:
|
10
|
+
node, parent_info = stack.pop()
|
11
|
+
|
12
|
+
# If node already processed, continue
|
13
|
+
if node in result_map:
|
14
|
+
continue
|
15
|
+
|
16
|
+
# Base case: leaf node
|
17
|
+
if not node.children:
|
18
|
+
result_map[node] = TreeNode(node.name, [])
|
19
|
+
continue
|
20
|
+
|
21
|
+
# Check if all children are processed
|
22
|
+
all_children_done = all(child in result_map for child in node.children)
|
23
|
+
if not all_children_done:
|
24
|
+
# Push current node back to stack after children
|
25
|
+
stack.append((node, parent_info))
|
26
|
+
for child in reversed(node.children):
|
27
|
+
if child not in result_map:
|
28
|
+
stack.append((child, (node, node.children)))
|
29
|
+
continue
|
30
|
+
|
31
|
+
# Now all children are processed, handle this node
|
32
|
+
if node.name == "f_eq":
|
33
|
+
left = result_map[node.children[0]]
|
34
|
+
right = result_map[node.children[1]]
|
35
|
+
result_map[node] = TreeNode("f_eq", [left, right])
|
36
|
+
continue
|
37
|
+
|
38
|
+
elif node.name == "f_add":
|
39
|
+
con = []
|
40
|
+
for child in node.children:
|
41
|
+
child_processed = result_map[child]
|
42
|
+
if child_processed.name == "f_pow" and child_processed.children[1].name[:2] == "d_" and int(child_processed.children[1].name[2:]) < 0:
|
43
|
+
den = []
|
44
|
+
n = int(child_processed.children[1].name[2:])
|
45
|
+
if n == -1:
|
46
|
+
den.append(child_processed.children[0])
|
47
|
+
else:
|
48
|
+
den.append(TreeNode("f_pow", [child_processed.children[0], tree_form("d_" + str(-n))]))
|
49
|
+
con.append([[], den])
|
50
|
+
elif child_processed.name == "f_mul":
|
51
|
+
num = []
|
52
|
+
den = []
|
53
|
+
for child2 in child_processed.children:
|
54
|
+
if child2.name == "f_pow" and child2.children[1].name[:2] == "d_" and int(child2.children[1].name[2:]) < 0:
|
55
|
+
n = int(child2.children[1].name[2:])
|
56
|
+
if n == -1:
|
57
|
+
den.append(child2.children[0])
|
58
|
+
else:
|
59
|
+
den.append(TreeNode("f_pow", [child2.children[0], tree_form("d_" + str(-n))]))
|
26
60
|
else:
|
27
|
-
|
61
|
+
num.append(child2)
|
62
|
+
con.append([num, den])
|
63
|
+
else:
|
64
|
+
con.append([[child_processed], []])
|
65
|
+
|
66
|
+
if len(con) > 1 and any(x[1] != [] for x in con):
|
67
|
+
# Construct numerator
|
68
|
+
a_children = []
|
69
|
+
for i in range(len(con)):
|
70
|
+
b_children = con[i][0].copy()
|
71
|
+
for j in range(len(con)):
|
72
|
+
if i == j:
|
73
|
+
continue
|
74
|
+
b_children += con[j][1]
|
75
|
+
if len(b_children) == 0:
|
76
|
+
b_children = [tree_form("d_1")]
|
77
|
+
elif len(b_children) == 1:
|
78
|
+
b_children = b_children
|
28
79
|
else:
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
if i ==j:
|
41
|
-
continue
|
42
|
-
b.children += con[j][1]
|
43
|
-
if len(b.children) == 1:
|
44
|
-
a.children.append(b.children[0])
|
45
|
-
elif len(b.children) > 1:
|
46
|
-
a.children.append(b)
|
80
|
+
b_children = [TreeNode("f_mul", b_children)]
|
81
|
+
a_children += b_children if isinstance(b_children, list) else [b_children]
|
82
|
+
|
83
|
+
a = TreeNode("f_add", a_children)
|
84
|
+
|
85
|
+
# Construct denominator
|
86
|
+
c_children = []
|
87
|
+
for i in range(len(con)):
|
88
|
+
c_children += con[i][1]
|
89
|
+
if len(c_children) == 1:
|
90
|
+
c = c_children[0]
|
47
91
|
else:
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
return solve(
|
92
|
+
c = TreeNode("f_mul", c_children)
|
93
|
+
c = TreeNode("f_pow", [c, tree_form("d_-1")])
|
94
|
+
|
95
|
+
result_map[node] = TreeNode("f_mul", [simplify(expand(a)), c])
|
96
|
+
continue
|
97
|
+
|
98
|
+
# Default: just reconstruct node
|
99
|
+
children_processed = [result_map[child] for child in node.children]
|
100
|
+
result_map[node] = TreeNode(node.name, children_processed)
|
101
|
+
|
102
|
+
# Final return
|
103
|
+
return solve(result_map[eq])
|