mathai 0.3.1__py3-none-any.whl → 0.3.3__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 -3
- 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 +92 -95
- mathai/simplify.py +11 -7
- mathai/structure.py +1 -1
- mathai/tool.py +28 -1
- mathai/trig.py +55 -10
- {mathai-0.3.1.dist-info → mathai-0.3.3.dist-info}/METADATA +13 -13
- mathai-0.3.3.dist-info/RECORD +25 -0
- {mathai-0.3.1.dist-info → mathai-0.3.3.dist-info}/WHEEL +1 -1
- mathai-0.3.1.dist-info/RECORD +0 -25
- {mathai-0.3.1.dist-info → mathai-0.3.3.dist-info}/top_level.txt +0 -0
mathai/parser.py
CHANGED
@@ -59,7 +59,7 @@ grammar = """
|
|
59
59
|
| ESCAPED_STRING -> string
|
60
60
|
| CAPITAL_ID -> matrix
|
61
61
|
|
62
|
-
FUNC_NAME: "midpoint" | "forall" | "imply" | "exist" | "len" | "sum" | "angle" | "line" | "sum2" | "charge" | "electricfield" | "perm" | "point" | "equationrhs" | "transpose" | "equationlhs" | "equation" | "error" | "covariance" | "variance" | "expect" | "mag" | "rad" | "laplace" | "diverge" | "pdif" | "gradient" | "curl" | "point1" | "point2" | "dot" | "point3" | "line1" | "line2" | "line3" | "sin" | "circumcenter" | "eqtri" | "linesegment" | "cos" | "tan" | "log" | "sqrt" | "integrate" | "dif" | "abs" | "cosec" | "sec" | "cot" | "arctan" | "arcsin" | "arccos" | "log10"
|
62
|
+
FUNC_NAME: "midpoint" | "ref" | "subs" | "try" | "forall" | "imply" | "exist" | "len" | "sum" | "angle" | "line" | "sum2" | "charge" | "electricfield" | "perm" | "point" | "equationrhs" | "transpose" | "equationlhs" | "equation" | "error" | "covariance" | "variance" | "expect" | "mag" | "rad" | "laplace" | "diverge" | "pdif" | "gradient" | "curl" | "point1" | "point2" | "dot" | "point3" | "line1" | "line2" | "line3" | "sin" | "circumcenter" | "eqtri" | "linesegment" | "cos" | "tan" | "log" | "sqrt" | "integrate" | "dif" | "abs" | "cosec" | "sec" | "cot" | "arctan" | "arcsin" | "arccos" | "log10"
|
63
63
|
|
64
64
|
VARIABLE: /[a-z]/ | "nabla" | "pi" | "kc" | "hbar" | "em" | "ec" | "anot" | "false" | "true"
|
65
65
|
|
@@ -130,7 +130,7 @@ def parse(equation, funclist=None):
|
|
130
130
|
if tree_node.name == "pass_through":
|
131
131
|
return fxchange(tree_node.children[0])
|
132
132
|
return TreeNode(
|
133
|
-
"f_" + tree_node.name if tree_node.name in tmp3 + ["sqrt","imply","forall","exist","exclude","union","intersection","len","index","angle","charge","sum2","electricfield","line","point","sum","transpose","equationrhs","equationlhs","equation","covariance","variance","expect","error","laplace","dot","curl","pdif","diverge","gradient","rad","ge","le","gt","lt","eqtri","linesegment","midpoint","mag","point1","point2","point3","line1","line2","line3","log10","arcsin","arccos","arctan","list","cosec","sec","cot","equiv","or","not","and","circumcenter","eq","sub","add","sin","cos","tan","mul","integrate","dif","pow","div","log","abs"] else "d_" + tree_node.name,
|
133
|
+
"f_" + tree_node.name if tree_node.name in tmp3 + ["try", "ref", "sqrt","imply","forall","exist","exclude","union","intersection","len","index","angle","charge","sum2","electricfield","line","point","sum","transpose","equationrhs","equationlhs","equation","covariance","variance","expect","error","laplace","dot","curl","pdif","diverge","gradient","rad","ge","le","gt","lt","eqtri","linesegment","midpoint","mag","point1","point2","point3","line1","line2","line3","log10","arcsin","arccos","arctan","list","cosec","sec","cot","equiv","or","not","and","circumcenter","eq","sub","add","sin","cos","tan","mul","integrate","dif","pow","div","log","abs"] else "d_" + tree_node.name,
|
134
134
|
[fxchange(child) for child in tree_node.children]
|
135
135
|
)
|
136
136
|
|
mathai/printeq.py
CHANGED
@@ -24,7 +24,7 @@ def abstractexpr(eq):
|
|
24
24
|
return TreeNode(eq.name, [abstractexpr(child) for child in eq.children])
|
25
25
|
|
26
26
|
def printeq_str(eq):
|
27
|
-
return str(dowhile(
|
27
|
+
return str(dowhile(eq, abstractexpr))
|
28
28
|
|
29
29
|
def printeq(eq):
|
30
30
|
print(printeq_str(eq))
|
mathai/search.py
CHANGED
@@ -2,110 +2,107 @@ from mathai import *
|
|
2
2
|
import copy
|
3
3
|
from concurrent.futures import ThreadPoolExecutor, TimeoutError
|
4
4
|
|
5
|
-
|
6
|
-
|
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)
|
5
|
+
# Original expression
|
6
|
+
original_eq = simplify(parse("((P|~Q)&(P&~Q|P&R)&(~P&~R|~Q))<->P&~Q"))
|
45
7
|
|
46
|
-
|
47
|
-
|
8
|
+
# Simplification functions
|
9
|
+
lst = [logic1, logic3, logic2]
|
10
|
+
|
11
|
+
MAX_SMALL = 2
|
12
|
+
smallest_four = []
|
13
|
+
|
14
|
+
# Stack element: (current_expr, path_list)
|
15
|
+
stack = [(copy.deepcopy(original_eq), [copy.deepcopy(original_eq)])]
|
16
|
+
|
17
|
+
# Keep track of visited expressions to prevent cycles
|
18
|
+
visited = set()
|
19
|
+
|
20
|
+
# Boolean constants for immediate termination
|
21
|
+
TRUE_EXPR = tree_form("s_true")
|
22
|
+
FALSE_EXPR = tree_form("s_false")
|
23
|
+
|
24
|
+
found_boolean = False
|
25
|
+
boolean_path = None
|
26
|
+
boolean_expr = None
|
48
27
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
28
|
+
# Thread pool executor
|
29
|
+
executor = ThreadPoolExecutor(max_workers=3)
|
30
|
+
|
31
|
+
while stack and not found_boolean:
|
32
|
+
current_eq, path = stack.pop()
|
33
|
+
expr_str = str(current_eq)
|
34
|
+
|
35
|
+
if expr_str in visited:
|
36
|
+
continue
|
37
|
+
visited.add(expr_str)
|
38
|
+
|
39
|
+
# Thinking message
|
40
|
+
printeq(current_eq)
|
41
|
+
|
42
|
+
# Immediate termination for boolean constants
|
43
|
+
if current_eq == TRUE_EXPR or current_eq == FALSE_EXPR:
|
44
|
+
found_boolean = True
|
45
|
+
boolean_path = path
|
46
|
+
boolean_expr = current_eq
|
47
|
+
break
|
48
|
+
|
49
|
+
# Insert into smallest_four if qualifies
|
50
|
+
inserted = False
|
51
|
+
for j in range(len(smallest_four)):
|
52
|
+
if len(expr_str) < len(str(smallest_four[j][0])):
|
53
|
+
smallest_four.insert(j, (copy.deepcopy(current_eq), copy.deepcopy(path)))
|
54
|
+
inserted = True
|
54
55
|
break
|
56
|
+
if not inserted and len(smallest_four) < MAX_SMALL:
|
57
|
+
smallest_four.append((copy.deepcopy(current_eq), copy.deepcopy(path)))
|
58
|
+
if len(smallest_four) > MAX_SMALL:
|
59
|
+
smallest_four = smallest_four[:MAX_SMALL]
|
60
|
+
|
61
|
+
# First, try functions that reduce length
|
62
|
+
reduced_any = False
|
63
|
+
for fx in lst:
|
64
|
+
print(f"[Thinking] Executing {fx.__name__} on current expression:")
|
65
|
+
printeq(current_eq)
|
66
|
+
future = executor.submit(fx, current_eq)
|
67
|
+
try:
|
68
|
+
new_expr = future.result(timeout=5)
|
69
|
+
new_expr_str = str(new_expr)
|
70
|
+
# Only accept if shorter or equal
|
71
|
+
if len(new_expr_str) <= len(expr_str) and new_expr_str != expr_str:
|
72
|
+
reduced_any = True
|
73
|
+
stack.append((new_expr, path + [copy.deepcopy(new_expr)]))
|
74
|
+
except TimeoutError:
|
75
|
+
print(f"[Thinking] {fx.__name__} timed out, skipping.")
|
76
|
+
continue
|
55
77
|
|
56
|
-
|
57
|
-
|
58
|
-
for
|
59
|
-
|
60
|
-
smallest_four.insert(j, (copy.deepcopy(current_eq), copy.deepcopy(path)))
|
61
|
-
inserted = True
|
62
|
-
break
|
63
|
-
if not inserted and len(smallest_four) < max_small:
|
64
|
-
smallest_four.append((copy.deepcopy(current_eq), copy.deepcopy(path)))
|
65
|
-
if len(smallest_four) > max_small:
|
66
|
-
smallest_four = smallest_four[:max_small]
|
67
|
-
|
68
|
-
# Calculate adaptive timeout with cap
|
69
|
-
timeout = (base_timeout + time_per_char * len(expr_str)) * (1 + timeout_increase * consecutive_timeouts)
|
70
|
-
if timeout > max_timeout:
|
71
|
-
timeout = max_timeout
|
72
|
-
|
73
|
-
# Try functions that reduce length first
|
74
|
-
reduced_any = False
|
75
|
-
for fx in functions:
|
76
|
-
print(f"[Thinking] Executing {fx.__name__} on current expression (timeout={timeout:.2f}s):")
|
78
|
+
# If no reducing function produced a shorter or equal expression, try a “growing” function
|
79
|
+
if not reduced_any:
|
80
|
+
for fx in lst:
|
81
|
+
print(f"[Thinking] Trying growing {fx.__name__} on current expression:")
|
77
82
|
printeq(current_eq)
|
78
83
|
future = executor.submit(fx, current_eq)
|
79
84
|
try:
|
80
|
-
new_expr = future.result(timeout=
|
85
|
+
new_expr = future.result(timeout=5)
|
81
86
|
new_expr_str = str(new_expr)
|
82
|
-
if
|
83
|
-
reduced_any = True
|
87
|
+
if new_expr_str != expr_str:
|
84
88
|
stack.append((new_expr, path + [copy.deepcopy(new_expr)]))
|
85
|
-
|
89
|
+
break # only take one growing function
|
86
90
|
except TimeoutError:
|
87
|
-
print(f"[Thinking] {fx.__name__} timed out, skipping.")
|
88
|
-
consecutive_timeouts += 1
|
91
|
+
print(f"[Thinking] {fx.__name__} (growing) timed out, skipping.")
|
89
92
|
continue
|
90
93
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
consecutive_timeouts += 1
|
107
|
-
continue
|
108
|
-
|
109
|
-
executor.shutdown(wait=True)
|
110
|
-
|
111
|
-
return found_boolean, boolean_path, smallest_four
|
94
|
+
# Shutdown executor
|
95
|
+
executor.shutdown(wait=True)
|
96
|
+
|
97
|
+
# Display final results
|
98
|
+
if found_boolean:
|
99
|
+
print("\nBoolean constant found! Full path to solution:\n")
|
100
|
+
for step in boolean_path:
|
101
|
+
printeq(step)
|
102
|
+
else:
|
103
|
+
print("\nDFS completed. Two smallest expressions with steps:\n")
|
104
|
+
for expr, path in smallest_four:
|
105
|
+
print("Path to final expression:")
|
106
|
+
for step in path:
|
107
|
+
printeq(step)
|
108
|
+
print("-"*50)
|
mathai/simplify.py
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
import math
|
2
2
|
from .base import *
|
3
3
|
from fractions import Fraction
|
4
|
-
|
4
|
+
nolog = False
|
5
|
+
def set_nolog(val):
|
6
|
+
global nolog
|
7
|
+
nolog = val
|
5
8
|
def _solve(eq):
|
6
9
|
def solve_add(eq):
|
7
10
|
def multiplied(eq):
|
@@ -269,12 +272,13 @@ def simplify(eq):
|
|
269
272
|
out = perfect_nth_root_value(n, r)
|
270
273
|
if out is not None:
|
271
274
|
return pp( tree_form("d_"+str(out)), f)
|
272
|
-
if
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
275
|
+
if not nolog:
|
276
|
+
if eq.name == "f_mul" and len(eq.children)== 2:
|
277
|
+
for i in range(2):
|
278
|
+
if eq.children[i].name[:2] == "d_" and eq.children[1-i].name == "f_log":
|
279
|
+
return (eq.children[1-i].children[0]**eq.children[i]).fx("log")
|
280
|
+
if eq.name == "f_pow" and eq.children[0] == tree_form("s_e") and eq.children[1].name == "f_log":
|
281
|
+
return eq.children[1].children[0]
|
278
282
|
if eq.name == "f_pow" and eq.children[0] == tree_form("d_1"):
|
279
283
|
eq = tree_form("d_1")
|
280
284
|
if eq.name == "f_pow" and eq.children[0] == tree_form("d_0"):
|
mathai/structure.py
CHANGED
@@ -90,7 +90,7 @@ def transform_formula(equation, wrt, formula_list, var, expr):
|
|
90
90
|
if var != "":
|
91
91
|
p = True
|
92
92
|
try:
|
93
|
-
out = structure(
|
93
|
+
out = structure(equation.copy_tree(), copy.deepcopy(item[0]), copy.deepcopy(item[1]), p)
|
94
94
|
if out is not None:
|
95
95
|
out = simplify(out)
|
96
96
|
|
mathai/tool.py
CHANGED
@@ -4,12 +4,39 @@ from .simplify import simplify
|
|
4
4
|
from .base import *
|
5
5
|
import math
|
6
6
|
|
7
|
+
def enclose_const(eq):
|
8
|
+
def req(eq, dic):
|
9
|
+
for key in dic.keys():
|
10
|
+
eq = replace(eq, dic[key], key)
|
11
|
+
return eq
|
12
|
+
alloclst = []
|
13
|
+
for i in range(0,26):
|
14
|
+
if "v_"+str(i) not in vlist(eq):
|
15
|
+
alloclst.append(tree_form("v_"+str(i)))
|
16
|
+
dic = {}
|
17
|
+
def helper(eq):
|
18
|
+
nonlocal alloclst, dic
|
19
|
+
if frac(eq) is not None:
|
20
|
+
return eq
|
21
|
+
|
22
|
+
if "v_" not in str_form(eq):
|
23
|
+
if eq not in dic.keys():
|
24
|
+
n = alloclst.pop(0)
|
25
|
+
dic[eq] = n
|
26
|
+
return dic[eq]
|
27
|
+
else:
|
28
|
+
if eq.name == "f_pow":
|
29
|
+
return TreeNode(eq.name, [helper(eq.children[0]), eq.children[1]])
|
30
|
+
return TreeNode(eq.name, [helper(child) for child in eq.children])
|
31
|
+
eq= helper(eq)
|
32
|
+
return eq, lambda x: req(x, dic)
|
33
|
+
|
7
34
|
def poly(eq, to_compute):
|
8
35
|
def substitute_val(eq, val, var="v_0"):
|
9
36
|
eq = replace(eq, tree_form(var), tree_form("d_"+str(val)))
|
10
37
|
return eq
|
11
38
|
def inv(eq):
|
12
|
-
if eq.name == "f_pow" and eq.children[1] == tree_form("d_-1"):
|
39
|
+
if eq.name == "f_pow" and "v_" in str_form(eq.children[0]) and eq.children[1] == tree_form("d_-1"):
|
13
40
|
return False
|
14
41
|
if eq.name == "f_abs":
|
15
42
|
return False
|
mathai/trig.py
CHANGED
@@ -65,6 +65,8 @@ def trig0(eq):
|
|
65
65
|
if eq.children[0].name == "d_1":
|
66
66
|
return tree_form("d_0")
|
67
67
|
if eq.name=="f_tan":
|
68
|
+
if eq.children[0].name == "f_arctan":
|
69
|
+
return eq.children[0].children[0]
|
68
70
|
return eq.children[0].fx("sin")/eq.children[0].fx("cos")
|
69
71
|
if eq.name == "f_sec":
|
70
72
|
return eq.children[0].fx("cos")**-1
|
@@ -72,14 +74,20 @@ def trig0(eq):
|
|
72
74
|
return eq.children[0].fx("sin")**-1
|
73
75
|
if eq.name == "f_cot":
|
74
76
|
return eq.children[0].fx("cos")/eq.children[0].fx("sin")
|
77
|
+
|
75
78
|
if eq.name == "f_sin":
|
79
|
+
if eq.children[0].name == "f_arcsin":
|
80
|
+
return eq.children[0].children[0]
|
76
81
|
lst = factor_generation(eq.children[0])
|
77
82
|
if any(isneg(item) for item in lst):
|
78
83
|
return -(eq.children[0]*-1).fx("sin")
|
79
84
|
out=single_pi(lst)
|
80
85
|
if out is not None:
|
81
86
|
return trig_sin_table[tuple(out)]
|
87
|
+
|
82
88
|
if eq.name == "f_cos":
|
89
|
+
if eq.children[0].name == "f_arccos":
|
90
|
+
return eq.children[0].children[0]
|
83
91
|
lst = factor_generation(eq.children[0])
|
84
92
|
if any(isneg(item) for item in lst):
|
85
93
|
return (eq.children[0]*-1).fx("cos")
|
@@ -122,11 +130,13 @@ def trig_formula_init():
|
|
122
130
|
(f"1/cos(B)^2", f"1/(1-sin(B)^2)"),\
|
123
131
|
(f"cos(arcsin(B))", f"sqrt(1-B^2)"),\
|
124
132
|
(f"sin(arccos(B))", f"sqrt(1-B^2)"),\
|
125
|
-
(f"arccos(B)", f"pi/2-arcsin(B)")
|
133
|
+
(f"arccos(B)", f"pi/2-arcsin(B)"),\
|
134
|
+
(f"sin(arctan(B))", f"x/sqrt(1+x^2)"),\
|
135
|
+
(f"cos(arctan(B))", f"1/sqrt(1+x^2)")]
|
126
136
|
formula_list = [[simplify(parse(y)) for y in x] for x in formula_list]
|
127
137
|
expr = [[parse("A"), parse("1")], [parse("B")], [parse("C"), parse("1")], [parse("D")]]
|
128
138
|
return [formula_list, var, expr]
|
129
|
-
formula_gen4 = trig_formula_init()
|
139
|
+
#formula_gen4 = trig_formula_init()
|
130
140
|
def trig3(eq):
|
131
141
|
def iseven(eq):
|
132
142
|
if eq.name[:2] != "d_":
|
@@ -145,15 +155,50 @@ def trig3(eq):
|
|
145
155
|
eq = (eq.children[0]/2).fx("cos")**2-(eq.children[0]/2).fx("sin")**2
|
146
156
|
eq = expand(simplify(eq))
|
147
157
|
return TreeNode(eq.name, [trig3(child) for child in eq.children])
|
148
|
-
def
|
158
|
+
def noneg_pow(eq):
|
159
|
+
if eq.name == "f_pow" and frac(eq.children[1]) is not None and frac(eq.children[1])<0:
|
160
|
+
return (eq.children[0]**(simplify(-eq.children[1])))**-1
|
161
|
+
return TreeNode(eq.name, [noneg_pow(child) for child in eq.children])
|
162
|
+
def _trig1(equation):
|
149
163
|
equation = product_to_sum(equation)
|
150
|
-
return TreeNode(equation.name, [
|
151
|
-
def
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
164
|
+
return TreeNode(equation.name, [_trig1(child) for child in equation.children])
|
165
|
+
def trig1(eq):
|
166
|
+
return simplify(_trig1(noneg_pow(eq)))
|
167
|
+
|
168
|
+
def trig4(eq, numer=True):
|
169
|
+
if eq.name == "f_sin":
|
170
|
+
if eq.children[0].name == "f_add" and len(eq.children[0].children)>=2:
|
171
|
+
r = len(eq.children[0].children)%2
|
172
|
+
a, b = eq.children[0].children[:(len(eq.children[0].children)-r)/2], eq.children[0].children[(len(eq.children[0].children)-r)/2:]
|
173
|
+
return a.fx("sin")*b.fx("cos") + a.fx("cos")*b.fx("sin")
|
174
|
+
if eq.children[0].name == "f_arccos":
|
175
|
+
a = eq.children[0].children[0]
|
176
|
+
return (1-a**2)**(tree_form("d_2")**-1)
|
177
|
+
if eq.children[0].name == "f_arctan":
|
178
|
+
a = eq.children[0].children[0]
|
179
|
+
return a/(1+a**2)**(tree_form("d_2")**-1)
|
180
|
+
if eq.name == "f_pow" and numer:
|
181
|
+
if eq.children[0].name == "f_cos":
|
182
|
+
a = eq.children[0].children[0]
|
183
|
+
if frac(eq.children[1]) == 2:
|
184
|
+
return 1 - a.fx("sin")**2
|
185
|
+
if eq.children[0].name == "f_sin":
|
186
|
+
a = eq.children[0].children[0]
|
187
|
+
if frac(eq.children[1]) == 2:
|
188
|
+
return 1 - a.fx("cos")**2
|
189
|
+
if eq.name == "f_cos":
|
190
|
+
if eq.children[0].name == "f_add" and len(eq.children[0].children)>=2:
|
191
|
+
r = len(eq.children[0].children)%2
|
192
|
+
a, b = eq.children[0].children[:(len(eq.children[0].children)-r)/2], eq.children[0].children[(len(eq.children[0].children)-r)/2:]
|
193
|
+
return a.fx("cos")*b.fx("cos") - a.fx("sin")*b.fx("sin")
|
194
|
+
if eq.children[0].name == "f_arcsin":
|
195
|
+
a = eq.children[0].children[0]
|
196
|
+
return (1-a**2)**(tree_form("d_2")**-1)
|
197
|
+
if eq.children[0].name == "f_arctan":
|
198
|
+
a = eq.children[0].children[0]
|
199
|
+
return tree_form("d_1")/(1+a**2)**(tree_form("d_2")**-1)
|
200
|
+
|
201
|
+
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])
|
157
202
|
def trig2(eq):
|
158
203
|
if eq.name == "f_add":
|
159
204
|
for item in itertools.combinations(range(len(eq.children)), 2):
|
@@ -1,6 +1,6 @@
|
|
1
|
-
Metadata-Version: 2.
|
1
|
+
Metadata-Version: 2.4
|
2
2
|
Name: mathai
|
3
|
-
Version: 0.3.
|
3
|
+
Version: 0.3.3
|
4
4
|
Summary: Mathematics solving Ai tailored to NCERT
|
5
5
|
Home-page: https://github.com/infinity390/mathai4
|
6
6
|
Author: educated indians are having a low iq and are good for nothing
|
@@ -69,22 +69,22 @@ f_add
|
|
69
69
|
|
70
70
|
**Variables** (start with a `v_` prefix):
|
71
71
|
|
72
|
-
- `v_0`
|
73
|
-
- `v_1`
|
74
|
-
- `v_2`
|
75
|
-
- `v_3`
|
72
|
+
- `v_0` -> x
|
73
|
+
- `v_1` -> y
|
74
|
+
- `v_2` -> z
|
75
|
+
- `v_3` -> a
|
76
76
|
|
77
77
|
**Numbers** (start with `d_` prefix; only integers):
|
78
78
|
|
79
|
-
- `d_-1`
|
80
|
-
- `d_0`
|
81
|
-
- `d_1`
|
82
|
-
- `d_2`
|
79
|
+
- `d_-1` -> -1
|
80
|
+
- `d_0` -> 0
|
81
|
+
- `d_1` -> 1
|
82
|
+
- `d_2` -> 2
|
83
83
|
|
84
84
|
#### Branch Nodes
|
85
|
-
- `f_add`
|
86
|
-
- `f_mul`
|
87
|
-
- `f_pow`
|
85
|
+
- `f_add` -> addition
|
86
|
+
- `f_mul` -> multiplication
|
87
|
+
- `f_pow` -> power
|
88
88
|
|
89
89
|
### parse
|
90
90
|
Takes a math equation string and outputs a `TreeNode` object.
|
@@ -0,0 +1,25 @@
|
|
1
|
+
mathai/__init__.py,sha256=GsDxDy6iWjoJ7CJty2nzE4Jx03mZkHFQW6hkmPJHkPE,1217
|
2
|
+
mathai/apart.py,sha256=Fhl-OHZzPGIOj8YFyGQddjuh-2HV7uVDhkIzQ-YoMO0,3492
|
3
|
+
mathai/base.py,sha256=x4Rjgz5mVblclsycKtDJjSudFpyIBWSEUX83_120BZY,12587
|
4
|
+
mathai/console.py,sha256=Sn58iwYE79MLEh67s8X3q6vZjw6g7f9XM1T8_dBBR2o,3048
|
5
|
+
mathai/diff.py,sha256=YUBpRsz0qmBkq5vGxeGnvR4nMKjdOQiIXlNMxpij2ns,3051
|
6
|
+
mathai/expand.py,sha256=SnBltkpIENMGkP0AYmbMlSc4H-CF5RslO2PcBEkn1BQ,3359
|
7
|
+
mathai/factor.py,sha256=NPXxET52TacNExuvw6p1jbC6g3wY6_VOCdlGlexXZio,5916
|
8
|
+
mathai/fraction.py,sha256=Q2ztsh5Bpz6YhML2QU0tfufbAs0Q6J319AhlzKephIY,4396
|
9
|
+
mathai/integrate.py,sha256=85qM7nvALtYjVMp17Tx5Kvevdz0d1UPDKQBBTnDqgrs,14828
|
10
|
+
mathai/inverse.py,sha256=QCvDrzKquWsZv-BDAzZd9HnU0c3gZvcc44UztHVO5LQ,2919
|
11
|
+
mathai/limit.py,sha256=RA8YAehgYCGVWv9qBc8uQ34BQ9mFthWl2OrVTwcHl2g,4920
|
12
|
+
mathai/linear.py,sha256=wyiLpIxRDmD96xXktkgvc5gegIB3zblLB1EuV3TFdmU,5474
|
13
|
+
mathai/logic.py,sha256=UvHzRmKcO9AD51tRzHmpNSEhgW5gmaf4XPaQKFjGfC4,9653
|
14
|
+
mathai/parser.py,sha256=f7bemieFmp0sbup1NlraMLvZDVFvqKGFknEVtlFRMVk,6979
|
15
|
+
mathai/printeq.py,sha256=gIes-pstFOa6FcnpVIVvkjVKuWdsVdo11LlEnmHhakU,1303
|
16
|
+
mathai/search.py,sha256=BmUKacCpptIoyUObB0hknAbgFs8EPQXXXXYBXT40Luc,3672
|
17
|
+
mathai/simplify.py,sha256=F37h-Z_rW35uVgx0G86vQErU2Ac6ZiTBN9KcC3RzDkg,15156
|
18
|
+
mathai/structure.py,sha256=4Ww2IAx62RcQSO7_17TZES-DjMWBpcFQtL939FBIHwY,4103
|
19
|
+
mathai/tool.py,sha256=UyccamiJy_CkFPakfufyPzdhtlEO6v2D7qwbXQ9V7Rg,2000
|
20
|
+
mathai/trig.py,sha256=5P0RNS4eetNds2l-wyA4BAKqJdFIUws_8RGS_dH7gp8,9348
|
21
|
+
mathai/univariate_inequality.py,sha256=_r-kkiS4Hr-jRN7f-EL_E4svAMFWJP1Ea50HJKKbjfk,14778
|
22
|
+
mathai-0.3.3.dist-info/METADATA,sha256=mlSi3WdczR0cSSetNJUPeJE7v9EAHJY-wTjKFbvRtsg,7021
|
23
|
+
mathai-0.3.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
24
|
+
mathai-0.3.3.dist-info/top_level.txt,sha256=ROP4l3OhGYw3ihkQGASr18xM9GsK4z3_6whV5AyXLwE,7
|
25
|
+
mathai-0.3.3.dist-info/RECORD,,
|
mathai-0.3.1.dist-info/RECORD
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
mathai/__init__.py,sha256=OrSjLAAeRQrr4eHcOZFtU56gRIjukNKnsEaDnYiZjrk,649
|
2
|
-
mathai/apart.py,sha256=P0B21wHUFitc5RGbNJlwSeOdseOMcav4I7teFNcZmFA,3130
|
3
|
-
mathai/base.py,sha256=l8p8nkCuBDUISI5whtxIuZnOHyFn7F29mLXeKtWWWFQ,12392
|
4
|
-
mathai/console.py,sha256=FsEMqDsgFeBSUiPCm9sfReZp56NSyoFVldqmVwvW4lg,3119
|
5
|
-
mathai/diff.py,sha256=Dvc-tuiW8jLncybjGqHs2WTg2vpMEdRJqUoIdnDj4sk,2879
|
6
|
-
mathai/expand.py,sha256=IqkxHS8lqbk0PZqz2y_IbRMSP0GExV6fneYwVEWQ9XM,1831
|
7
|
-
mathai/factor.py,sha256=1-Bxl3MX6P1mYM-CX0hRskCrTZWHFdaUL-V1OqX48hY,5316
|
8
|
-
mathai/fraction.py,sha256=KGldpi8mndp5cvp6qbN7ZdMZyVmK6popa3AwkWmHXl4,2573
|
9
|
-
mathai/integrate.py,sha256=I_9hIi3m9eoYjYwBbp_Bu1VXVRiXbUqYcJfL3cpLBPk,12652
|
10
|
-
mathai/inverse.py,sha256=QCvDrzKquWsZv-BDAzZd9HnU0c3gZvcc44UztHVO5LQ,2919
|
11
|
-
mathai/limit.py,sha256=RA8YAehgYCGVWv9qBc8uQ34BQ9mFthWl2OrVTwcHl2g,4920
|
12
|
-
mathai/linear.py,sha256=eVnDbJYC1TWwg4J7ovBKsaHYlSoDmXk5jQpsqwtVPyI,5481
|
13
|
-
mathai/logic.py,sha256=UvHzRmKcO9AD51tRzHmpNSEhgW5gmaf4XPaQKFjGfC4,9653
|
14
|
-
mathai/parser.py,sha256=aDaF1-tqJHZI4znAcHUSEbz7pPVnvHItOMZ2lp7Vxww,6940
|
15
|
-
mathai/printeq.py,sha256=JTB0_RBcgt1yFviqlHtXGXuSXcpKrxzSxj5WHkOHon4,1318
|
16
|
-
mathai/search.py,sha256=7YH39WN3pZsGdMfA-dXUSZalc0Orz3kI9fDLaegvV10,4617
|
17
|
-
mathai/simplify.py,sha256=NymYVFocnpY8T-LJkyvQPddoF5avUgm3T-JzzRC1R3w,15040
|
18
|
-
mathai/structure.py,sha256=Hgw2y43dwasa6G8z6OS2lmReh7JHwlChGn-FUdEaWY8,4106
|
19
|
-
mathai/tool.py,sha256=87N5Ya7DmHdFOobTYDAjPHNWZuMzMIDjYN0ZtlHjxqE,1099
|
20
|
-
mathai/trig.py,sha256=ywu89MJfAB81JCzsVPBLpGGv8od0LhLn5cgDtLtYwmw,6897
|
21
|
-
mathai/univariate_inequality.py,sha256=_r-kkiS4Hr-jRN7f-EL_E4svAMFWJP1Ea50HJKKbjfk,14778
|
22
|
-
mathai-0.3.1.dist-info/METADATA,sha256=hsbiZmYg6R_9C2NVmr7rh0g03RuOArr-CZ9r0WJQB80,7087
|
23
|
-
mathai-0.3.1.dist-info/WHEEL,sha256=jB7zZ3N9hIM9adW7qlTAyycLYW9npaWKLRzaoVcLKcM,91
|
24
|
-
mathai-0.3.1.dist-info/top_level.txt,sha256=ROP4l3OhGYw3ihkQGASr18xM9GsK4z3_6whV5AyXLwE,7
|
25
|
-
mathai-0.3.1.dist-info/RECORD,,
|
File without changes
|