mathai 0.6.9__tar.gz → 0.7.1__tar.gz
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-0.7.1/PKG-INFO +239 -0
- mathai-0.7.1/README.md +222 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/base.py +5 -3
- mathai-0.7.1/mathai/expand.py +175 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/matrix.py +1 -1
- {mathai-0.6.9 → mathai-0.7.1}/mathai/parser.py +1 -1
- mathai-0.7.1/mathai.egg-info/PKG-INFO +239 -0
- {mathai-0.6.9 → mathai-0.7.1}/setup.py +1 -1
- mathai-0.6.9/PKG-INFO +0 -234
- mathai-0.6.9/README.md +0 -217
- mathai-0.6.9/mathai/expand.py +0 -95
- mathai-0.6.9/mathai.egg-info/PKG-INFO +0 -234
- {mathai-0.6.9 → mathai-0.7.1}/mathai/__init__.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/apart.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/bivariate_inequality.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/console.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/diff.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/factor.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/fraction.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/integrate.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/inverse.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/limit.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/linear.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/logic.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/ode.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/parsetab.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/printeq.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/simplify.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/structure.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/tool.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/trig.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai/univariate_inequality.py +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai.egg-info/SOURCES.txt +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai.egg-info/dependency_links.txt +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai.egg-info/requires.txt +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/mathai.egg-info/top_level.txt +0 -0
- {mathai-0.6.9 → mathai-0.7.1}/setup.cfg +0 -0
mathai-0.7.1/PKG-INFO
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: mathai
|
|
3
|
+
Version: 0.7.1
|
|
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 Summary Of How Computer "Solves" Math
|
|
32
|
+
Math equations are a tree data structure (`TreeNode` class).
|
|
33
|
+
We can manipulate the math equations using various algorithms (functions provided by the `mathai` library).
|
|
34
|
+
We first parse the math equation strings to get the tree data structure (`parse` function in `mathai`).
|
|
35
|
+
|
|
36
|
+
## The Library
|
|
37
|
+
Import the library by doing:
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
from mathai import *
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### str_form
|
|
44
|
+
It is the string representation of a `TreeNode` math equation.
|
|
45
|
+
|
|
46
|
+
#### Example
|
|
47
|
+
```text
|
|
48
|
+
(cos(x)^2)+(sin(x)^2)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Is represented internally as:
|
|
52
|
+
|
|
53
|
+
```text
|
|
54
|
+
f_add
|
|
55
|
+
f_pow
|
|
56
|
+
f_cos
|
|
57
|
+
v_0
|
|
58
|
+
d_2
|
|
59
|
+
f_pow
|
|
60
|
+
f_sin
|
|
61
|
+
v_0
|
|
62
|
+
d_2
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
#### Leaf Nodes
|
|
66
|
+
|
|
67
|
+
**Variables** (start with a `v_` prefix):
|
|
68
|
+
|
|
69
|
+
- `v_0` -> x
|
|
70
|
+
- `v_1` -> y
|
|
71
|
+
- `v_2` -> z
|
|
72
|
+
- `v_3` -> a
|
|
73
|
+
|
|
74
|
+
**Numbers** (start with `d_` prefix; only integers):
|
|
75
|
+
|
|
76
|
+
- `d_-1` -> -1
|
|
77
|
+
- `d_0` -> 0
|
|
78
|
+
- `d_1` -> 1
|
|
79
|
+
- `d_2` -> 2
|
|
80
|
+
|
|
81
|
+
#### Branch Nodes
|
|
82
|
+
- `f_add` -> addition
|
|
83
|
+
- `f_mul` -> multiplication
|
|
84
|
+
- `f_pow` -> power
|
|
85
|
+
|
|
86
|
+
### parse
|
|
87
|
+
Takes a math equation string and outputs a `TreeNode` object.
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
from mathai import *
|
|
91
|
+
|
|
92
|
+
equation = parse("sin(x)^2+cos(x)^2")
|
|
93
|
+
print(equation)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### Output
|
|
97
|
+
```text
|
|
98
|
+
(cos(x)^2)+(sin(x)^2)
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### solve, simplify
|
|
102
|
+
It simplifies and cleans up a given math equation.
|
|
103
|
+
|
|
104
|
+
```python
|
|
105
|
+
from mathai import *
|
|
106
|
+
|
|
107
|
+
equation = simplify(parse("(x+x+x+x-1-1-1-1)*(4*x-4)*sin(sin(x+x+x)*sin(3*x))"))
|
|
108
|
+
printeq(equation)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
#### Output
|
|
112
|
+
```text
|
|
113
|
+
((-4+(4*x))^2)*sin((sin((3*x))^2))
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Incomplete Documentation, Will be updated and completed later on
|
|
117
|
+
|
|
118
|
+
### Demonstrations
|
|
119
|
+
|
|
120
|
+
#### Example Demonstration 1
|
|
121
|
+
```python
|
|
122
|
+
from mathai import *
|
|
123
|
+
question_list_from_lecture = [
|
|
124
|
+
"2*x/(2*x^2 + 5*x + 2) > 1/(x + 1)",
|
|
125
|
+
"(x + 2)*(x + 3)/((x - 2)*(x - 3)) <= 1",
|
|
126
|
+
"(5*x - 1) < (x + 1)^2 & (x + 1)^2 < 7*x - 3",
|
|
127
|
+
"(2*x - 1)/(2*x^3 + 3*x^2 + x) > 0",
|
|
128
|
+
"abs(x + 5)*x + 2*abs(x + 7) - 2 = 0",
|
|
129
|
+
"x*abs(x) - 5*abs(x + 2) + 6 = 0",
|
|
130
|
+
"x^2 - abs(x + 2) + x > 0",
|
|
131
|
+
"abs(abs(x - 2) - 3) <= 2",
|
|
132
|
+
"abs(3*x - 5) + abs(8 - x) = abs(3 + 2*x)",
|
|
133
|
+
"abs(x^2 + 5*x + 9) < abs(x^2 + 2*x + 2) + abs(3*x + 7)"
|
|
134
|
+
]
|
|
135
|
+
|
|
136
|
+
for item in question_list_from_lecture:
|
|
137
|
+
eq = simplify(parse(item))
|
|
138
|
+
eq = dowhile(eq, absolute)
|
|
139
|
+
eq = simplify(factor1(fraction(eq)))
|
|
140
|
+
eq = prepare(eq)
|
|
141
|
+
eq = factor2(eq)
|
|
142
|
+
c = wavycurvy(eq & domain(eq)).fix()
|
|
143
|
+
print(c)
|
|
144
|
+
```
|
|
145
|
+
#### Output
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
(-2,-1)U(-(2/3),-(1/2))
|
|
149
|
+
(-inf,0)U(2,3)U{0}
|
|
150
|
+
(2,4)
|
|
151
|
+
(-inf,-1)U(-(1/2),0)U(1/2,+inf)
|
|
152
|
+
{-4,-3,-(3/2)-(sqrt(57)/2)}
|
|
153
|
+
{-1,(5/2)-(sqrt(89)/2),(5/2)+(sqrt(41)/2)}
|
|
154
|
+
(-inf,-sqrt(2))U((2*sqrt(2))/2,+inf)
|
|
155
|
+
(-3,1)U(3,7)U{1,-3,7,3}
|
|
156
|
+
(5/3,8)U{5/3,8}
|
|
157
|
+
(-inf,-(7/3))
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
#### Example Demonstration 2
|
|
161
|
+
```python
|
|
162
|
+
from mathai import *
|
|
163
|
+
def nested_func(eq_node):
|
|
164
|
+
eq_node = fraction(eq_node)
|
|
165
|
+
eq_node = simplify(eq_node)
|
|
166
|
+
eq_node = trig1(eq_node)
|
|
167
|
+
eq_node = trig0(eq_node)
|
|
168
|
+
return eq_node
|
|
169
|
+
for item in ["(cosec(x)-cot(x))^2=(1-cos(x))/(1+cos(x))", "cos(x)/(1+sin(x)) + (1+sin(x))/cos(x) = 2*sec(x)",\
|
|
170
|
+
"tan(x)/(1-cot(x)) + cot(x)/(1-tan(x)) = 1 + sec(x)*cosec(x)", "(1+sec(x))/sec(x) = sin(x)^2/(1-cos(x))",\
|
|
171
|
+
"(cos(x)-sin(x)+1)/(cos(x)+sin(x)-1) = cosec(x)+cot(x)"]:
|
|
172
|
+
eq = logic0(dowhile(parse(item), nested_func))
|
|
173
|
+
print(eq)
|
|
174
|
+
```
|
|
175
|
+
#### Output
|
|
176
|
+
|
|
177
|
+
```
|
|
178
|
+
true
|
|
179
|
+
true
|
|
180
|
+
true
|
|
181
|
+
true
|
|
182
|
+
true
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### Example Demonstration 3
|
|
186
|
+
```python
|
|
187
|
+
from mathai import *
|
|
188
|
+
|
|
189
|
+
eq = simplify(parse("integrate(2*x/(x^2+1),x)"))
|
|
190
|
+
eq = integrate_const(eq)
|
|
191
|
+
eq = integrate_fraction(eq)
|
|
192
|
+
print(simplify(fraction(simplify(eq))))
|
|
193
|
+
|
|
194
|
+
eq = simplify(parse("integrate(sin(cos(x))*sin(x),x)"))
|
|
195
|
+
eq = integrate_subs(eq)
|
|
196
|
+
eq = integrate_const(eq)
|
|
197
|
+
eq = integrate_formula(eq)
|
|
198
|
+
eq = integrate_clean(eq)
|
|
199
|
+
print(simplify(eq))
|
|
200
|
+
|
|
201
|
+
eq = simplify(parse("integrate(x*sqrt(x+2),x)"))
|
|
202
|
+
eq = integrate_subs(eq)
|
|
203
|
+
eq = integrate_const(eq)
|
|
204
|
+
eq = integrate_formula(eq)
|
|
205
|
+
eq = expand(eq)
|
|
206
|
+
eq = integrate_const(eq)
|
|
207
|
+
eq = integrate_summation(eq)
|
|
208
|
+
eq = simplify(eq)
|
|
209
|
+
eq = integrate_const(eq)
|
|
210
|
+
eq = integrate_formula(eq)
|
|
211
|
+
eq = integrate_clean(eq)
|
|
212
|
+
print(simplify(fraction(simplify(eq))))
|
|
213
|
+
|
|
214
|
+
eq = simplify(parse("integrate(x/(e^(x^2)),x)"))
|
|
215
|
+
eq = integrate_subs(eq)
|
|
216
|
+
eq = integrate_const(eq)
|
|
217
|
+
eq = integrate_formula(eq)
|
|
218
|
+
eq = simplify(eq)
|
|
219
|
+
eq = integrate_formula(eq)
|
|
220
|
+
eq = integrate_clean(eq)
|
|
221
|
+
print(simplify(eq))
|
|
222
|
+
|
|
223
|
+
eq = fraction(trig0(trig1(simplify(parse("integrate(sin(x)^4,x)")))))
|
|
224
|
+
eq = integrate_const(eq)
|
|
225
|
+
eq = integrate_summation(eq)
|
|
226
|
+
eq = integrate_formula(eq)
|
|
227
|
+
eq = integrate_const(eq)
|
|
228
|
+
eq = integrate_formula(eq)
|
|
229
|
+
print(factor0(simplify(fraction(simplify(eq)))))
|
|
230
|
+
```
|
|
231
|
+
#### Output
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
log(abs((1+(x^2))))
|
|
235
|
+
cos(cos(x))
|
|
236
|
+
((6*((2+x)^(5/2)))-(20*((2+x)^(3/2))))/15
|
|
237
|
+
-((e^-(x^2))/2)
|
|
238
|
+
-(((8*sin((2*x)))-(12*x)-sin((4*x)))/32)
|
|
239
|
+
```
|
mathai-0.7.1/README.md
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Math AI Documentation
|
|
2
|
+
## Source
|
|
3
|
+
Github repository of the code
|
|
4
|
+
https://github.com/infinity390/mathai4
|
|
5
|
+
|
|
6
|
+
## Philosophy
|
|
7
|
+
I think it is a big realization in computer science and programming to realize that computers can solve mathematics.
|
|
8
|
+
This understanding should be made mainstream. It can help transform education, mathematical research, and computation of mathematical equations for work.
|
|
9
|
+
|
|
10
|
+
## Societal Implications Of Such A Computer Program And The Author's Comment On Universities Of India
|
|
11
|
+
I think mathematics is valued by society because of education. Schools and universities teach them.
|
|
12
|
+
So this kind of software, if made mainstream, could bring real change.
|
|
13
|
+
|
|
14
|
+
## The Summary Of How Computer "Solves" Math
|
|
15
|
+
Math equations are a tree data structure (`TreeNode` class).
|
|
16
|
+
We can manipulate the math equations using various algorithms (functions provided by the `mathai` library).
|
|
17
|
+
We first parse the math equation strings to get the tree data structure (`parse` function in `mathai`).
|
|
18
|
+
|
|
19
|
+
## The Library
|
|
20
|
+
Import the library by doing:
|
|
21
|
+
|
|
22
|
+
```python
|
|
23
|
+
from mathai import *
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### str_form
|
|
27
|
+
It is the string representation of a `TreeNode` math equation.
|
|
28
|
+
|
|
29
|
+
#### Example
|
|
30
|
+
```text
|
|
31
|
+
(cos(x)^2)+(sin(x)^2)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Is represented internally as:
|
|
35
|
+
|
|
36
|
+
```text
|
|
37
|
+
f_add
|
|
38
|
+
f_pow
|
|
39
|
+
f_cos
|
|
40
|
+
v_0
|
|
41
|
+
d_2
|
|
42
|
+
f_pow
|
|
43
|
+
f_sin
|
|
44
|
+
v_0
|
|
45
|
+
d_2
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Leaf Nodes
|
|
49
|
+
|
|
50
|
+
**Variables** (start with a `v_` prefix):
|
|
51
|
+
|
|
52
|
+
- `v_0` -> x
|
|
53
|
+
- `v_1` -> y
|
|
54
|
+
- `v_2` -> z
|
|
55
|
+
- `v_3` -> a
|
|
56
|
+
|
|
57
|
+
**Numbers** (start with `d_` prefix; only integers):
|
|
58
|
+
|
|
59
|
+
- `d_-1` -> -1
|
|
60
|
+
- `d_0` -> 0
|
|
61
|
+
- `d_1` -> 1
|
|
62
|
+
- `d_2` -> 2
|
|
63
|
+
|
|
64
|
+
#### Branch Nodes
|
|
65
|
+
- `f_add` -> addition
|
|
66
|
+
- `f_mul` -> multiplication
|
|
67
|
+
- `f_pow` -> power
|
|
68
|
+
|
|
69
|
+
### parse
|
|
70
|
+
Takes a math equation string and outputs a `TreeNode` object.
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from mathai import *
|
|
74
|
+
|
|
75
|
+
equation = parse("sin(x)^2+cos(x)^2")
|
|
76
|
+
print(equation)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
#### Output
|
|
80
|
+
```text
|
|
81
|
+
(cos(x)^2)+(sin(x)^2)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### solve, simplify
|
|
85
|
+
It simplifies and cleans up a given math equation.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
from mathai import *
|
|
89
|
+
|
|
90
|
+
equation = simplify(parse("(x+x+x+x-1-1-1-1)*(4*x-4)*sin(sin(x+x+x)*sin(3*x))"))
|
|
91
|
+
printeq(equation)
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
#### Output
|
|
95
|
+
```text
|
|
96
|
+
((-4+(4*x))^2)*sin((sin((3*x))^2))
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Incomplete Documentation, Will be updated and completed later on
|
|
100
|
+
|
|
101
|
+
### Demonstrations
|
|
102
|
+
|
|
103
|
+
#### Example Demonstration 1
|
|
104
|
+
```python
|
|
105
|
+
from mathai import *
|
|
106
|
+
question_list_from_lecture = [
|
|
107
|
+
"2*x/(2*x^2 + 5*x + 2) > 1/(x + 1)",
|
|
108
|
+
"(x + 2)*(x + 3)/((x - 2)*(x - 3)) <= 1",
|
|
109
|
+
"(5*x - 1) < (x + 1)^2 & (x + 1)^2 < 7*x - 3",
|
|
110
|
+
"(2*x - 1)/(2*x^3 + 3*x^2 + x) > 0",
|
|
111
|
+
"abs(x + 5)*x + 2*abs(x + 7) - 2 = 0",
|
|
112
|
+
"x*abs(x) - 5*abs(x + 2) + 6 = 0",
|
|
113
|
+
"x^2 - abs(x + 2) + x > 0",
|
|
114
|
+
"abs(abs(x - 2) - 3) <= 2",
|
|
115
|
+
"abs(3*x - 5) + abs(8 - x) = abs(3 + 2*x)",
|
|
116
|
+
"abs(x^2 + 5*x + 9) < abs(x^2 + 2*x + 2) + abs(3*x + 7)"
|
|
117
|
+
]
|
|
118
|
+
|
|
119
|
+
for item in question_list_from_lecture:
|
|
120
|
+
eq = simplify(parse(item))
|
|
121
|
+
eq = dowhile(eq, absolute)
|
|
122
|
+
eq = simplify(factor1(fraction(eq)))
|
|
123
|
+
eq = prepare(eq)
|
|
124
|
+
eq = factor2(eq)
|
|
125
|
+
c = wavycurvy(eq & domain(eq)).fix()
|
|
126
|
+
print(c)
|
|
127
|
+
```
|
|
128
|
+
#### Output
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
(-2,-1)U(-(2/3),-(1/2))
|
|
132
|
+
(-inf,0)U(2,3)U{0}
|
|
133
|
+
(2,4)
|
|
134
|
+
(-inf,-1)U(-(1/2),0)U(1/2,+inf)
|
|
135
|
+
{-4,-3,-(3/2)-(sqrt(57)/2)}
|
|
136
|
+
{-1,(5/2)-(sqrt(89)/2),(5/2)+(sqrt(41)/2)}
|
|
137
|
+
(-inf,-sqrt(2))U((2*sqrt(2))/2,+inf)
|
|
138
|
+
(-3,1)U(3,7)U{1,-3,7,3}
|
|
139
|
+
(5/3,8)U{5/3,8}
|
|
140
|
+
(-inf,-(7/3))
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
#### Example Demonstration 2
|
|
144
|
+
```python
|
|
145
|
+
from mathai import *
|
|
146
|
+
def nested_func(eq_node):
|
|
147
|
+
eq_node = fraction(eq_node)
|
|
148
|
+
eq_node = simplify(eq_node)
|
|
149
|
+
eq_node = trig1(eq_node)
|
|
150
|
+
eq_node = trig0(eq_node)
|
|
151
|
+
return eq_node
|
|
152
|
+
for item in ["(cosec(x)-cot(x))^2=(1-cos(x))/(1+cos(x))", "cos(x)/(1+sin(x)) + (1+sin(x))/cos(x) = 2*sec(x)",\
|
|
153
|
+
"tan(x)/(1-cot(x)) + cot(x)/(1-tan(x)) = 1 + sec(x)*cosec(x)", "(1+sec(x))/sec(x) = sin(x)^2/(1-cos(x))",\
|
|
154
|
+
"(cos(x)-sin(x)+1)/(cos(x)+sin(x)-1) = cosec(x)+cot(x)"]:
|
|
155
|
+
eq = logic0(dowhile(parse(item), nested_func))
|
|
156
|
+
print(eq)
|
|
157
|
+
```
|
|
158
|
+
#### Output
|
|
159
|
+
|
|
160
|
+
```
|
|
161
|
+
true
|
|
162
|
+
true
|
|
163
|
+
true
|
|
164
|
+
true
|
|
165
|
+
true
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
#### Example Demonstration 3
|
|
169
|
+
```python
|
|
170
|
+
from mathai import *
|
|
171
|
+
|
|
172
|
+
eq = simplify(parse("integrate(2*x/(x^2+1),x)"))
|
|
173
|
+
eq = integrate_const(eq)
|
|
174
|
+
eq = integrate_fraction(eq)
|
|
175
|
+
print(simplify(fraction(simplify(eq))))
|
|
176
|
+
|
|
177
|
+
eq = simplify(parse("integrate(sin(cos(x))*sin(x),x)"))
|
|
178
|
+
eq = integrate_subs(eq)
|
|
179
|
+
eq = integrate_const(eq)
|
|
180
|
+
eq = integrate_formula(eq)
|
|
181
|
+
eq = integrate_clean(eq)
|
|
182
|
+
print(simplify(eq))
|
|
183
|
+
|
|
184
|
+
eq = simplify(parse("integrate(x*sqrt(x+2),x)"))
|
|
185
|
+
eq = integrate_subs(eq)
|
|
186
|
+
eq = integrate_const(eq)
|
|
187
|
+
eq = integrate_formula(eq)
|
|
188
|
+
eq = expand(eq)
|
|
189
|
+
eq = integrate_const(eq)
|
|
190
|
+
eq = integrate_summation(eq)
|
|
191
|
+
eq = simplify(eq)
|
|
192
|
+
eq = integrate_const(eq)
|
|
193
|
+
eq = integrate_formula(eq)
|
|
194
|
+
eq = integrate_clean(eq)
|
|
195
|
+
print(simplify(fraction(simplify(eq))))
|
|
196
|
+
|
|
197
|
+
eq = simplify(parse("integrate(x/(e^(x^2)),x)"))
|
|
198
|
+
eq = integrate_subs(eq)
|
|
199
|
+
eq = integrate_const(eq)
|
|
200
|
+
eq = integrate_formula(eq)
|
|
201
|
+
eq = simplify(eq)
|
|
202
|
+
eq = integrate_formula(eq)
|
|
203
|
+
eq = integrate_clean(eq)
|
|
204
|
+
print(simplify(eq))
|
|
205
|
+
|
|
206
|
+
eq = fraction(trig0(trig1(simplify(parse("integrate(sin(x)^4,x)")))))
|
|
207
|
+
eq = integrate_const(eq)
|
|
208
|
+
eq = integrate_summation(eq)
|
|
209
|
+
eq = integrate_formula(eq)
|
|
210
|
+
eq = integrate_const(eq)
|
|
211
|
+
eq = integrate_formula(eq)
|
|
212
|
+
print(factor0(simplify(fraction(simplify(eq)))))
|
|
213
|
+
```
|
|
214
|
+
#### Output
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
log(abs((1+(x^2))))
|
|
218
|
+
cos(cos(x))
|
|
219
|
+
((6*((2+x)^(5/2)))-(20*((2+x)^(3/2))))/15
|
|
220
|
+
-((e^-(x^2))/2)
|
|
221
|
+
-(((8*sin((2*x)))-(12*x)-sin((4*x)))/32)
|
|
222
|
+
```
|
|
@@ -370,21 +370,23 @@ def product(lst):
|
|
|
370
370
|
for item in lst[1:]:
|
|
371
371
|
s *= item
|
|
372
372
|
return s
|
|
373
|
-
def flatten_tree(node
|
|
373
|
+
def flatten_tree(node):
|
|
374
|
+
if node is None:
|
|
375
|
+
return None
|
|
374
376
|
if not node.children:
|
|
375
377
|
return node
|
|
376
378
|
ad = []
|
|
377
379
|
if node.name in ["f_add", "f_mul", "f_and", "f_or", "f_wmul"]:
|
|
378
380
|
merged_children = []
|
|
379
381
|
for child in node.children:
|
|
380
|
-
flattened_child = flatten_tree(child
|
|
382
|
+
flattened_child = flatten_tree(child)
|
|
381
383
|
if flattened_child.name == node.name:
|
|
382
384
|
merged_children.extend(flattened_child.children)
|
|
383
385
|
else:
|
|
384
386
|
merged_children.append(flattened_child)
|
|
385
387
|
return TreeNode(node.name, merged_children)
|
|
386
388
|
else:
|
|
387
|
-
node.children = [flatten_tree(child
|
|
389
|
+
node.children = [flatten_tree(child) for child in node.children]
|
|
388
390
|
return node
|
|
389
391
|
def dowhile(eq, fx):
|
|
390
392
|
if eq is None:
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
from .base import *
|
|
2
|
+
from .simplify import simplify
|
|
3
|
+
import itertools
|
|
4
|
+
|
|
5
|
+
def eliminate_powers(node):
|
|
6
|
+
if not node.children:
|
|
7
|
+
return node
|
|
8
|
+
|
|
9
|
+
node.children = [eliminate_powers(c) for c in node.children]
|
|
10
|
+
|
|
11
|
+
if node.name == "f_pow":
|
|
12
|
+
base, exp = node.children
|
|
13
|
+
n = frac(exp)
|
|
14
|
+
|
|
15
|
+
# Only expand positive integer powers
|
|
16
|
+
if not (n and n.denominator == 1 and n.numerator > 1):
|
|
17
|
+
return node
|
|
18
|
+
|
|
19
|
+
n = n.numerator
|
|
20
|
+
|
|
21
|
+
# ---- Multinomial expansion ----
|
|
22
|
+
if base.name == "f_add":
|
|
23
|
+
terms = []
|
|
24
|
+
for combo in itertools.product(base.children, repeat=n):
|
|
25
|
+
prod = combo[0]
|
|
26
|
+
for c in combo[1:]:
|
|
27
|
+
prod = prod * c
|
|
28
|
+
terms.append(prod)
|
|
29
|
+
return simplify(TreeNode("f_add", terms))
|
|
30
|
+
|
|
31
|
+
# ---- Fallback: simple power ----
|
|
32
|
+
return TreeNode("f_mul", [base] * n)
|
|
33
|
+
|
|
34
|
+
return node
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# =====================================================
|
|
39
|
+
# Phase 2: Single distributive rewrite (DEEPEST FIRST)
|
|
40
|
+
# =====================================================
|
|
41
|
+
|
|
42
|
+
def expand_once(node):
|
|
43
|
+
"""
|
|
44
|
+
Performs exactly ONE distributive expansion.
|
|
45
|
+
Deepest-first (post-order).
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
# ---- recurse FIRST (this is the fix) ----
|
|
49
|
+
for i, c in enumerate(node.children):
|
|
50
|
+
new, changed = expand_once(c)
|
|
51
|
+
if changed:
|
|
52
|
+
node.children[i] = new
|
|
53
|
+
return node, True
|
|
54
|
+
|
|
55
|
+
# ---- now try expanding at this node ----
|
|
56
|
+
if node.name == "f_mul":
|
|
57
|
+
for i, child in enumerate(node.children):
|
|
58
|
+
if child.name == "f_add":
|
|
59
|
+
left = node.children[:i]
|
|
60
|
+
right = node.children[i+1:]
|
|
61
|
+
|
|
62
|
+
terms = []
|
|
63
|
+
for t in child.children:
|
|
64
|
+
prod = t
|
|
65
|
+
for r in right:
|
|
66
|
+
prod = prod * r
|
|
67
|
+
for l in reversed(left):
|
|
68
|
+
prod = l * prod
|
|
69
|
+
terms.append(prod)
|
|
70
|
+
|
|
71
|
+
return TreeNode("f_add", terms), True
|
|
72
|
+
|
|
73
|
+
return node, False
|
|
74
|
+
|
|
75
|
+
def _expand2(equation):
|
|
76
|
+
"""Iterative version of _expand without recursion."""
|
|
77
|
+
# Stack: (node, child_index, partially_processed_children)
|
|
78
|
+
stack = [(equation, 0, [])]
|
|
79
|
+
|
|
80
|
+
while stack:
|
|
81
|
+
node, child_index, processed_children = stack.pop()
|
|
82
|
+
|
|
83
|
+
# If all children are processed
|
|
84
|
+
if child_index >= len(node.children):
|
|
85
|
+
# Replace children with processed versions
|
|
86
|
+
node.children = processed_children
|
|
87
|
+
|
|
88
|
+
# === Handle f_pow ===
|
|
89
|
+
if node.name == "f_pow":
|
|
90
|
+
n = frac(node.children[1])
|
|
91
|
+
if n is not None and n.denominator == 1 and n.numerator > 1:
|
|
92
|
+
# Convert power to repeated multiplication
|
|
93
|
+
power_children = [node.children[0] for _ in range(n.numerator)]
|
|
94
|
+
new_node = TreeNode("f_mul", power_children)
|
|
95
|
+
# Flatten tree
|
|
96
|
+
node = flatten_tree(new_node)
|
|
97
|
+
# Push it back for further processing
|
|
98
|
+
stack.append((node, 0, []))
|
|
99
|
+
continue
|
|
100
|
+
|
|
101
|
+
# === Handle f_mul ===
|
|
102
|
+
elif node.name == "f_mul":
|
|
103
|
+
# Separate lone children and bracket children
|
|
104
|
+
lone_children = tree_form("d_1")
|
|
105
|
+
bracket_children = []
|
|
106
|
+
|
|
107
|
+
# Iterate in reverse (like original)
|
|
108
|
+
for child in reversed(node.children):
|
|
109
|
+
if child.name == "f_add":
|
|
110
|
+
bracket_children.append(child)
|
|
111
|
+
elif child.name == "f_pow" and child.children[0].name == "f_add":
|
|
112
|
+
n = frac(child.children[1])
|
|
113
|
+
if n is not None and n.denominator == 1 and n.numerator > 1:
|
|
114
|
+
for _ in range(n.numerator):
|
|
115
|
+
bracket_children.append(child.children[0])
|
|
116
|
+
else:
|
|
117
|
+
lone_children = lone_children * child
|
|
118
|
+
else:
|
|
119
|
+
lone_children = lone_children * child
|
|
120
|
+
|
|
121
|
+
lone_children = simplify(lone_children)
|
|
122
|
+
|
|
123
|
+
# Distribute bracket children over lone children iteratively
|
|
124
|
+
while bracket_children:
|
|
125
|
+
tmp = tree_form("d_0")
|
|
126
|
+
bracket = bracket_children.pop(0)
|
|
127
|
+
for bc in bracket.children:
|
|
128
|
+
if lone_children.name == "f_add":
|
|
129
|
+
for lc in lone_children.children:
|
|
130
|
+
tmp = tmp + bc * lc
|
|
131
|
+
else:
|
|
132
|
+
tmp = tmp + bc * lone_children
|
|
133
|
+
# Simplify after each distribution
|
|
134
|
+
lone_children = flatten_tree(simplify(tmp))
|
|
135
|
+
|
|
136
|
+
node = lone_children
|
|
137
|
+
|
|
138
|
+
# === Return node to parent ===
|
|
139
|
+
if stack:
|
|
140
|
+
parent, idx, parent_children = stack.pop()
|
|
141
|
+
parent_children.append(node)
|
|
142
|
+
stack.append((parent, idx + 1, parent_children))
|
|
143
|
+
else:
|
|
144
|
+
# Root node fully expanded
|
|
145
|
+
return node
|
|
146
|
+
|
|
147
|
+
else:
|
|
148
|
+
# Push current node back for next child
|
|
149
|
+
stack.append((node, child_index, processed_children))
|
|
150
|
+
# Push the child to process next
|
|
151
|
+
child = flatten_tree(node.children[child_index])
|
|
152
|
+
stack.append((child, 0, []))
|
|
153
|
+
|
|
154
|
+
# =====================================================
|
|
155
|
+
# Phase 3: Global fixed-point driver
|
|
156
|
+
# =====================================================
|
|
157
|
+
|
|
158
|
+
def expand(eq):
|
|
159
|
+
orig = TreeNode.matmul
|
|
160
|
+
if TreeNode.matmul is None:
|
|
161
|
+
return _expand2(eq)
|
|
162
|
+
eq = simplify(eq)
|
|
163
|
+
if TreeNode.matmul is not None:
|
|
164
|
+
TreeNode.matmul = True
|
|
165
|
+
eq = tree_form(str_form(eq).replace("f_wmul", "f_mul"))
|
|
166
|
+
eq = flatten_tree(eq)
|
|
167
|
+
eq = eliminate_powers(eq)
|
|
168
|
+
while True:
|
|
169
|
+
eq = flatten_tree(eq)
|
|
170
|
+
eq, changed = expand_once(eq)
|
|
171
|
+
if not changed:
|
|
172
|
+
break
|
|
173
|
+
eq =simplify(eq)
|
|
174
|
+
TreeNode.matmul = orig
|
|
175
|
+
return eq
|
|
@@ -154,7 +154,7 @@ def parse(equation, funclist=None):
|
|
|
154
154
|
return tree_node
|
|
155
155
|
|
|
156
156
|
tree_node = rfx(tree_node)
|
|
157
|
-
tree_node = flatten_tree(tree_node
|
|
157
|
+
tree_node = flatten_tree(tree_node)
|
|
158
158
|
if TreeNode.matmul == True:
|
|
159
159
|
TreeNode.matmul = False
|
|
160
160
|
tree_node = use(tree_form(str_form(tree_node).replace("f_w","f_")))
|