mathai 0.3.3__py3-none-any.whl → 0.3.5__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/integrate.py CHANGED
@@ -376,24 +376,25 @@ def rm_const(equation):
376
376
  return rm_const(TreeNode("f_integrate",[equation, wrt])) *const
377
377
  equation = eq2
378
378
  return TreeNode(equation.name, [rm_const(child) for child in equation.children])
379
+
379
380
  def integrate_formula(equation):
380
381
  if equation.name == "f_ref":
381
- return equation
382
+ return equation.copy_tree()
382
383
  eq2 = equation.copy_tree()
383
384
  if eq2.name == "f_integrate":
384
- equation = eq2.children[0]
385
+ integrand = eq2.children[0]
385
386
  wrt = eq2.children[1]
386
- if equation == wrt:
387
- return equation**2/2
388
- if not contain(equation,wrt):
389
- return wrt*equation
390
- out = transform_formula(simplify(trig0(equation)), wrt.name, formula_gen[0], formula_gen[1], formula_gen[2])
387
+ if integrand == wrt:
388
+ return TreeNode("f_add", [TreeNode("f_power", [wrt.copy_tree(), TreeNode("2")]), TreeNode("f_div", [TreeNode("1"), TreeNode("2")])]) # x^2/2
389
+ if not contain(integrand, wrt):
390
+ return TreeNode("f_mul", [wrt.copy_tree(), integrand.copy_tree()]) # constant * dx
391
+ out = transform_formula(simplify(trig0(integrand)), wrt.name, formula_gen[0], formula_gen[1], formula_gen[2])
391
392
  if out is not None:
392
393
  return out
393
-
394
- if str_form(equation).count("f_sin")+str_form(equation).count("f_cos")>2:
395
- out = transform_formula(equation, wrt.name, formula_gen4[0], formula_gen4[1], formula_gen4[2])
396
- if out is not None:
397
- return out
398
- equation = eq2
399
- return TreeNode(equation.name, [integrate_formula(child) for child in equation.children])
394
+ expr_str = str_form(integrand)
395
+ if expr_str.count("f_sin") + expr_str.count("f_cos") > 2:
396
+ out = transform_formula(integrand, wrt.name, formula_gen4[0], formula_gen4[1], formula_gen4[2])
397
+ if out is not None:
398
+ return out
399
+ return TreeNode(eq2.name, [integrate_formula(child) for child in eq2.children])
400
+
mathai/search.py CHANGED
@@ -2,107 +2,116 @@ from mathai import *
2
2
  import copy
3
3
  from concurrent.futures import ThreadPoolExecutor, TimeoutError
4
4
 
5
- # Original expression
6
- original_eq = simplify(parse("((P|~Q)&(P&~Q|P&R)&(~P&~R|~Q))<->P&~Q"))
7
-
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
27
-
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)
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)
41
45
 
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
46
+ # Thinking message
47
+ printeq(current_eq)
48
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
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
55
54
  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
+ if false_expr(current_eq):
56
+ found_boolean = True
57
+ boolean_path = path
58
+ boolean_expr = current_eq
59
+ break
60
+
77
61
 
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:")
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):")
82
83
  printeq(current_eq)
83
84
  future = executor.submit(fx, current_eq)
84
85
  try:
85
- new_expr = future.result(timeout=5)
86
+ new_expr = future.result(timeout=timeout)
86
87
  new_expr_str = str(new_expr)
87
- if new_expr_str != expr_str:
88
+ if len(new_expr_str) <= len(expr_str) and new_expr_str != expr_str:
89
+ reduced_any = True
88
90
  stack.append((new_expr, path + [copy.deepcopy(new_expr)]))
89
- break # only take one growing function
91
+ consecutive_timeouts = 0 # reset after success
90
92
  except TimeoutError:
91
- print(f"[Thinking] {fx.__name__} (growing) timed out, skipping.")
93
+ print(f"[Thinking] {fx.__name__} timed out, skipping.")
94
+ consecutive_timeouts += 1
92
95
  continue
93
96
 
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)
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mathai
3
- Version: 0.3.3
3
+ Version: 0.3.5
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
@@ -6,20 +6,20 @@ mathai/diff.py,sha256=YUBpRsz0qmBkq5vGxeGnvR4nMKjdOQiIXlNMxpij2ns,3051
6
6
  mathai/expand.py,sha256=SnBltkpIENMGkP0AYmbMlSc4H-CF5RslO2PcBEkn1BQ,3359
7
7
  mathai/factor.py,sha256=NPXxET52TacNExuvw6p1jbC6g3wY6_VOCdlGlexXZio,5916
8
8
  mathai/fraction.py,sha256=Q2ztsh5Bpz6YhML2QU0tfufbAs0Q6J319AhlzKephIY,4396
9
- mathai/integrate.py,sha256=85qM7nvALtYjVMp17Tx5Kvevdz0d1UPDKQBBTnDqgrs,14828
9
+ mathai/integrate.py,sha256=1E6Uv0f6aqQHB1vmrgvhApw2vtb13upThOKptk891LA,15002
10
10
  mathai/inverse.py,sha256=QCvDrzKquWsZv-BDAzZd9HnU0c3gZvcc44UztHVO5LQ,2919
11
11
  mathai/limit.py,sha256=RA8YAehgYCGVWv9qBc8uQ34BQ9mFthWl2OrVTwcHl2g,4920
12
12
  mathai/linear.py,sha256=wyiLpIxRDmD96xXktkgvc5gegIB3zblLB1EuV3TFdmU,5474
13
13
  mathai/logic.py,sha256=UvHzRmKcO9AD51tRzHmpNSEhgW5gmaf4XPaQKFjGfC4,9653
14
14
  mathai/parser.py,sha256=f7bemieFmp0sbup1NlraMLvZDVFvqKGFknEVtlFRMVk,6979
15
15
  mathai/printeq.py,sha256=gIes-pstFOa6FcnpVIVvkjVKuWdsVdo11LlEnmHhakU,1303
16
- mathai/search.py,sha256=BmUKacCpptIoyUObB0hknAbgFs8EPQXXXXYBXT40Luc,3672
16
+ mathai/search.py,sha256=6S_V0PrC2ZnbhkWyT2ZTtExRD_mDlo-C3p0TDn6Dk3w,4743
17
17
  mathai/simplify.py,sha256=F37h-Z_rW35uVgx0G86vQErU2Ac6ZiTBN9KcC3RzDkg,15156
18
18
  mathai/structure.py,sha256=4Ww2IAx62RcQSO7_17TZES-DjMWBpcFQtL939FBIHwY,4103
19
19
  mathai/tool.py,sha256=UyccamiJy_CkFPakfufyPzdhtlEO6v2D7qwbXQ9V7Rg,2000
20
20
  mathai/trig.py,sha256=5P0RNS4eetNds2l-wyA4BAKqJdFIUws_8RGS_dH7gp8,9348
21
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,,
22
+ mathai-0.3.5.dist-info/METADATA,sha256=fKwgikKrsCYSz8fRhFqIOJY71JITj1PLuFgM_GEKpFY,7021
23
+ mathai-0.3.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
+ mathai-0.3.5.dist-info/top_level.txt,sha256=ROP4l3OhGYw3ihkQGASr18xM9GsK4z3_6whV5AyXLwE,7
25
+ mathai-0.3.5.dist-info/RECORD,,
File without changes