mathai 0.4.0__tar.gz → 0.4.2__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.
Files changed (30) hide show
  1. {mathai-0.4.0 → mathai-0.4.2}/PKG-INFO +1 -1
  2. {mathai-0.4.0 → mathai-0.4.2}/mathai/__init__.py +0 -2
  3. {mathai-0.4.0 → mathai-0.4.2}/mathai/apart.py +19 -9
  4. {mathai-0.4.0 → mathai-0.4.2}/mathai/base.py +6 -0
  5. {mathai-0.4.0 → mathai-0.4.2}/mathai/integrate.py +18 -10
  6. {mathai-0.4.0 → mathai-0.4.2}/mathai/linear.py +7 -4
  7. {mathai-0.4.0 → mathai-0.4.2}/mathai/simplify.py +23 -1
  8. {mathai-0.4.0 → mathai-0.4.2}/mathai/trig.py +41 -10
  9. {mathai-0.4.0 → mathai-0.4.2}/mathai.egg-info/PKG-INFO +1 -1
  10. {mathai-0.4.0 → mathai-0.4.2}/mathai.egg-info/SOURCES.txt +0 -1
  11. {mathai-0.4.0 → mathai-0.4.2}/setup.py +1 -1
  12. mathai-0.4.0/mathai/search.py +0 -117
  13. {mathai-0.4.0 → mathai-0.4.2}/README.md +0 -0
  14. {mathai-0.4.0 → mathai-0.4.2}/mathai/console.py +0 -0
  15. {mathai-0.4.0 → mathai-0.4.2}/mathai/diff.py +0 -0
  16. {mathai-0.4.0 → mathai-0.4.2}/mathai/expand.py +0 -0
  17. {mathai-0.4.0 → mathai-0.4.2}/mathai/factor.py +0 -0
  18. {mathai-0.4.0 → mathai-0.4.2}/mathai/fraction.py +0 -0
  19. {mathai-0.4.0 → mathai-0.4.2}/mathai/inverse.py +0 -0
  20. {mathai-0.4.0 → mathai-0.4.2}/mathai/limit.py +0 -0
  21. {mathai-0.4.0 → mathai-0.4.2}/mathai/logic.py +0 -0
  22. {mathai-0.4.0 → mathai-0.4.2}/mathai/parser.py +0 -0
  23. {mathai-0.4.0 → mathai-0.4.2}/mathai/printeq.py +0 -0
  24. {mathai-0.4.0 → mathai-0.4.2}/mathai/structure.py +0 -0
  25. {mathai-0.4.0 → mathai-0.4.2}/mathai/tool.py +0 -0
  26. {mathai-0.4.0 → mathai-0.4.2}/mathai/univariate_inequality.py +0 -0
  27. {mathai-0.4.0 → mathai-0.4.2}/mathai.egg-info/dependency_links.txt +0 -0
  28. {mathai-0.4.0 → mathai-0.4.2}/mathai.egg-info/requires.txt +0 -0
  29. {mathai-0.4.0 → mathai-0.4.2}/mathai.egg-info/top_level.txt +0 -0
  30. {mathai-0.4.0 → mathai-0.4.2}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mathai
3
- Version: 0.4.0
3
+ Version: 0.4.2
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
@@ -36,8 +36,6 @@ from .console import console
36
36
 
37
37
  from .limit import limit
38
38
 
39
- from .search import dfs_simplify as search0
40
-
41
39
  from .univariate_inequality import wavycurvy, absolute, domain, handle_sqrt
42
40
 
43
41
  from .base import *
@@ -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="v_0"):
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
- eq = _apart(eq)
113
- return fx(eq)
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))
@@ -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)
@@ -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
- output.append(inverse(eq3, str_form(eq2)))
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.children = list(set(eq2.children))
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 TreeNode("f_add", [TreeNode("f_power", [wrt.copy_tree(), TreeNode("2")]), TreeNode("f_div", [TreeNode("1"), TreeNode("2")])]) # x^2/2
394
+ return wrt**2/2 # x^2/2
388
395
  if not contain(integrand, wrt):
389
- return TreeNode("f_mul", [wrt.copy_tree(), integrand.copy_tree()]) # constant * dx
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
- print(out, 111)
405
+
398
406
  return out
399
407
  return TreeNode(eq2.name, [integrate_formula(child) for child in eq2.children])
400
408
 
@@ -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 fraction(simplify(matrix[i][lead])) == tree_form("d_0"):
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] = [fraction(simplify(m / lv)) for m in 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] = [fraction(simplify(m - lv * n)) for m, n in zip(matrix[i], matrix[r])]
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
- #print(m)
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")
@@ -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:
@@ -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 = eq.children[0].children[:(len(eq.children[0].children)-r)/2], eq.children[0].children[(len(eq.children[0].children)-r)/2:]
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 = eq.children[0].children[:(len(eq.children[0].children)-r)/2], eq.children[0].children[(len(eq.children[0].children)-r)/2:]
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
- if all(eq.children[item2].name == "f_sin" for item2 in item):
206
- a, b = eq.children[item[0]].children[0], eq.children[item[1]].children[0]
207
- rest = [item2 for index, item2 in enumerate(eq.children) if index not in item]
208
- if len(rest)==0:
209
- rest = tree_form("d_0")
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
- rest = summation(rest)
212
- two = tree_form("d_2")
213
- return rest + two*((a+b)/two).fx("sin")*((a-b)/two).fx("cos")
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mathai
3
- Version: 0.4.0
3
+ Version: 0.4.2
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
@@ -15,7 +15,6 @@ mathai/linear.py
15
15
  mathai/logic.py
16
16
  mathai/parser.py
17
17
  mathai/printeq.py
18
- mathai/search.py
19
18
  mathai/simplify.py
20
19
  mathai/structure.py
21
20
  mathai/tool.py
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="mathai",
5
- version="0.4.0",
5
+ version="0.4.2",
6
6
  description="Mathematics solving Ai tailored to NCERT",
7
7
  long_description=open("README.md").read(),
8
8
  long_description_content_type="text/markdown",
@@ -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
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