mathai 0.6.8__tar.gz → 0.6.9__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 (34) hide show
  1. {mathai-0.6.8 → mathai-0.6.9}/PKG-INFO +1 -1
  2. {mathai-0.6.8 → mathai-0.6.9}/mathai/__init__.py +1 -1
  3. {mathai-0.6.8 → mathai-0.6.9}/mathai/base.py +7 -2
  4. mathai-0.6.9/mathai/expand.py +95 -0
  5. {mathai-0.6.8 → mathai-0.6.9}/mathai/factor.py +1 -1
  6. {mathai-0.6.8 → mathai-0.6.9}/mathai/matrix.py +1 -2
  7. {mathai-0.6.8 → mathai-0.6.9}/mathai/printeq.py +8 -5
  8. {mathai-0.6.8 → mathai-0.6.9}/mathai/simplify.py +13 -1
  9. {mathai-0.6.8 → mathai-0.6.9}/mathai.egg-info/PKG-INFO +1 -1
  10. {mathai-0.6.8 → mathai-0.6.9}/setup.py +1 -1
  11. mathai-0.6.8/mathai/expand.py +0 -129
  12. {mathai-0.6.8 → mathai-0.6.9}/README.md +0 -0
  13. {mathai-0.6.8 → mathai-0.6.9}/mathai/apart.py +0 -0
  14. {mathai-0.6.8 → mathai-0.6.9}/mathai/bivariate_inequality.py +0 -0
  15. {mathai-0.6.8 → mathai-0.6.9}/mathai/console.py +0 -0
  16. {mathai-0.6.8 → mathai-0.6.9}/mathai/diff.py +0 -0
  17. {mathai-0.6.8 → mathai-0.6.9}/mathai/fraction.py +0 -0
  18. {mathai-0.6.8 → mathai-0.6.9}/mathai/integrate.py +0 -0
  19. {mathai-0.6.8 → mathai-0.6.9}/mathai/inverse.py +0 -0
  20. {mathai-0.6.8 → mathai-0.6.9}/mathai/limit.py +0 -0
  21. {mathai-0.6.8 → mathai-0.6.9}/mathai/linear.py +0 -0
  22. {mathai-0.6.8 → mathai-0.6.9}/mathai/logic.py +0 -0
  23. {mathai-0.6.8 → mathai-0.6.9}/mathai/ode.py +0 -0
  24. {mathai-0.6.8 → mathai-0.6.9}/mathai/parser.py +0 -0
  25. {mathai-0.6.8 → mathai-0.6.9}/mathai/parsetab.py +0 -0
  26. {mathai-0.6.8 → mathai-0.6.9}/mathai/structure.py +0 -0
  27. {mathai-0.6.8 → mathai-0.6.9}/mathai/tool.py +0 -0
  28. {mathai-0.6.8 → mathai-0.6.9}/mathai/trig.py +0 -0
  29. {mathai-0.6.8 → mathai-0.6.9}/mathai/univariate_inequality.py +0 -0
  30. {mathai-0.6.8 → mathai-0.6.9}/mathai.egg-info/SOURCES.txt +0 -0
  31. {mathai-0.6.8 → mathai-0.6.9}/mathai.egg-info/dependency_links.txt +0 -0
  32. {mathai-0.6.8 → mathai-0.6.9}/mathai.egg-info/requires.txt +0 -0
  33. {mathai-0.6.8 → mathai-0.6.9}/mathai.egg-info/top_level.txt +0 -0
  34. {mathai-0.6.8 → mathai-0.6.9}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mathai
3
- Version: 0.6.8
3
+ Version: 0.6.9
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
@@ -7,7 +7,7 @@ from .expand import expand
7
7
 
8
8
  from .parser import parse
9
9
 
10
- from .printeq import printeq, printeq_log, printeq_str
10
+ from .printeq import printeq, printeq_str
11
11
 
12
12
  from .simplify import simplify
13
13
 
@@ -2,6 +2,8 @@ import copy
2
2
  from fractions import Fraction
3
3
  def use(eq):
4
4
  return TreeNode(eq.name, [use(child) for child in eq.children])
5
+ def use2(eq):
6
+ return use(tree_form(str_form(eq).replace("f_wmul", "f_mul")))
5
7
  def contains_list_or_neg(node):
6
8
  stack = [node]
7
9
  while stack:
@@ -10,9 +12,10 @@ def contains_list_or_neg(node):
10
12
  return True
11
13
  stack.extend(n.children)
12
14
  return False
15
+
13
16
  class TreeNode:
14
17
  matmul = None
15
-
18
+
16
19
  def __init__(self, name, children=None):
17
20
  if children is None:
18
21
  children = []
@@ -247,7 +250,9 @@ def frac(eq):
247
250
  def factor_generation(eq):
248
251
  output = []
249
252
  if eq.name != "f_mul":
250
- eq = TreeNode("f_mul", [eq])
253
+ tmp = TreeNode("f_mul", [])
254
+ tmp.children.append(eq)
255
+ eq = tmp
251
256
  if eq.name == "f_mul":
252
257
  for child in eq.children:
253
258
  if child.name == "f_pow":
@@ -0,0 +1,95 @@
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
+
76
+ # =====================================================
77
+ # Phase 3: Global fixed-point driver
78
+ # =====================================================
79
+
80
+ def expand(eq):
81
+ orig = TreeNode.matmul
82
+ eq = simplify(eq)
83
+ if TreeNode.matmul is not None:
84
+ TreeNode.matmul = True
85
+ eq = tree_form(str_form(eq).replace("f_wmul", "f_mul"))
86
+ eq = flatten_tree(eq)
87
+ eq = eliminate_powers(eq)
88
+ while True:
89
+ eq = flatten_tree(eq)
90
+ eq, changed = expand_once(eq)
91
+ if not changed:
92
+ break
93
+ eq =simplify(eq)
94
+ TreeNode.matmul = orig
95
+ return eq
@@ -8,7 +8,7 @@ from .expand import expand
8
8
  import math
9
9
  from .tool import poly
10
10
  from .fraction import fraction
11
- from .printeq import printeq
11
+
12
12
  from collections import Counter
13
13
  def multiset_intersection(*lists):
14
14
  counters = list(map(Counter, lists))
@@ -221,8 +221,7 @@ def use(eq):
221
221
  def _matrix_solve(eq):
222
222
  if TreeNode.matmul == True:
223
223
  TreeNode.matmul = False
224
- eq = use(eq)
225
- eq = dowhile(eq, lambda x: fold_wmul(flat(x)))
224
+ eq = dowhile(eq, lambda x: fold_wmul(use(flat(x))))
226
225
  TreeNode.matmul = True
227
226
  return eq
228
227
  def matrix_solve(eq):
@@ -1,4 +1,5 @@
1
1
  from .base import *
2
+ from .factor import merge_sqrt
2
3
  from .simplify import simplify
3
4
  import copy
4
5
  from fractions import Fraction
@@ -24,11 +25,13 @@ def abstractexpr(eq):
24
25
  return TreeNode(eq.name, [abstractexpr(child) for child in eq.children])
25
26
 
26
27
  def printeq_str(eq):
27
- return str(dowhile(eq, abstractexpr))
28
+ if eq is None:
29
+ return None
30
+ eq = merge_sqrt(eq)
31
+ return string_equation(str_form(dowhile(eq, abstractexpr)))
32
+ def printeq_obj(self):
33
+ return printeq_str(self)
28
34
 
29
35
  def printeq(eq):
30
36
  print(printeq_str(eq))
31
-
32
- def printeq_log(lst):
33
- for item in lst:
34
- print(" "*item[0] + item[1])
37
+ TreeNode.__repr__ = printeq_obj
@@ -15,9 +15,12 @@ def convert_to_basic(node):
15
15
  return node
16
16
 
17
17
  def clear_div(eq, denom):
18
+
18
19
  lst = factor_generation(eq)
20
+
19
21
  if tree_form("d_0") in lst:
20
22
  return tree_form("d_0"), True
23
+
21
24
  lst3 = []
22
25
  for item in lst:
23
26
  if "v_" not in str_form(item) and compute(item) < 0:
@@ -33,10 +36,12 @@ def clear_div(eq, denom):
33
36
  eq2.append(item)
34
37
  else:
35
38
  eq3.append(item)
39
+
36
40
  if eq3 == []:
37
41
  return product(eq2), True
38
42
  return product(eq3), sign
39
43
  lst4 = []
44
+
40
45
  for item in lst:
41
46
  if item.name == "f_pow":
42
47
  tmp = frac(item.children[1])
@@ -44,10 +49,12 @@ def clear_div(eq, denom):
44
49
  lst4.append(item)
45
50
  else:
46
51
  lst4.append(item)
52
+
47
53
  lst2 = []
48
54
  for item in lst4:
49
55
  if frac(item) is None:#"v_" in str_form(item):
50
56
  lst2.append(item)
57
+
51
58
  if lst2 == []:
52
59
  return product(lst4), sign
53
60
  return product(lst2), sign
@@ -503,23 +510,28 @@ def simplify(eq, basic=True):
503
510
  orig = TreeNode.matmul
504
511
  if TreeNode.matmul == True:
505
512
  TreeNode.matmul = False
513
+ if TreeNode.matmul == False:
506
514
  eq = use(tree_form(str_form(eq).replace("f_w","f_")))
507
515
 
508
516
  if eq.name == "f_and" or eq.name == "f_not" or eq.name == "f_or":
509
517
  new_children = []
510
518
  for child in eq.children:
511
519
  new_children.append(simplify(child))
520
+ TreeNode.matmul = orig
512
521
  return TreeNode(eq.name, new_children)
513
522
  if eq.name[2:] in "gt ge lt le eq".split(" "):
514
523
  denom = eq.name != "f_eq"
515
524
  tmp2 = simplify(eq.children[0] - eq.children[1])
516
525
  tmp, denom = clear_div(tmp2, denom)
517
526
  tmp = simplify(tmp)
527
+
518
528
  value2 = eq.name[2:]
519
529
  if denom is False:
520
530
  value2 = {"ge":"le", "le":"ge", "gt":"lt", "lt":"gt", "eq":"eq"}[value2]
521
531
  value2 = "f_"+value2
522
- return TreeNode(value2, [tmp, tree_form("d_0")])
532
+ out = TreeNode(value2, [tmp, tree_form("d_0")])
533
+ TreeNode.matmul = orig
534
+ return out
523
535
  eq = flatten_tree(eq)
524
536
  if basic:
525
537
  eq = convert_to_basic(eq)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mathai
3
- Version: 0.6.8
3
+ Version: 0.6.9
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
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
2
2
 
3
3
  setup(
4
4
  name="mathai",
5
- version="0.6.8",
5
+ version="0.6.9",
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,129 +0,0 @@
1
- import itertools
2
- from .base import *
3
- from .simplify import simplify
4
- '''
5
- def _expand(equation):
6
- eq = equation
7
- eq.children = [_expand(flatten_tree(child)) for child in eq.children]
8
- if eq.name == "f_pow":
9
- n = frac(eq.children[1])
10
- if n is not None and n.denominator == 1 and n.numerator > 1:
11
- power_children = []
12
- for i in range(n.numerator):
13
- power_children.append(eq.children[0])
14
- return _expand(flatten_tree(TreeNode("f_mul", power_children)))
15
- if eq.name == "f_mul":
16
- lone_children = tree_form("d_1")
17
- bracket_children = []
18
- for i in range(len(eq.children)-1,-1,-1):
19
- if eq.children[i].name == "f_add":
20
- bracket_children.append(eq.children[i])
21
- elif eq.children[i].name == "f_pow" and eq.children[i].children[0].name == "f_add":
22
- n = frac(eq.children[i].children[1])
23
- if n is not None and n.denominator == 1 and n.numerator > 1:
24
- for j in range(n.numerator):
25
- bracket_children.append(eq.children[i].children[0])
26
- else:
27
- lone_children = lone_children * eq.children[i]
28
- else:
29
- lone_children = lone_children * eq.children[i]
30
- lone_children = simplify(lone_children)
31
- while bracket_children != []:
32
- tmp = tree_form("d_0")
33
- for i in range(len(bracket_children[0].children)):
34
- if lone_children.name == "f_add":
35
- for j in range(len(lone_children.children)):
36
- tmp = tmp + bracket_children[0].children[i] * lone_children.children[j]
37
- else:
38
- tmp = tmp + lone_children * bracket_children[0].children[i]
39
- lone_children = flatten_tree(simplify(tmp))
40
- bracket_children.pop(0)
41
- return lone_children
42
- return eq
43
- '''
44
- def is_expandable(child):
45
- if child.name == "f_add":
46
- return True
47
- if child.name == "f_pow" and child.children[0].name == "f_add":
48
- n = frac(child.children[1])
49
- return n is not None and n.denominator == 1 and n.numerator > 1
50
- return False
51
-
52
-
53
- def expand_terms(child):
54
- if child.name == "f_add":
55
- return child.children
56
- n = frac(child.children[1]).numerator
57
- return child.children[0].children * n
58
-
59
-
60
- def _expand(equation):
61
- stack = [(equation, 0, [])]
62
-
63
- while stack:
64
- node, idx, done = stack.pop()
65
-
66
- if idx >= len(node.children):
67
- node.children = done
68
-
69
- # ===== f_pow =====
70
- if node.name == "f_pow":
71
- n = frac(node.children[1])
72
- if n and n.denominator == 1 and n.numerator > 1:
73
- node = flatten_tree(
74
- TreeNode("f_mul", [node.children[0]] * n.numerator)
75
- )
76
- stack.append((node, 0, []))
77
- continue
78
-
79
- # ===== f_mul =====
80
- elif node.name == "f_mul":
81
- children = node.children
82
- k = len(children)
83
-
84
- # ---- find expandable index (L→R, then R→L) ----
85
- idxs = list(range(k)) + list(reversed(range(k)))
86
- seen = set()
87
- expand_i = None
88
-
89
- for i in idxs:
90
- if i in seen:
91
- continue
92
- seen.add(i)
93
- if is_expandable(children[i]):
94
- expand_i = i
95
- break
96
-
97
- if expand_i is not None:
98
- left = children[:expand_i]
99
- right = children[expand_i + 1:]
100
- expandable = children[expand_i]
101
-
102
- out = tree_form("d_0")
103
- for term in expand_terms(expandable):
104
- prod = term
105
- for r in right:
106
- prod = prod * r
107
- for l in reversed(left):
108
- prod = l * prod
109
- out = out + prod
110
-
111
- node = flatten_tree(simplify(out))
112
-
113
- # ===== return =====
114
- if stack:
115
- parent, pidx, acc = stack.pop()
116
- acc.append(node)
117
- stack.append((parent, pidx + 1, acc))
118
- else:
119
- return node
120
-
121
- else:
122
- stack.append((node, idx, done))
123
- child = flatten_tree(node.children[idx])
124
- stack.append((child, 0, []))
125
-
126
- def expand(eq):
127
- if TreeNode.matmul == True:
128
- eq = tree_form(str_form(eq).replace("f_wmul", "f_mul"))
129
- return _expand(eq)
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