mathai 0.6.0__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.
@@ -0,0 +1,458 @@
1
+ import itertools
2
+
3
+ from .base import *
4
+ from .inverse import inverse
5
+ from collections import Counter
6
+ #from .factor import factor2
7
+ from .simplify import simplify
8
+ from .expand import expand
9
+ from .fraction import fraction
10
+ import copy
11
+ from .diff import diff
12
+ from .logic import logic0
13
+ from .tool import poly, poly_simplify
14
+ def intersection2(domain, lst):
15
+ domain = copy.deepcopy(domain)
16
+ if domain == [True]:
17
+ return lst
18
+ elif domain == [True]:
19
+ return []
20
+ lst = [item for item in lst if item not in domain]
21
+ out = []
22
+
23
+ for item2 in lst:
24
+ for index in range(len(domain)):
25
+
26
+ if isinstance(domain[index], bool) and domain[index]:
27
+
28
+ if index == 0 and compute(item2) < compute(domain[index+1]):
29
+
30
+ out.append(item2)
31
+ break
32
+ elif index == len(domain)-1 and compute(domain[index-1]) < compute(item2):
33
+ out.append(item2)
34
+ break
35
+ elif index != 0 and index != len(domain)-1 and compute(domain[index-1]) < compute(item2) and compute(item2) < compute(domain[index+1]):
36
+
37
+ out.append(item2)
38
+ break
39
+
40
+ return list(set(out))
41
+ def flip_less_than(inter):
42
+ inter = copy.deepcopy(inter)
43
+ return [not item if isinstance(item, bool) else item for item in inter]
44
+ def intersection(domain_1, domain_2):
45
+ domain_1, domain_2 = copy.deepcopy(domain_1), copy.deepcopy(domain_2)
46
+ if domain_1 == [True]:
47
+ return domain_2
48
+ if domain_2 == [True]:
49
+ return domain_1
50
+ if domain_1 == [False] or domain_2 == [False]:
51
+ return [False]
52
+ def simplify_ranges(ranges):
53
+ simplified_ranges = []
54
+ i = 0
55
+ while i < len(ranges):
56
+ if i + 2 < len(ranges) and ranges[i] is True and ranges[i + 2] is True:
57
+ simplified_ranges.append(True)
58
+ i += 3
59
+ elif i + 2 < len(ranges) and ranges[i] is False and ranges[i + 2] is False:
60
+ simplified_ranges.append(False)
61
+ i += 3
62
+ else:
63
+ simplified_ranges.append(ranges[i])
64
+ i += 1
65
+ return simplified_ranges
66
+ result = domain_1 + domain_2
67
+ result = [item for item in result if not isinstance(item, bool)]
68
+ result = list(set(result))
69
+ result = sorted(result, key=lambda x: compute(x))
70
+ i = len(result)
71
+ while i>=0:
72
+ result.insert(i, True)
73
+ i = i - 1
74
+ result[0] = domain_1[0] and domain_2[0]
75
+ result[-1] = domain_1[-1] and domain_2[-1]
76
+ def find_fraction_in_list(fraction_list, target_fraction):
77
+ for i in range(1, len(fraction_list)-1, 2):
78
+ if fraction_list[i] == target_fraction:
79
+ return i
80
+ return -1
81
+ for i in range(2, len(result)-1, 2):
82
+ if result[i+1] in domain_1:
83
+ result[i] = result[i] and domain_1[find_fraction_in_list(domain_1, result[i+1])-1]
84
+ if result[i+1] in domain_2:
85
+ result[i] = result[i] and domain_2[find_fraction_in_list(domain_2, result[i+1])-1]
86
+ if result[i-1] in domain_1:
87
+ result[i] = result[i] and domain_1[find_fraction_in_list(domain_1, result[i-1])+1]
88
+ if result[i-1] in domain_2:
89
+ result[i] = result[i] and domain_2[find_fraction_in_list(domain_2, result[i-1])+1]
90
+
91
+ result = simplify_ranges(result)
92
+ return result
93
+ class Range:
94
+ def __init__(self, r=[True], p=[], z=[]):
95
+ self.r = r
96
+ self.p = p
97
+ self.z = z
98
+ self.do = True
99
+
100
+ def unfix(self):
101
+ self.do = False
102
+ return self
103
+ def fix(self):
104
+ if not self.do:
105
+ return
106
+ def simplify_ranges(ranges):
107
+ simplified_ranges = []
108
+ i = 0
109
+ while i < len(ranges):
110
+ if i + 2 < len(ranges) and ranges[i] is True and ranges[i + 2] is True:
111
+ simplified_ranges.append(True)
112
+ i += 3
113
+ elif i + 2 < len(ranges) and ranges[i] is False and ranges[i + 2] is False:
114
+ simplified_ranges.append(False)
115
+ i += 3
116
+ else:
117
+ simplified_ranges.append(ranges[i])
118
+ i += 1
119
+ return simplified_ranges
120
+
121
+ self.r = simplify_ranges(self.r)
122
+
123
+ common = set(self.p) & set(self.z)
124
+ self.z = list(set(self.z) - common)
125
+ self.p = list(set(self.p) - common)
126
+
127
+ self.p = list(set(self.p) - set(intersection2(self.r, self.p)))
128
+ self.z = list(set(intersection2(self.r, self.z)))
129
+ return self
130
+
131
+ def __or__(self, other):
132
+ return (self.unfix().__invert__().unfix() & other.unfix().__invert__().unfix()).unfix().__invert__().fix()
133
+ def __invert__(self):
134
+ tmp = Range(flip_less_than(self.r), self.z, list(set(self.p)-set(self.z)))
135
+
136
+ return tmp
137
+ def __and__(self, other):
138
+ a = intersection(self.r, other.r)
139
+ b = intersection2(self.r, other.p)
140
+ c = intersection2(other.r, self.p)
141
+ tmp = Range(a, list(set(b)|set(c)|(set(self.p)&set(other.p))), list(set(self.z)|set(other.z)))
142
+ return tmp
143
+ def __str__(self):
144
+
145
+ if self.r == [False] and self.p == [] and self.z == []:
146
+ return "{}"
147
+ out = []
148
+ out2 = ""
149
+ if self.r != [False]:
150
+ for i in range(0, len(self.r), 2):
151
+ string = ""
152
+ if self.r[i]:
153
+ if i == 0:
154
+ string += "(-inf,"
155
+ if len(self.r)==1:
156
+ string += "+inf)"
157
+ else:
158
+ string += str(self.r[i+1])+")"
159
+ elif i == len(self.r)-1 and len(self.r)!=1:
160
+ string += "("+str(self.r[i-1])+",+inf)"
161
+ else:
162
+ string += "("+str(self.r[i-1])+","+str(self.r[i+1])+")"
163
+ out.append(string)
164
+ if self.p != []:
165
+ out.append("{"+",".join([str(item) for item in self.p])+"}")
166
+ if self.z != []:
167
+ out2 = "{"+",".join([str(item) for item in self.z])+"}"
168
+ if out2 == "":
169
+ return "U".join(out)
170
+ else:
171
+ return "U".join(out)+"-"+out2
172
+ def prepare(eq):
173
+ if eq.name[2:] in "and not or".split(" "):
174
+ output = TreeNode(eq.name, [])
175
+ for child in eq.children:
176
+ out = prepare(child)
177
+ if out is None:
178
+ return None
179
+ output.children.append(out)
180
+ output = TreeNode(output.name, output.children)
181
+ return output
182
+ elif eq.name[2:] in "gt lt eq ge le".split(" "):
183
+ eq = simplify(eq)
184
+ out = prepare(eq.children[0])
185
+ if out is None:
186
+ return None
187
+ output = TreeNode(eq.name, [out, tree_form("d_0")])
188
+
189
+ output = logic0(output)
190
+ return output
191
+ else:
192
+ eq = logic0(eq)
193
+ if eq.name in ["s_true", "s_false"]:
194
+ return eq
195
+ if len(vlist(eq)) != 1:
196
+ if "v_" not in str_form(eq):
197
+ return eq
198
+ return None
199
+ out = poly(eq, vlist(eq)[0])
200
+ if out is None or len(out) > 3:
201
+
202
+ output = []
203
+ for item in factor_generation(eq):
204
+ if item.name == "f_pow" and item.children[1].name == "d_-1":
205
+ out2 = poly(item.children[0], vlist(eq)[0])
206
+ if out2 is not None and len(out2) <= 3:
207
+ output.append(poly_simplify(item.children[0])**-1)
208
+ else:
209
+ return None
210
+ else:
211
+ out2 = poly(item, vlist(eq)[0])
212
+ if out2 is not None and len(out2) <= 3:
213
+ output.append(poly_simplify(item))
214
+ else:
215
+ return None
216
+ return simplify(product(output))
217
+ else:
218
+ return poly_simplify(eq)
219
+
220
+ dic_table = {}
221
+ def helper(eq, var="v_0"):
222
+ global dic_table
223
+
224
+ eq2 = copy.deepcopy(eq)
225
+
226
+ if eq2 in dic_table.keys():
227
+ return dic_table[eq2]
228
+
229
+ if eq.children[0].name == "f_add":
230
+
231
+ eq.children[0] = simplify(expand(eq.children[0]))
232
+ #eq = simplify(factor2(eq))
233
+
234
+
235
+ equ = False
236
+ sign= True
237
+ if eq.name in ["f_gt", "f_ge"]:
238
+ sign = True
239
+ elif eq.name in ["f_lt", "f_le"]:
240
+ sign = False
241
+ if eq.name in ["f_ge", "f_le"]:
242
+ equ = True
243
+ if eq.name == "f_eq":
244
+ equ= True
245
+ critical = []
246
+ equal = []
247
+ more = []
248
+
249
+ _, d = num_dem(eq.children[0])
250
+ d = simplify(d)
251
+
252
+ #d = factor2(d)
253
+
254
+ for item in factor_generation(d):
255
+
256
+ item = simplify(expand(item))
257
+ if len(vlist(item)) != 0:
258
+ v = vlist(item)[0]
259
+ if diff(diff(item, v), v) != tree_form("d_0"):
260
+ continue
261
+ out = inverse(item, vlist(item)[0])
262
+ more.append(simplify(out))
263
+
264
+ #eq.children[0] = factor2(eq.children[0])
265
+
266
+ for item in factor_generation(eq.children[0]):
267
+ item = simplify(expand(item))
268
+
269
+ if len(vlist(item)) == 0:
270
+ if compute(item) <0:
271
+ sign = not sign
272
+ continue
273
+ v = vlist(item)[0]
274
+
275
+ if item.name == "f_pow" and item.children[1].name== "d_-1":
276
+
277
+ item = item.children[0]
278
+
279
+ if diff(diff(item, v), v) != tree_form("d_0"):
280
+
281
+ a = replace(diff(diff(item, v), v), tree_form(v), tree_form("d_0"))/tree_form("d_2")
282
+ if "v_" in str_form(a):
283
+ return None
284
+ if compute(a) < 0:
285
+ sign = not sign
286
+ continue
287
+ else:
288
+ tmp2 = diff(copy.deepcopy(item))
289
+ if compute(tmp2)<0:
290
+ sign = not sign
291
+ item = simplify(item * tree_form("d_-1"))
292
+ out = inverse(item, vlist(item)[0])
293
+ critical.append(out)
294
+ else:
295
+
296
+
297
+ if diff(diff(item, v), v) != tree_form("d_0"):
298
+ a = replace(diff(diff(item, v), v), tree_form(v), tree_form("d_0"))/tree_form("d_2")
299
+ if "v_" in str_form(a):
300
+ return None
301
+ if compute(a) < 0:
302
+ sign = not sign
303
+ continue
304
+ else:
305
+ tmp2 = diff(copy.deepcopy(item))
306
+ if compute(tmp2)<0:
307
+ sign = not sign
308
+ item = simplify(item * tree_form("d_-1"))
309
+ out = inverse(item, vlist(item)[0])
310
+ critical.append(out)
311
+ if equ:
312
+ equal.append(out)
313
+ equal = list(set([simplify(item) for item in equal]))
314
+ more = list(set([simplify(item) for item in more]))
315
+ critical = [simplify(item) for item in critical]
316
+
317
+ critical = Counter(critical)
318
+
319
+ critical = sorted(critical.items(), key=lambda x: compute(x[0]))
320
+
321
+ i = len(critical)
322
+ element = sign
323
+ while i>=0:
324
+ critical.insert(i, element)
325
+ if i>0 and critical[i-1][1] % 2 != 0:
326
+ element = not element
327
+ i = i - 1
328
+ for i in range(1, len(critical), 2):
329
+ critical[i] = critical[i][0]
330
+
331
+
332
+ if eq.name == "f_eq":
333
+ final = Range([False], equal, more)
334
+ dic_table[eq2] = final
335
+ return final
336
+
337
+ final = Range(critical, equal, more)
338
+ dic_table[eq2] = final
339
+ return final
340
+ def wavycurvy(eq):
341
+ if eq.name == "s_true":
342
+ return Range([True])
343
+ if eq.name == "s_false":
344
+ return Range([False])
345
+ if eq.name not in ["f_and", "f_or", "f_not"]:
346
+
347
+ out = helper(eq)
348
+ if out is None:
349
+ return None
350
+ return out
351
+ lst= [wavycurvy(child) for child in eq.children]
352
+ if None in lst:
353
+ return None
354
+ ra = lst[0]
355
+ if eq.name == "f_and":
356
+ for child in lst[1:]:
357
+ ra = ra & child
358
+ elif eq.name == "f_or":
359
+ for child in lst[1:]:
360
+ ra = ra | child
361
+ elif eq.name == "f_not":
362
+ ra = ~ra
363
+ return ra
364
+
365
+ def absolute(equation):
366
+ def mul_abs(eq):
367
+ if eq.name == "f_abs" and eq.children[0].name == "f_mul":
368
+ return simplify(product([item.fx("abs") for item in factor_generation(eq.children[0])]))
369
+ return TreeNode(eq.name, [mul_abs(child) for child in eq.children])
370
+ equation = mul_abs(equation)
371
+
372
+ def collectabs(eq):
373
+ out = []
374
+ if eq.name == "f_abs":
375
+
376
+ out.append(eq)
377
+ return out
378
+ for child in eq.children:
379
+ out += collectabs(child)
380
+ if out != []:
381
+ return out
382
+ return out
383
+ def abc(eq, arr):
384
+ def trans(eq):
385
+ nonlocal arr
386
+ out = {}
387
+ if eq.name == "f_abs":
388
+ x = arr.pop(0)
389
+ if x == 0 or x==2:
390
+ return eq.children[0]
391
+ else:
392
+ return -eq.children[0]
393
+ else:
394
+ return TreeNode(eq.name, [trans(child) for child in eq.children])
395
+ return trans(eq)
396
+ out = list(set(collectabs(equation)))
397
+ if out == []:
398
+ return logic0(equation)
399
+ else:
400
+ a = TreeNode("f_ge", [out[0].children[0], tree_form("d_0")]) & replace(equation, out[0], out[0].children[0])
401
+ b = TreeNode("f_lt", [out[0].children[0], tree_form("d_0")]) & replace(equation, out[0], -out[0].children[0])
402
+ return a | b
403
+ def handle_sqrt(eq):
404
+ d= []
405
+ def helper2(eq):
406
+ nonlocal d
407
+ if eq.name in ["f_lt", "f_gt", "f_le", "f_ge","f_eq"]:
408
+ out = []
409
+ def helper(eq):
410
+ nonlocal out
411
+ if eq.name == "f_pow" and frac(eq.children[1]) == Fraction(1,2):
412
+ out.append(simplify(eq))
413
+ x = [helper(child) for child in eq.children]
414
+ helper(eq)
415
+ for item in out:
416
+ n = tree_form("d_1")
417
+ if eq.name == "f_eq":
418
+ eq2 = inverse(simplify(eq.children[0]), str_form(item))
419
+ else:
420
+ eq2, sgn = inverse(simplify(eq.children[0]), str_form(item), True)
421
+ if sgn == False:
422
+ n = tree_form("d_-1")
423
+ d.append(TreeNode("f_ge", [eq2,tree_form("d_0")]))
424
+ #d.append(TreeNode("f_ge", [item.children[0],tree_form("d_0")]))
425
+ eq3 = simplify(expand(simplify(eq2**2)))
426
+
427
+ return simplify(TreeNode(eq.name, [simplify(n*item.children[0]-eq3*n), tree_form("d_0")]))
428
+
429
+ return TreeNode(eq.name, [helper2(child) for child in eq.children])
430
+ out = helper2(eq)
431
+ if len(d) == 0:
432
+ return out
433
+ return TreeNode("f_and", [helper2(eq)]+d)
434
+ def domain(eq):
435
+ eq = simplify(eq)
436
+ out = []
437
+ def helper2(eq):
438
+ nonlocal out
439
+ if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]).denominator == 2:
440
+ if "v_" in str_form(eq.children[0]):
441
+ out.append(TreeNode("f_ge", [eq.children[0], tree_form("d_0")]))
442
+ out.append(TreeNode("f_ge", [eq, tree_form("d_0")]))
443
+ if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1]) <0:
444
+ tmp = TreeNode("f_eq", [eq.children[0], tree_form("d_0")]).fx("not")
445
+ if "v_" in str_form(tmp):
446
+ out.append(tmp)
447
+ x = [helper2(child) for child in eq.children]
448
+ helper2(eq)
449
+ out = list(set([simplify(item) for item in out]))
450
+ if out == []:
451
+ return eq
452
+ if len(out)==1:
453
+ out = out[0]
454
+ else:
455
+ out = TreeNode("f_and", list(out))
456
+ if eq.name in ["f_lt", "f_gt", "f_le", "f_ge", "f_eq"]:
457
+ return eq & out
458
+ return out
@@ -0,0 +1,234 @@
1
+ Metadata-Version: 2.4
2
+ Name: mathai
3
+ Version: 0.6.0
4
+ Summary: Mathematics solving Ai tailored to NCERT
5
+ Home-page: https://github.com/infinity390/mathai4
6
+ Author: educated indians are having a low iq and are good for nothing
7
+ Requires-Python: >=3.7
8
+ Description-Content-Type: text/markdown
9
+ Requires-Dist: lark-parser
10
+ Dynamic: author
11
+ Dynamic: description
12
+ Dynamic: description-content-type
13
+ Dynamic: home-page
14
+ Dynamic: requires-dist
15
+ Dynamic: requires-python
16
+ Dynamic: summary
17
+
18
+ # Math AI Documentation
19
+ ## Source
20
+ Github repository of the code
21
+ https://github.com/infinity390/mathai4
22
+
23
+ ## Philosophy
24
+ I think it is a big realization in computer science and programming to realize that computers can solve mathematics.
25
+ This understanding should be made mainstream. It can help transform education, mathematical research, and computation of mathematical equations for work.
26
+
27
+ ## Societal Implications Of Such A Computer Program And The Author's Comment On Universities Of India
28
+ I think mathematics is valued by society because of education. Schools and universities teach them.
29
+ So this kind of software, if made mainstream, could bring real change.
30
+
31
+ ### The Author's Comments On The Universities In His Country
32
+ > Educated Indians are having a low IQ and are good for nothing.
33
+ > The Indian Institute of Technology (IITs) graduates are the leader of the fools.
34
+ > Every educated Indian is beneath me.
35
+ > Now learn how this Python library can solve the math questions of your exams.
36
+
37
+ ## The Summary Of How Computer "Solves" Math
38
+ Math equations are a tree data structure (`TreeNode` class).
39
+ We can manipulate the math equations using various algorithms (functions provided by the `mathai` library).
40
+ We first parse the math equation strings to get the tree data structure (`parse` function in `mathai`).
41
+
42
+ ## The Library
43
+ Import the library by doing:
44
+
45
+ ```python
46
+ from mathai import *
47
+ ```
48
+
49
+ ### str_form
50
+ It is the string representation of a `TreeNode` math equation.
51
+
52
+ #### Example
53
+ ```text
54
+ (cos(x)^2)+(sin(x)^2)
55
+ ```
56
+
57
+ Is represented internally as:
58
+
59
+ ```text
60
+ f_add
61
+ f_pow
62
+ f_cos
63
+ v_0
64
+ d_2
65
+ f_pow
66
+ f_sin
67
+ v_0
68
+ d_2
69
+ ```
70
+
71
+ #### Leaf Nodes
72
+
73
+ **Variables** (start with a `v_` prefix):
74
+
75
+ - `v_0` -> x
76
+ - `v_1` -> y
77
+ - `v_2` -> z
78
+ - `v_3` -> a
79
+
80
+ **Numbers** (start with `d_` prefix; only integers):
81
+
82
+ - `d_-1` -> -1
83
+ - `d_0` -> 0
84
+ - `d_1` -> 1
85
+ - `d_2` -> 2
86
+
87
+ #### Branch Nodes
88
+ - `f_add` -> addition
89
+ - `f_mul` -> multiplication
90
+ - `f_pow` -> power
91
+
92
+ ### parse
93
+ Takes a math equation string and outputs a `TreeNode` object.
94
+
95
+ ```python
96
+ from mathai import *
97
+
98
+ equation = parse("sin(x)^2+cos(x)^2")
99
+ print(equation)
100
+ ```
101
+
102
+ #### Output
103
+ ```text
104
+ (cos(x)^2)+(sin(x)^2)
105
+ ```
106
+
107
+ ### printeq, printeq_str, printeq_log
108
+ Prints math equations in a more readable form than usual `print`.
109
+
110
+ ```python
111
+ from mathai import *
112
+
113
+ equation = simplify(parse("(x+1)/x"))
114
+ print(equation)
115
+ printeq(equation)
116
+ ```
117
+
118
+ #### Output
119
+ ```text
120
+ (1+x)*(x^-1)
121
+ (1+x)/x
122
+ ```
123
+
124
+ ### solve, simplify
125
+ `simplify` performs what `solve` does and more.
126
+ It simplifies and cleans up a given math equation.
127
+
128
+ ```python
129
+ from mathai import *
130
+
131
+ equation = simplify(parse("(x+x+x+x-1-1-1-1)*(4*x-4)*sin(sin(x+x+x)*sin(3*x))"))
132
+ printeq(equation)
133
+ ```
134
+
135
+ #### Output
136
+ ```text
137
+ ((-4+(4*x))^2)*sin((sin((3*x))^2))
138
+ ```
139
+
140
+ ### Incomplete Documentation, Will be updated and completed later on
141
+
142
+ ### Example Demonstration [limits questions can also be solved other than this these, try limit()]
143
+ ![pip-install-mathai-mathematics-solving-ai-system-in-python-v0-xcg3c22k51sf1](https://github.com/user-attachments/assets/799f576f-27d0-4d7c-86e9-ad55ff221bcc)
144
+ ```python
145
+ import sys, os, time
146
+ from mathai import *
147
+
148
+ sys.setrecursionlimit(10000)
149
+
150
+ def integration_byparts(item): return simplify(fraction(simplify(byparts(simplify(parse(item)))[0])))
151
+ def integration_apart(item): return simplify(fraction(integrate(apart(factor2(simplify(parse(item)))))[0]))
152
+ def integration_direct(item): return simplify(fraction(simplify(integrate(simplify(parse(item)))[0])))
153
+ def integration_trig(item): return simplify(trig0(integrate(trig1(simplify(parse(item))))[0]))
154
+ def algebra(item): return logic0(simplify(expand(simplify(parse(item)))))
155
+ def trig_basic(item): return logic0(simplify(expand(trig3(simplify(parse(item))))))
156
+ def trig_advanced(item): return logic0(simplify(trig0(trig1(trig4(simplify(fraction(trig0(simplify(parse(item))))))))))
157
+
158
+ all_tasks = [
159
+ *[(item, trig_advanced) for item in [
160
+ "cos(x)/(1+sin(x)) + (1+sin(x))/cos(x) = 2*sec(x)",
161
+ "(1+sec(x))/sec(x) = sin(x)^2/(1-cos(x))"]],
162
+ *[(item, integration_byparts) for item in ["sin(x)*x","x*sin(3*x)","x*log(abs(x))","arctan(x)"]],
163
+ *[(item, integration_apart) for item in ["x/((x+1)*(x+2))","1/(x^2-9)"]],
164
+ *[(item, integration_direct) for item in [
165
+ "x*sqrt(x+2)","sin(cos(x))*sin(x)","2*x/(1+x^2)","sqrt(a*x+b)","cos(sqrt(x))/sqrt(x)","e^(arctan(x))/(1+x^2)","sqrt(sin(2*x))*cos(2*x"]],
166
+ *[(item, integration_trig) for item in ["sin(2*x+5)^2","sin(x)^4","cos(2*x)^4"]],
167
+ *[(item, algebra) for item in ["(x+1)^2 = x^2+2*x+1","(x+1)*(x-1) = x^2-1"]],
168
+ *[(item, trig_basic) for item in ["2*sin(x)*cos(x)=sin(2*x)"]],
169
+ ]
170
+
171
+ def run_task(task):
172
+ item, func = task
173
+ try: result = func(item)
174
+ except Exception as e: result = str(e)
175
+ return item, result
176
+
177
+ if __name__=="__main__":
178
+ print(f"Solving {len(all_tasks)} math questions...\n")
179
+ start_time = time.time()
180
+ for task in all_tasks:
181
+ item, result = run_task(task)
182
+ print(f"{item} => {result}\n")
183
+ print(f"All tasks completed in {time.time()-start_time:.2f} seconds")
184
+ ```
185
+ ### Output
186
+
187
+ ```
188
+ Running 21 tasks asynchronously on 8 cores...
189
+
190
+ x*log(abs(x)) => ((-2*(x^2))+(4*log(abs(x))*(x^2)))*(8^-1)
191
+
192
+ arctan(x) => (log((abs((1+(x^2)))^-1))+(2*arctan(x)*x))*(2^-1)
193
+
194
+ sin(cos(x))*sin(x) => cos(cos(x))
195
+
196
+ 1/(x^2-9) => (log(abs((-3+x)))+log((abs((3+x))^-1)))*(6^-1)
197
+
198
+ x/((x+1)*(x+2)) => log((abs((1+x))^-1))+log(((2+x)^2))
199
+
200
+ x*sin(3*x) => ((-9*cos((3*x))*x)+(3*sin((3*x))))*(27^-1)
201
+
202
+ (1+sec(x))/sec(x) = sin(x)^2/(1-cos(x)) => true
203
+
204
+ e^(arctan(x))/(1+x^2) => e^arctan(x)
205
+
206
+ cos(sqrt(x))/sqrt(x) => 2*sin((x^(2^-1)))
207
+
208
+ sqrt(a*x+b) => 2*(3^-1)*(((x*a)+b)^(3*(2^-1)))*(a^-1)
209
+
210
+ sin(x)*x => (-1*cos(x)*x)+sin(x)
211
+
212
+ (x+1)^2 = x^2+2*x+1 => true
213
+
214
+ (x+1)*(x-1) = x^2-1 => true
215
+
216
+ cos(x)/(1+sin(x)) + (1+sin(x))/cos(x) = 2*sec(x) => true
217
+
218
+ 2*sin(x)*cos(x)=sin(2*x) => true
219
+
220
+ sqrt(sin(2*x))*cos(2*x) => (3^-1)*(sin((2*x))^(3*(2^-1)))
221
+
222
+ 2*x/(1+x^2) => log(abs((1+(x^2))))
223
+
224
+ sin(2*x+5)^2 => ((-1*(4^-1)*sin((10+(4*x))))+x)*(2^-1)
225
+
226
+ cos(2*x)^4 => ((4^-1)*x)+((64^-1)*sin((8*x)))+((8^-1)*sin((4*x)))+((8^-1)*x)
227
+
228
+ x*sqrt(x+2) => ((-1*(4^-1)*((2+x)^(2+(2^-1))))+(-2*((2+x)^(2+(2^-1))))+(5*((2+x)^(1+(2^-1)))*x)+((2^-1)*((2+x)^(1+(2^-1)))*x)+((8^-1)*((2+x)^(1+(2^-1)))*x))*((1+(2^-1))^-3)*((2+(2^-1))^-1)
229
+
230
+ sin(x)^4 => (-1*(4^-1)*sin((2*x)))+((32^-1)*sin((4*x)))+((4^-1)*x)+((8^-1)*x)
231
+
232
+ All tasks completed in 129.78 seconds
233
+ ```
234
+