mathai 0.4.0__py3-none-any.whl → 0.4.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 +0 -2
- mathai/apart.py +19 -9
- mathai/base.py +6 -0
- mathai/integrate.py +18 -10
- mathai/linear.py +7 -4
- mathai/simplify.py +23 -1
- mathai/trig.py +41 -10
- {mathai-0.4.0.dist-info → mathai-0.4.2.dist-info}/METADATA +1 -1
- {mathai-0.4.0.dist-info → mathai-0.4.2.dist-info}/RECORD +11 -12
- mathai/search.py +0 -117
- {mathai-0.4.0.dist-info → mathai-0.4.2.dist-info}/WHEEL +0 -0
- {mathai-0.4.0.dist-info → mathai-0.4.2.dist-info}/top_level.txt +0 -0
mathai/__init__.py
CHANGED
mathai/apart.py
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
from .linear import linear_solve
|
|
2
2
|
from .expand import expand
|
|
3
3
|
from .simplify import simplify
|
|
4
|
+
|
|
4
5
|
from .diff import diff
|
|
5
6
|
from .inverse import inverse
|
|
6
7
|
from .base import *
|
|
7
8
|
import math
|
|
8
9
|
from .tool import poly, enclose_const
|
|
9
10
|
|
|
10
|
-
def _apart(eq, v=
|
|
11
|
-
|
|
11
|
+
def _apart(eq, v=None):
|
|
12
|
+
if v is None:
|
|
13
|
+
if len(vlist(eq)) == 0:
|
|
14
|
+
return eq
|
|
15
|
+
v = vlist(eq)[0]
|
|
12
16
|
origv = vlist(eq)
|
|
13
17
|
eq = simplify(eq)
|
|
14
18
|
if eq.name != "f_mul":
|
|
@@ -42,8 +46,9 @@ def _apart(eq, v="v_0"):
|
|
|
42
46
|
s = []
|
|
43
47
|
facd = [simplify(x) for x in factor_generation(simplify(d))]
|
|
44
48
|
|
|
45
|
-
|
|
46
|
-
facd2 = remove_duplicates_custom(facd, lambda m, n: simplify(m-n) == tree_form("d_0"))
|
|
49
|
+
|
|
50
|
+
facd2 = remove_duplicates_custom(facd, lambda m, n: simplify(expand(simplify(m-n))) == tree_form("d_0"))
|
|
51
|
+
|
|
47
52
|
if len(facd2) == 1:
|
|
48
53
|
return eq
|
|
49
54
|
x = tree_form(v)
|
|
@@ -58,6 +63,7 @@ def _apart(eq, v="v_0"):
|
|
|
58
63
|
if n > 2:
|
|
59
64
|
return eq
|
|
60
65
|
n = tree_form("d_"+str(n))
|
|
66
|
+
|
|
61
67
|
l = len(poly(item, v))
|
|
62
68
|
if l == 3:
|
|
63
69
|
a = alloclst.pop(0)
|
|
@@ -93,14 +99,15 @@ def _apart(eq, v="v_0"):
|
|
|
93
99
|
final = summation(final2)
|
|
94
100
|
|
|
95
101
|
s = simplify(TreeNode("f_eq", [final-eq2, tree_form("d_0")]))
|
|
96
|
-
|
|
102
|
+
|
|
97
103
|
lst = poly(s.children[0], v)
|
|
98
|
-
|
|
104
|
+
|
|
99
105
|
lst = [TreeNode("f_eq", [item, tree_form("d_0")]) for item in lst if "v_" in str_form(item)]
|
|
100
106
|
lst2 = []
|
|
101
107
|
for item in lst:
|
|
102
108
|
lst2+=vlist(item)
|
|
103
109
|
origv = list(set(lst2)-set(origv))
|
|
110
|
+
|
|
104
111
|
out = linear_solve(TreeNode("f_and", lst), [tree_form(item) for item in origv])
|
|
105
112
|
for item in out.children:
|
|
106
113
|
|
|
@@ -108,6 +115,9 @@ def _apart(eq, v="v_0"):
|
|
|
108
115
|
return simplify(final3)
|
|
109
116
|
def apart(eq):
|
|
110
117
|
eq, fx = enclose_const(eq)
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
118
|
+
def helper(eq):
|
|
119
|
+
eq2 = _apart(eq)
|
|
120
|
+
if eq != eq2:
|
|
121
|
+
return eq2
|
|
122
|
+
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
|
123
|
+
return fx(helper(eq))
|
mathai/base.py
CHANGED
|
@@ -131,6 +131,8 @@ def frac(eq):
|
|
|
131
131
|
return Fraction(int(eq.name[2:]))
|
|
132
132
|
if eq.name == "f_add":
|
|
133
133
|
p = frac(eq.children[0])
|
|
134
|
+
if p is None:
|
|
135
|
+
return None
|
|
134
136
|
for child in eq.children[1:]:
|
|
135
137
|
tmp = frac(child)
|
|
136
138
|
if isinstance(tmp, Fraction):
|
|
@@ -140,6 +142,8 @@ def frac(eq):
|
|
|
140
142
|
return p
|
|
141
143
|
if eq.name == "f_mul":
|
|
142
144
|
p = frac(eq.children[0])
|
|
145
|
+
if p is None:
|
|
146
|
+
return None
|
|
143
147
|
for child in eq.children[1:]:
|
|
144
148
|
tmp = frac(child)
|
|
145
149
|
if isinstance(tmp, Fraction):
|
|
@@ -286,6 +290,8 @@ def flatten_tree(node):
|
|
|
286
290
|
node.children = [flatten_tree(child) for child in node.children]
|
|
287
291
|
return node
|
|
288
292
|
def dowhile(eq, fx):
|
|
293
|
+
if eq is None:
|
|
294
|
+
return None
|
|
289
295
|
while True:
|
|
290
296
|
orig = eq.copy_tree()
|
|
291
297
|
eq2 = fx(eq)
|
mathai/integrate.py
CHANGED
|
@@ -104,8 +104,6 @@ def handle_try(eq):
|
|
|
104
104
|
else:
|
|
105
105
|
return TreeNode(eq.name, [handle_try(child) for child in eq.children])
|
|
106
106
|
def inteq(eq):
|
|
107
|
-
if "f_ref" not in str_form(eq):
|
|
108
|
-
return eq
|
|
109
107
|
if eq.name == "f_try":
|
|
110
108
|
eq2 = None
|
|
111
109
|
output = []
|
|
@@ -113,13 +111,19 @@ def inteq(eq):
|
|
|
113
111
|
if child.name == "f_ref":
|
|
114
112
|
eq2 = child.children[0]
|
|
115
113
|
break
|
|
114
|
+
if eq2 is None:
|
|
115
|
+
return eq
|
|
116
116
|
for child in eq.children:
|
|
117
117
|
if child.name == "f_ref":
|
|
118
118
|
output.append(child)
|
|
119
119
|
else:
|
|
120
120
|
eq3 = simplify(expand(simplify(eq2 - child)))
|
|
121
121
|
if contain(eq3, eq2):
|
|
122
|
-
|
|
122
|
+
out = inverse(eq3, str_form(eq2))
|
|
123
|
+
if out is None:
|
|
124
|
+
output.append(child)
|
|
125
|
+
else:
|
|
126
|
+
output.append(out)
|
|
123
127
|
else:
|
|
124
128
|
output.append(child)
|
|
125
129
|
return TreeNode("f_try", output)
|
|
@@ -128,13 +132,14 @@ def inteq(eq):
|
|
|
128
132
|
def rm(eq):
|
|
129
133
|
if eq.name == "f_try":
|
|
130
134
|
eq = TreeNode(eq.name, list(set(eq.children)))
|
|
131
|
-
return TreeNode(eq.name, [rm(child) for child in eq.children])
|
|
135
|
+
return TreeNode(eq.name, [rm(child) for child in eq.children if child is not None])
|
|
132
136
|
def solve_integrate(eq):
|
|
133
137
|
|
|
134
138
|
eq2 = dowhile(eq, _solve_integrate)
|
|
135
139
|
eq2 = dowhile(eq2, handle_try)
|
|
136
140
|
eq2 = rm(eq2)
|
|
137
|
-
eq2.
|
|
141
|
+
if eq2.name == "f_try":
|
|
142
|
+
eq2.children = list(set(eq2.children))
|
|
138
143
|
return eq2
|
|
139
144
|
def integrate_subs(equation, term, v1, v2):
|
|
140
145
|
output = []
|
|
@@ -165,7 +170,7 @@ def integrate_subs(equation, term, v1, v2):
|
|
|
165
170
|
|
|
166
171
|
return none
|
|
167
172
|
|
|
168
|
-
return TreeNode("f_subs", [TreeNode("f_integrate", [simplify(expand(simplify(equation))), tree_form(origv2)]),tree_form(origv2) ,g])
|
|
173
|
+
return TreeNode("f_subs", [TreeNode("f_integrate", [simplify(fraction(expand(simplify(equation)))), tree_form(origv2)]),tree_form(origv2) ,g])
|
|
169
174
|
|
|
170
175
|
def integrate_subs_main(equation):
|
|
171
176
|
if equation.name == "f_ref":
|
|
@@ -291,7 +296,7 @@ def _sqint(equation):
|
|
|
291
296
|
return coll
|
|
292
297
|
|
|
293
298
|
def sqint(eq):
|
|
294
|
-
out = _sqint(eq)
|
|
299
|
+
out = simplify(_sqint(eq))
|
|
295
300
|
if out is None:
|
|
296
301
|
return eq
|
|
297
302
|
return out
|
|
@@ -338,6 +343,7 @@ def integration_formula_init():
|
|
|
338
343
|
(f"e^(A*{var}+B)", f"e^(A*{var}+B)/A"),\
|
|
339
344
|
(f"1/cos({var})", f"log(abs((1+sin({var}))/cos({var})))"),\
|
|
340
345
|
(f"1/cos({var})^2", f"sin({var})/cos({var})"),\
|
|
346
|
+
(f"1/sin({var})", f"log(abs(tan({var}/2)))"),\
|
|
341
347
|
(f"abs(A*{var}+B)", f"(A*{var}+B)*abs(A*{var}+B)/(2*A)")]
|
|
342
348
|
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
|
343
349
|
expr = [[parse("A"), parse("1")], [parse("B"), parse("0")]]
|
|
@@ -376,6 +382,7 @@ def rm_const(equation):
|
|
|
376
382
|
return rm_const(TreeNode("f_integrate",[equation, wrt])) *const
|
|
377
383
|
equation = eq2
|
|
378
384
|
return TreeNode(equation.name, [rm_const(child) for child in equation.children])
|
|
385
|
+
|
|
379
386
|
def integrate_formula(equation):
|
|
380
387
|
if equation.name == "f_ref":
|
|
381
388
|
return equation.copy_tree()
|
|
@@ -384,17 +391,18 @@ def integrate_formula(equation):
|
|
|
384
391
|
integrand = eq2.children[0]
|
|
385
392
|
wrt = eq2.children[1]
|
|
386
393
|
if integrand == wrt:
|
|
387
|
-
return
|
|
394
|
+
return wrt**2/2 # x^2/2
|
|
388
395
|
if not contain(integrand, wrt):
|
|
389
|
-
return
|
|
396
|
+
return integrand*wrt
|
|
390
397
|
out = transform_formula(simplify(trig0(integrand)), wrt.name, formula_gen[0], formula_gen[1], formula_gen[2])
|
|
391
398
|
if out is not None:
|
|
399
|
+
|
|
392
400
|
return out
|
|
393
401
|
expr_str = str_form(integrand)
|
|
394
402
|
if expr_str.count("f_sin") + expr_str.count("f_cos") > 2:
|
|
395
403
|
out = transform_formula(integrand, wrt.name, formula_gen4[0], formula_gen4[1], formula_gen4[2])
|
|
396
404
|
if out is not None:
|
|
397
|
-
|
|
405
|
+
|
|
398
406
|
return out
|
|
399
407
|
return TreeNode(eq2.name, [integrate_formula(child) for child in eq2.children])
|
|
400
408
|
|
mathai/linear.py
CHANGED
|
@@ -3,6 +3,9 @@ from .simplify import simplify, solve
|
|
|
3
3
|
from .fraction import fraction
|
|
4
4
|
from .expand import expand
|
|
5
5
|
from .base import *
|
|
6
|
+
from .factor import factorconst
|
|
7
|
+
def ss(eq):
|
|
8
|
+
return dowhile(eq, lambda x: fraction(expand(simplify(x))))
|
|
6
9
|
def rref(matrix):
|
|
7
10
|
rows, cols = len(matrix), len(matrix[0])
|
|
8
11
|
lead = 0
|
|
@@ -10,7 +13,7 @@ def rref(matrix):
|
|
|
10
13
|
if lead >= cols:
|
|
11
14
|
return matrix
|
|
12
15
|
i = r
|
|
13
|
-
while
|
|
16
|
+
while ss(matrix[i][lead]) == tree_form("d_0"):
|
|
14
17
|
i += 1
|
|
15
18
|
if i == rows:
|
|
16
19
|
i = r
|
|
@@ -19,11 +22,11 @@ def rref(matrix):
|
|
|
19
22
|
return matrix
|
|
20
23
|
matrix[i], matrix[r] = matrix[r], matrix[i]
|
|
21
24
|
lv = matrix[r][lead]
|
|
22
|
-
matrix[r] = [
|
|
25
|
+
matrix[r] = [ss(m / lv) for m in matrix[r]]
|
|
23
26
|
for i in range(rows):
|
|
24
27
|
if i != r:
|
|
25
28
|
lv = matrix[i][lead]
|
|
26
|
-
matrix[i] = [
|
|
29
|
+
matrix[i] = [ss(m - lv * n) for m, n in zip(matrix[i], matrix[r])]
|
|
27
30
|
lead += 1
|
|
28
31
|
return matrix
|
|
29
32
|
def islinear(eq, fxconst):
|
|
@@ -91,7 +94,7 @@ def linear(eqlist, fxconst):
|
|
|
91
94
|
for i in range(len(m)):
|
|
92
95
|
for j in range(len(m[i])):
|
|
93
96
|
m[i][j] = fraction(m[i][j])
|
|
94
|
-
|
|
97
|
+
|
|
95
98
|
for item in m:
|
|
96
99
|
if all(item2==tree_form("d_0") for item2 in item[:-1]) and item[-1] != tree_form("d_0"):
|
|
97
100
|
return tree_form("s_false")
|
mathai/simplify.py
CHANGED
|
@@ -279,6 +279,7 @@ def simplify(eq):
|
|
|
279
279
|
return (eq.children[1-i].children[0]**eq.children[i]).fx("log")
|
|
280
280
|
if eq.name == "f_pow" and eq.children[0] == tree_form("s_e") and eq.children[1].name == "f_log":
|
|
281
281
|
return eq.children[1].children[0]
|
|
282
|
+
|
|
282
283
|
if eq.name == "f_pow" and eq.children[0] == tree_form("d_1"):
|
|
283
284
|
eq = tree_form("d_1")
|
|
284
285
|
if eq.name == "f_pow" and eq.children[0] == tree_form("d_0"):
|
|
@@ -286,6 +287,23 @@ def simplify(eq):
|
|
|
286
287
|
error = True
|
|
287
288
|
else:
|
|
288
289
|
eq = tree_form("d_0")
|
|
290
|
+
|
|
291
|
+
if eq.name == "f_mul":
|
|
292
|
+
dic = {}
|
|
293
|
+
for child in eq.children:
|
|
294
|
+
head = child
|
|
295
|
+
tail = None
|
|
296
|
+
if child.name == "f_pow":
|
|
297
|
+
head = child.children[0]
|
|
298
|
+
tail = child.children[1]
|
|
299
|
+
if tail is None:
|
|
300
|
+
tail = tree_form("d_1")
|
|
301
|
+
if head not in dic.keys():
|
|
302
|
+
dic[head] = tail
|
|
303
|
+
else:
|
|
304
|
+
dic[head] += tail
|
|
305
|
+
if len(eq.children) > len(dic.keys()):
|
|
306
|
+
eq = product([key if dic[key] == 1 else key**dic[key] for key in dic.keys()])
|
|
289
307
|
if eq.name == "f_pow" and eq.children[0].name == "f_pow" and eq.children[0].children[1] == tree_form("d_2")**-1 and eq.children[1] == tree_form("d_2"):
|
|
290
308
|
eq = eq.children[0].children[0]
|
|
291
309
|
if (eq.name == "f_sin" and eq.children[0].name == "f_arcsin") or (eq.name == "f_cos" and eq.children[0].name == "f_arccos") or (eq.name == "f_tan" and eq.children[0].name == "f_arctan"):
|
|
@@ -298,7 +316,11 @@ def simplify(eq):
|
|
|
298
316
|
eq = eq.children[0].children[0]
|
|
299
317
|
if eq.name == "f_abs" and eq.children[0].name[:2] == "d_":
|
|
300
318
|
eq = tree_form("d_"+str(abs(int(eq.children[0].name[2:]))))
|
|
301
|
-
|
|
319
|
+
if eq.name == "f_abs" and "v_" not in str_form(eq.children[0]):
|
|
320
|
+
if compute(eq.children[0]) > 0.00001:
|
|
321
|
+
eq = eq.children[0]
|
|
322
|
+
elif compute(eq.children[0]) < 0.00001:
|
|
323
|
+
eq = -eq.children[0]
|
|
302
324
|
if eq.name == "f_pow" and eq.children[0].name[:2] == "d_" and frac(eq.children[1]) is not None:
|
|
303
325
|
f = frac(eq.children[1])
|
|
304
326
|
if f.denominator != 1:
|
mathai/trig.py
CHANGED
|
@@ -169,7 +169,12 @@ def trig4(eq, numer=True):
|
|
|
169
169
|
if eq.name == "f_sin":
|
|
170
170
|
if eq.children[0].name == "f_add" and len(eq.children[0].children)>=2:
|
|
171
171
|
r = len(eq.children[0].children)%2
|
|
172
|
-
a, b =
|
|
172
|
+
a, b = TreeNode("f_add", eq.children[0].children[:round((len(eq.children[0].children)-r)/2)]),\
|
|
173
|
+
TreeNode("f_add", eq.children[0].children[round((len(eq.children[0].children)-r)/2):])
|
|
174
|
+
if len(a.children)==1:
|
|
175
|
+
a=a.children[0]
|
|
176
|
+
if len(b.children)==1:
|
|
177
|
+
b=b.children[0]
|
|
173
178
|
return a.fx("sin")*b.fx("cos") + a.fx("cos")*b.fx("sin")
|
|
174
179
|
if eq.children[0].name == "f_arccos":
|
|
175
180
|
a = eq.children[0].children[0]
|
|
@@ -189,7 +194,12 @@ def trig4(eq, numer=True):
|
|
|
189
194
|
if eq.name == "f_cos":
|
|
190
195
|
if eq.children[0].name == "f_add" and len(eq.children[0].children)>=2:
|
|
191
196
|
r = len(eq.children[0].children)%2
|
|
192
|
-
a, b =
|
|
197
|
+
a, b = TreeNode("f_add", eq.children[0].children[:round((len(eq.children[0].children)-r)/2)]),\
|
|
198
|
+
TreeNode("f_add", eq.children[0].children[round((len(eq.children[0].children)-r)/2):])
|
|
199
|
+
if len(a.children)==1:
|
|
200
|
+
a=a.children[0]
|
|
201
|
+
if len(b.children)==1:
|
|
202
|
+
b=b.children[0]
|
|
193
203
|
return a.fx("cos")*b.fx("cos") - a.fx("sin")*b.fx("sin")
|
|
194
204
|
if eq.children[0].name == "f_arcsin":
|
|
195
205
|
a = eq.children[0].children[0]
|
|
@@ -199,16 +209,37 @@ def trig4(eq, numer=True):
|
|
|
199
209
|
return tree_form("d_1")/(1+a**2)**(tree_form("d_2")**-1)
|
|
200
210
|
|
|
201
211
|
return TreeNode(eq.name, [trig4(child, False) if not numer or (eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]) < 0) else trig4(child, True) for child in eq.children])
|
|
212
|
+
|
|
202
213
|
def trig2(eq):
|
|
203
214
|
if eq.name == "f_add":
|
|
204
215
|
for item in itertools.combinations(range(len(eq.children)), 2):
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
216
|
+
child1, child2 = eq.children[item[0]], eq.children[item[1]]
|
|
217
|
+
|
|
218
|
+
# Check if both are sin or cos
|
|
219
|
+
if child1.name in ["f_sin", "f_cos"] and child2.name in ["f_sin", "f_cos"]:
|
|
220
|
+
a, b = child1.children[0], child2.children[0]
|
|
221
|
+
|
|
222
|
+
# Compute the rest of the sum
|
|
223
|
+
rest = [eq.children[i] for i in range(len(eq.children)) if i not in item]
|
|
224
|
+
if len(rest) == 0:
|
|
225
|
+
rest_tree = tree_form("d_0")
|
|
226
|
+
else:
|
|
227
|
+
rest_tree = summation(rest)
|
|
228
|
+
|
|
229
|
+
# Now handle the sin/cos combination formula
|
|
230
|
+
if child1.name == "f_sin" and child2.name == "f_sin":
|
|
231
|
+
# sin A + sin B = 2 sin((A+B)/2) cos((A-B)/2)
|
|
232
|
+
two = tree_form("d_2")
|
|
233
|
+
combined = two * ((a + b) / two).fx("sin") * ((a - b) / two).fx("cos")
|
|
234
|
+
elif child1.name == "f_cos" and child2.name == "f_cos":
|
|
235
|
+
# cos A + cos B = 2 cos((A+B)/2) cos((A-B)/2)
|
|
236
|
+
two = tree_form("d_2")
|
|
237
|
+
combined = two * ((a + b) / two).fx("cos") * ((a - b) / two).fx("cos")
|
|
210
238
|
else:
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
239
|
+
# sin A + cos B = sin A + cos B (leave unchanged, or implement formula if desired)
|
|
240
|
+
continue # skip for now, keep original
|
|
241
|
+
|
|
242
|
+
return rest_tree + combined
|
|
243
|
+
|
|
244
|
+
# Recurse for other nodes
|
|
214
245
|
return TreeNode(eq.name, [trig2(child) for child in eq.children])
|
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
mathai/__init__.py,sha256=
|
|
2
|
-
mathai/apart.py,sha256=
|
|
3
|
-
mathai/base.py,sha256=
|
|
1
|
+
mathai/__init__.py,sha256=hxMCrvwj98yE5ChWSzvkn0gMxqAQnh8oze3ZlImWyD0,1170
|
|
2
|
+
mathai/apart.py,sha256=8IlJ8X6SKAjPunUPHVLmgNB5GuEi4_XpY0oLkQqrHKc,3770
|
|
3
|
+
mathai/base.py,sha256=DBFHDBRSPeb8O2cH_YzTNG3h7vxrQzrEPSUpDIPCtPI,12724
|
|
4
4
|
mathai/console.py,sha256=Sn58iwYE79MLEh67s8X3q6vZjw6g7f9XM1T8_dBBR2o,3048
|
|
5
5
|
mathai/diff.py,sha256=YUBpRsz0qmBkq5vGxeGnvR4nMKjdOQiIXlNMxpij2ns,3051
|
|
6
6
|
mathai/expand.py,sha256=SnBltkpIENMGkP0AYmbMlSc4H-CF5RslO2PcBEkn1BQ,3359
|
|
7
7
|
mathai/factor.py,sha256=NPXxET52TacNExuvw6p1jbC6g3wY6_VOCdlGlexXZio,5916
|
|
8
8
|
mathai/fraction.py,sha256=Q2ztsh5Bpz6YhML2QU0tfufbAs0Q6J319AhlzKephIY,4396
|
|
9
|
-
mathai/integrate.py,sha256=
|
|
9
|
+
mathai/integrate.py,sha256=a0zAndTUco7FhEDSkuQFtTNzh-5Q0E2_bYkYqWpbgu0,15133
|
|
10
10
|
mathai/inverse.py,sha256=QCvDrzKquWsZv-BDAzZd9HnU0c3gZvcc44UztHVO5LQ,2919
|
|
11
11
|
mathai/limit.py,sha256=RA8YAehgYCGVWv9qBc8uQ34BQ9mFthWl2OrVTwcHl2g,4920
|
|
12
|
-
mathai/linear.py,sha256=
|
|
12
|
+
mathai/linear.py,sha256=BzSnm941Zlod_l6hON4Rs6J4pdAA3MGpRVqr6-66ZBk,5524
|
|
13
13
|
mathai/logic.py,sha256=UvHzRmKcO9AD51tRzHmpNSEhgW5gmaf4XPaQKFjGfC4,9653
|
|
14
14
|
mathai/parser.py,sha256=f7bemieFmp0sbup1NlraMLvZDVFvqKGFknEVtlFRMVk,6979
|
|
15
15
|
mathai/printeq.py,sha256=gIes-pstFOa6FcnpVIVvkjVKuWdsVdo11LlEnmHhakU,1303
|
|
16
|
-
mathai/
|
|
17
|
-
mathai/simplify.py,sha256=F37h-Z_rW35uVgx0G86vQErU2Ac6ZiTBN9KcC3RzDkg,15156
|
|
16
|
+
mathai/simplify.py,sha256=nxDjrQzC0wgF4BooBiHI_7mTdEJgygOSM97zx1zBR5c,16075
|
|
18
17
|
mathai/structure.py,sha256=4Ww2IAx62RcQSO7_17TZES-DjMWBpcFQtL939FBIHwY,4103
|
|
19
18
|
mathai/tool.py,sha256=UyccamiJy_CkFPakfufyPzdhtlEO6v2D7qwbXQ9V7Rg,2000
|
|
20
|
-
mathai/trig.py,sha256=
|
|
19
|
+
mathai/trig.py,sha256=VYpn3_uuFrr9xOXBSOSGlwdlGHAAlGEzjA1ez-HsZxQ,10712
|
|
21
20
|
mathai/univariate_inequality.py,sha256=_r-kkiS4Hr-jRN7f-EL_E4svAMFWJP1Ea50HJKKbjfk,14778
|
|
22
|
-
mathai-0.4.
|
|
23
|
-
mathai-0.4.
|
|
24
|
-
mathai-0.4.
|
|
25
|
-
mathai-0.4.
|
|
21
|
+
mathai-0.4.2.dist-info/METADATA,sha256=fXzD9pbztl7ku4RJ2BRJosBOXoe1R6uj-SDiTnyRbgM,7021
|
|
22
|
+
mathai-0.4.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
23
|
+
mathai-0.4.2.dist-info/top_level.txt,sha256=ROP4l3OhGYw3ihkQGASr18xM9GsK4z3_6whV5AyXLwE,7
|
|
24
|
+
mathai-0.4.2.dist-info/RECORD,,
|
mathai/search.py
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
from mathai import *
|
|
2
|
-
import copy
|
|
3
|
-
from concurrent.futures import ThreadPoolExecutor, TimeoutError
|
|
4
|
-
|
|
5
|
-
def dfs_simplify(equation, functions, true_expr, false_expr,
|
|
6
|
-
max_timeout=25, max_small=4,
|
|
7
|
-
base_timeout=1, time_per_char=0.1, timeout_increase=0.5):
|
|
8
|
-
"""
|
|
9
|
-
Perform DFS simplification on a given equation using provided functions.
|
|
10
|
-
|
|
11
|
-
Args:
|
|
12
|
-
equation: The starting expression (TreeNode or parsed equation)
|
|
13
|
-
functions: List of simplification functions
|
|
14
|
-
true_expr: Expression representing True (immediate termination)
|
|
15
|
-
false_expr: Expression representing False (immediate termination)
|
|
16
|
-
max_timeout: Maximum timeout allowed for any function
|
|
17
|
-
max_small: Number of smallest expressions to track
|
|
18
|
-
base_timeout: Base timeout in seconds
|
|
19
|
-
time_per_char: Additional timeout per character of expression
|
|
20
|
-
timeout_increase: Factor to increase timeout for consecutive timeouts
|
|
21
|
-
|
|
22
|
-
Returns:
|
|
23
|
-
tuple(found_boolean, boolean_path, smallest_expressions)
|
|
24
|
-
"""
|
|
25
|
-
original_eq = simplify(equation)
|
|
26
|
-
smallest_four = []
|
|
27
|
-
|
|
28
|
-
stack = [(copy.deepcopy(original_eq), [copy.deepcopy(original_eq)])]
|
|
29
|
-
visited = set()
|
|
30
|
-
|
|
31
|
-
found_boolean = False
|
|
32
|
-
boolean_path = None
|
|
33
|
-
boolean_expr = None
|
|
34
|
-
|
|
35
|
-
executor = ThreadPoolExecutor(max_workers=3)
|
|
36
|
-
consecutive_timeouts = 0
|
|
37
|
-
|
|
38
|
-
while stack and not found_boolean:
|
|
39
|
-
current_eq, path = stack.pop()
|
|
40
|
-
expr_str = str(current_eq)
|
|
41
|
-
|
|
42
|
-
if expr_str in visited:
|
|
43
|
-
continue
|
|
44
|
-
visited.add(expr_str)
|
|
45
|
-
|
|
46
|
-
# Thinking message
|
|
47
|
-
printeq(current_eq)
|
|
48
|
-
|
|
49
|
-
# Immediate termination using predicate functions
|
|
50
|
-
if true_expr(current_eq):
|
|
51
|
-
found_boolean = True
|
|
52
|
-
boolean_path = path
|
|
53
|
-
boolean_expr = current_eq
|
|
54
|
-
break
|
|
55
|
-
if false_expr(current_eq):
|
|
56
|
-
found_boolean = True
|
|
57
|
-
boolean_path = path
|
|
58
|
-
boolean_expr = current_eq
|
|
59
|
-
break
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
# Insert into smallest_four if qualifies
|
|
63
|
-
inserted = False
|
|
64
|
-
for j in range(len(smallest_four)):
|
|
65
|
-
if len(expr_str) < len(str(smallest_four[j][0])):
|
|
66
|
-
smallest_four.insert(j, (copy.deepcopy(current_eq), copy.deepcopy(path)))
|
|
67
|
-
inserted = True
|
|
68
|
-
break
|
|
69
|
-
if not inserted and len(smallest_four) < max_small:
|
|
70
|
-
smallest_four.append((copy.deepcopy(current_eq), copy.deepcopy(path)))
|
|
71
|
-
if len(smallest_four) > max_small:
|
|
72
|
-
smallest_four = smallest_four[:max_small]
|
|
73
|
-
|
|
74
|
-
# Calculate adaptive timeout with cap
|
|
75
|
-
timeout = (base_timeout + time_per_char * len(expr_str)) * (1 + timeout_increase * consecutive_timeouts)
|
|
76
|
-
if timeout > max_timeout:
|
|
77
|
-
timeout = max_timeout
|
|
78
|
-
|
|
79
|
-
# Try functions that reduce length first
|
|
80
|
-
reduced_any = False
|
|
81
|
-
for fx in functions:
|
|
82
|
-
print(f"[Thinking] Executing {fx.__name__} on current expression (timeout={timeout:.2f}s):")
|
|
83
|
-
printeq(current_eq)
|
|
84
|
-
future = executor.submit(fx, current_eq)
|
|
85
|
-
try:
|
|
86
|
-
new_expr = future.result(timeout=timeout)
|
|
87
|
-
new_expr_str = str(new_expr)
|
|
88
|
-
if len(new_expr_str) <= len(expr_str) and new_expr_str != expr_str:
|
|
89
|
-
reduced_any = True
|
|
90
|
-
stack.append((new_expr, path + [copy.deepcopy(new_expr)]))
|
|
91
|
-
consecutive_timeouts = 0 # reset after success
|
|
92
|
-
except TimeoutError:
|
|
93
|
-
print(f"[Thinking] {fx.__name__} timed out, skipping.")
|
|
94
|
-
consecutive_timeouts += 1
|
|
95
|
-
continue
|
|
96
|
-
|
|
97
|
-
# If no reducing function worked, try growing functions
|
|
98
|
-
if not reduced_any:
|
|
99
|
-
for fx in functions:
|
|
100
|
-
print(f"[Thinking] Trying growing {fx.__name__} on current expression (timeout={timeout:.2f}s):")
|
|
101
|
-
printeq(current_eq)
|
|
102
|
-
future = executor.submit(fx, current_eq)
|
|
103
|
-
try:
|
|
104
|
-
new_expr = future.result(timeout=timeout)
|
|
105
|
-
new_expr_str = str(new_expr)
|
|
106
|
-
if new_expr_str != expr_str:
|
|
107
|
-
stack.append((new_expr, path + [copy.deepcopy(new_expr)]))
|
|
108
|
-
consecutive_timeouts = 0
|
|
109
|
-
break # only take one growing function
|
|
110
|
-
except TimeoutError:
|
|
111
|
-
print(f"[Thinking] {fx.__name__} (growing) timed out, skipping.")
|
|
112
|
-
consecutive_timeouts += 1
|
|
113
|
-
continue
|
|
114
|
-
|
|
115
|
-
executor.shutdown(wait=True)
|
|
116
|
-
|
|
117
|
-
return found_boolean, boolean_path, smallest_four
|
|
File without changes
|
|
File without changes
|