mathai 2.4.6__tar.gz → 2.4.8__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-2.4.6 → mathai-2.4.8}/PKG-INFO +1 -1
- {mathai-2.4.6 → mathai-2.4.8}/mathai/__init__.py +1 -1
- mathai-2.4.8/mathai/benchmark.py +195 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/decision.py +17 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai.egg-info/PKG-INFO +1 -1
- {mathai-2.4.6 → mathai-2.4.8}/setup.py +1 -1
- mathai-2.4.6/mathai/benchmark.py +0 -63
- {mathai-2.4.6 → mathai-2.4.8}/README.md +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/apart.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/base.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/diff.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/electronic.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/expand.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/factor.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/formula_applier.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/formula_compiler.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/fraction.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/graphics.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/integrate.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/inverse.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/lambda_calculus.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/limit.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/linear.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/logic.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/matrix.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/ml.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/mlscalar.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/ncert_data.txt +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/ode.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/parser.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/pde.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/printeq.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/qm.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/simplify.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/statistics.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/test.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/tool.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/trig.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai/univariate_inequality.py +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai.egg-info/SOURCES.txt +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai.egg-info/dependency_links.txt +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/mathai.egg-info/top_level.txt +0 -0
- {mathai-2.4.6 → mathai-2.4.8}/setup.cfg +0 -0
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
from .simplify import simplify
|
|
5
|
+
from .expand import expand
|
|
6
|
+
from .parser import parse
|
|
7
|
+
from .fraction import fraction
|
|
8
|
+
from .apart import apart
|
|
9
|
+
from .integrate import (
|
|
10
|
+
integrate_formula,
|
|
11
|
+
integrate_trig_formula,
|
|
12
|
+
integrate_fraction,
|
|
13
|
+
integrate_subs_main as integrate_subs,
|
|
14
|
+
solve_integrate as integrate_clean,
|
|
15
|
+
)
|
|
16
|
+
from .factor import factor2
|
|
17
|
+
from .trig import trig0, trig1, trig4, trig6
|
|
18
|
+
from .univariate_inequality import simple_wavycurvy, absolute
|
|
19
|
+
from .limit import limit1
|
|
20
|
+
from .logic import logic0
|
|
21
|
+
from .base import *
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
fx_list = [
|
|
25
|
+
lambda x: dowhile(x, absolute),
|
|
26
|
+
logic0,
|
|
27
|
+
limit1,
|
|
28
|
+
simple_wavycurvy,
|
|
29
|
+
simplify,
|
|
30
|
+
expand,
|
|
31
|
+
fraction,
|
|
32
|
+
integrate_formula,
|
|
33
|
+
integrate_subs,
|
|
34
|
+
integrate_trig_formula,
|
|
35
|
+
integrate_clean,
|
|
36
|
+
apart,
|
|
37
|
+
trig0,
|
|
38
|
+
trig1,
|
|
39
|
+
trig4,
|
|
40
|
+
integrate_fraction,
|
|
41
|
+
factor2,
|
|
42
|
+
trig6,
|
|
43
|
+
]
|
|
44
|
+
|
|
45
|
+
name_list = """
|
|
46
|
+
absolute logic0 limit1 simple_wavycurvy simplify expand fraction
|
|
47
|
+
integrate_formula integrate_subs integrate_trig_formula
|
|
48
|
+
integrate_clean apart trig0 trig1 trig4 integrate_fraction factor2 trig6
|
|
49
|
+
""".split()
|
|
50
|
+
|
|
51
|
+
# O(1) name -> function lookup
|
|
52
|
+
FUNCS = dict(zip(name_list, fx_list))
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# ---------------------------------------------------------------------------
|
|
56
|
+
# Benchmark
|
|
57
|
+
# ---------------------------------------------------------------------------
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def benchmark(s="ncert_data"):
|
|
61
|
+
data_path = Path(__file__).parent / f"{s}.txt"
|
|
62
|
+
output_path = Path(__file__).parent / f"{s}_optimized.txt"
|
|
63
|
+
|
|
64
|
+
optimized_lines = []
|
|
65
|
+
|
|
66
|
+
with open(data_path, "r", encoding="utf-8") as file:
|
|
67
|
+
for count, line in enumerate(file, 1):
|
|
68
|
+
parts = line.split()
|
|
69
|
+
|
|
70
|
+
if not parts:
|
|
71
|
+
continue
|
|
72
|
+
|
|
73
|
+
expr_str, *function_names = parts
|
|
74
|
+
eq = simplify(parse(expr_str))
|
|
75
|
+
effective_steps = [expr_str]
|
|
76
|
+
|
|
77
|
+
for func_name in function_names:
|
|
78
|
+
func = FUNCS[func_name]
|
|
79
|
+
prev_eq = copy.deepcopy(eq)
|
|
80
|
+
eq = func(eq)
|
|
81
|
+
|
|
82
|
+
if eq != prev_eq:
|
|
83
|
+
effective_steps.append(func_name)
|
|
84
|
+
|
|
85
|
+
print(f"{count}. {expr_str} => {eq}")
|
|
86
|
+
optimized_lines.append(" ".join(effective_steps))
|
|
87
|
+
|
|
88
|
+
with open(output_path, "w", encoding="utf-8") as file:
|
|
89
|
+
file.write("\n".join(optimized_lines) + "\n")
|
|
90
|
+
|
|
91
|
+
print(f"\nOptimized dataset successfully written to: {output_path}")
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# ---------------------------------------------------------------------------
|
|
95
|
+
# Strategy tree
|
|
96
|
+
# ---------------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class Node:
|
|
100
|
+
def __init__(self, value):
|
|
101
|
+
self.value = value
|
|
102
|
+
self.children = {} # Dictionary for O(1) child lookup
|
|
103
|
+
|
|
104
|
+
def add_child(self, value):
|
|
105
|
+
if value not in self.children:
|
|
106
|
+
self.children[value] = Node(value)
|
|
107
|
+
return self.children[value]
|
|
108
|
+
|
|
109
|
+
def execute(self, equation, sequence=None, terminal_condition=None):
|
|
110
|
+
if sequence is None:
|
|
111
|
+
sequence = []
|
|
112
|
+
|
|
113
|
+
if self.value != "ROOT":
|
|
114
|
+
func = FUNCS[self.value]
|
|
115
|
+
|
|
116
|
+
# Track previous state to detect and prune no-ops
|
|
117
|
+
prev_eq = copy.deepcopy(equation)
|
|
118
|
+
equation = func(equation)
|
|
119
|
+
|
|
120
|
+
# PRUNING: if the function didn't change the equation, halt this branch
|
|
121
|
+
if equation == prev_eq:
|
|
122
|
+
return []
|
|
123
|
+
|
|
124
|
+
sequence = sequence + [self.value]
|
|
125
|
+
|
|
126
|
+
# Check terminal condition after applying the function
|
|
127
|
+
if terminal_condition is not None and terminal_condition(equation):
|
|
128
|
+
return [(equation, sequence)]
|
|
129
|
+
|
|
130
|
+
if not self.children:
|
|
131
|
+
return [(equation, sequence)]
|
|
132
|
+
|
|
133
|
+
results = []
|
|
134
|
+
for child in self.children.values():
|
|
135
|
+
results.extend(
|
|
136
|
+
child.execute(copy.deepcopy(equation), sequence, terminal_condition)
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
return results
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
def strategy_tree(sequences):
|
|
143
|
+
root = Node("ROOT")
|
|
144
|
+
|
|
145
|
+
for sequence in sequences:
|
|
146
|
+
node = root
|
|
147
|
+
|
|
148
|
+
for function_name in sequence:
|
|
149
|
+
node = node.add_child(function_name)
|
|
150
|
+
|
|
151
|
+
return root
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def load_sequences(s="ncert_data"):
|
|
155
|
+
data_path = Path(__file__).parent / f"{s}.txt"
|
|
156
|
+
sequences = []
|
|
157
|
+
|
|
158
|
+
with open(data_path, "r", encoding="utf-8") as file:
|
|
159
|
+
for line in file:
|
|
160
|
+
parts = line.split()
|
|
161
|
+
|
|
162
|
+
if parts:
|
|
163
|
+
sequences.append(parts[1:])
|
|
164
|
+
|
|
165
|
+
return sequences
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
def print_tree(node, depth=0):
|
|
169
|
+
print(" " * depth + str(node.value))
|
|
170
|
+
|
|
171
|
+
for child in node.children.values():
|
|
172
|
+
print_tree(child, depth + 1)
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
# ---------------------------------------------------------------------------
|
|
176
|
+
# Serial Execution Entry Point
|
|
177
|
+
# ---------------------------------------------------------------------------
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def execute_serial(tree, equation, terminal_condition=None):
|
|
181
|
+
"""
|
|
182
|
+
Executes the strategy tree serially and returns at most one
|
|
183
|
+
matching path as a list of tuples: [(equation, sequence)].
|
|
184
|
+
"""
|
|
185
|
+
for child in tree.children.values():
|
|
186
|
+
try:
|
|
187
|
+
results = child.execute(copy.deepcopy(equation), [], terminal_condition)
|
|
188
|
+
except Exception:
|
|
189
|
+
continue
|
|
190
|
+
|
|
191
|
+
for eq, seq in results:
|
|
192
|
+
if terminal_condition is None or terminal_condition(eq):
|
|
193
|
+
return [(eq, seq)]
|
|
194
|
+
|
|
195
|
+
return []
|
|
@@ -15,6 +15,7 @@ from .factor import factor2, factor
|
|
|
15
15
|
from .limit import limit1, limit5
|
|
16
16
|
from .linear import linear_solve
|
|
17
17
|
from .matrix import matrix_solve, matrix_formula
|
|
18
|
+
from .benchmark import load_sequences, strategy_tree, execute_serial
|
|
18
19
|
|
|
19
20
|
def vlist_2(eq):
|
|
20
21
|
out = []
|
|
@@ -60,6 +61,22 @@ def solve_subs(q):
|
|
|
60
61
|
if len(solution.keys()) == 0:
|
|
61
62
|
return orig
|
|
62
63
|
return operation("f_and", [item for item in lst if all(not contain(item, tree_form(key)) for key in solution.keys())] + [TreeNode("f_eq", [tree_form(key), item]) for key, item in solution.items()])
|
|
64
|
+
def _no_integrate_left(eq):
|
|
65
|
+
return eq.name == "f_range" or eq.name == "s_true" or all(not contain2(eq, "f_"+item) for item in "eq integrate subs limit limitpinf limitninf".split(" "))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def god2(string):
|
|
69
|
+
out = execute_serial(
|
|
70
|
+
strategy_tree(load_sequences("ncert_data")),
|
|
71
|
+
simplify(parse(string)),
|
|
72
|
+
_no_integrate_left,
|
|
73
|
+
)
|
|
74
|
+
if len(out) >= 1:
|
|
75
|
+
print(string)
|
|
76
|
+
print("=>", out[0][0])
|
|
77
|
+
print(["parse", "simplify"] + out[0][1])
|
|
78
|
+
return None
|
|
79
|
+
|
|
63
80
|
def god(string, debug=True):
|
|
64
81
|
if debug:
|
|
65
82
|
print(f"? {string}")
|
|
@@ -3,7 +3,7 @@ from setuptools import setup, find_packages
|
|
|
3
3
|
|
|
4
4
|
setup(
|
|
5
5
|
name="mathai",
|
|
6
|
-
version="2.4.
|
|
6
|
+
version="2.4.8",
|
|
7
7
|
description="Mathematics solving Ai tailored to NCERT",
|
|
8
8
|
long_description=Path("README.md").read_text(encoding="utf-8"),
|
|
9
9
|
long_description_content_type="text/markdown",
|
mathai-2.4.6/mathai/benchmark.py
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import random
|
|
2
|
-
import copy
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
from .simplify import simplify
|
|
5
|
-
from .expand import expand
|
|
6
|
-
from .parser import parse
|
|
7
|
-
from .fraction import fraction
|
|
8
|
-
from .apart import apart
|
|
9
|
-
from .integrate import integrate_formula, integrate_trig_formula, integrate_fraction
|
|
10
|
-
from .integrate import integrate_subs_main as integrate_subs
|
|
11
|
-
from .integrate import solve_integrate as integrate_clean
|
|
12
|
-
from .factor import factor2
|
|
13
|
-
from .trig import trig0, trig1, trig4, trig6
|
|
14
|
-
from .univariate_inequality import simple_wavycurvy, absolute
|
|
15
|
-
from .limit import limit1
|
|
16
|
-
from .logic import logic0
|
|
17
|
-
from .base import *
|
|
18
|
-
|
|
19
|
-
fx_list = [lambda x: dowhile(x, absolute), logic0, limit1, simple_wavycurvy, simplify, expand, fraction, integrate_formula, integrate_subs, integrate_trig_formula, integrate_clean, apart, trig0, trig1, trig4, integrate_fraction, factor2, trig6]
|
|
20
|
-
name_list = "absolute, logic0, limit1, simple_wavycurvy, simplify, expand, fraction, integrate_formula, integrate_subs, integrate_trig_formula, integrate_clean, apart, trig0, trig1, trig4, integrate_fraction, factor2, trig6".split(", ")
|
|
21
|
-
|
|
22
|
-
def benchmark(s="ncert_data"):
|
|
23
|
-
data_path = Path(__file__).parent / f"{s}.txt"
|
|
24
|
-
output_path = Path(__file__).parent / f"{s}_optimized.txt"
|
|
25
|
-
|
|
26
|
-
optimized_lines = []
|
|
27
|
-
|
|
28
|
-
with open(data_path, "r", encoding="utf-8") as file:
|
|
29
|
-
content = file.read().strip().split("\n")
|
|
30
|
-
count = 0
|
|
31
|
-
for item in content:
|
|
32
|
-
count += 1
|
|
33
|
-
item = item.strip()
|
|
34
|
-
if not item:
|
|
35
|
-
continue
|
|
36
|
-
parts = item.split(" ")
|
|
37
|
-
expr_str = parts[0]
|
|
38
|
-
eq = simplify(parse(expr_str))
|
|
39
|
-
|
|
40
|
-
effective_steps = [expr_str]
|
|
41
|
-
|
|
42
|
-
for func_name in parts[1:]:
|
|
43
|
-
func_idx = name_list.index(func_name)
|
|
44
|
-
func = fx_list[func_idx]
|
|
45
|
-
|
|
46
|
-
# Deepcopy to avoid in-place mutation reference traps
|
|
47
|
-
prev_eq = copy.deepcopy(eq)
|
|
48
|
-
eq = func(eq)
|
|
49
|
-
|
|
50
|
-
# Check if the function changed the equation
|
|
51
|
-
if eq == prev_eq:
|
|
52
|
-
pass
|
|
53
|
-
else:
|
|
54
|
-
effective_steps.append(func_name)
|
|
55
|
-
|
|
56
|
-
print(f"{count}. {expr_str} => {eq}")
|
|
57
|
-
optimized_lines.append(" ".join(effective_steps))
|
|
58
|
-
|
|
59
|
-
# Write out the optimized lines without non-changing functions
|
|
60
|
-
with open(output_path, "w", encoding="utf-8") as outfile:
|
|
61
|
-
outfile.write("\n".join(optimized_lines) + "\n")
|
|
62
|
-
|
|
63
|
-
print(f"\nOptimized dataset successfully written to: {output_path}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|