aciang commited on
Commit
8a4e70b
·
verified ·
1 Parent(s): e462304

Upload folder using huggingface_hub

Browse files
Files changed (2) hide show
  1. README.md +7 -2
  2. app.py +119 -56
README.md CHANGED
@@ -1,5 +1,5 @@
1
  ---
2
- title: LanguageBridge — Math Fast Agent (SymPy)
3
  emoji: 🧮
4
  colorFrom: yellow
5
  colorTo: blue
@@ -9,4 +9,9 @@ app_file: app.py
9
  pinned: false
10
  ---
11
 
12
- SymPy 的數學推理小助手,可一次貼上多行算式、聯立方程;也可用 `diff(...)`、`integrate(...)`、`factor(...)` 等指令。
 
 
 
 
 
 
1
  ---
2
+ title: LanguageBridge — Math Fast Agent (SymPy, Safe)
3
  emoji: 🧮
4
  colorFrom: yellow
5
  colorTo: blue
 
9
  pinned: false
10
  ---
11
 
12
+ A lightweight SymPy-based math agent. No torch needed.
13
+
14
+ Usage examples:
15
+ - 2*x + 5 = 11
16
+ - sin(theta) = sqrt(3)/2, 0 <= theta < 2*pi
17
+ - factor(x**4 - 1)
app.py CHANGED
@@ -1,68 +1,131 @@
1
- \
2
  import gradio as gr
3
  import sympy as sp
4
 
5
- TITLE = "LanguageBridge — Math Fast Agent (SymPy)"
6
-
7
- def solve_math(q: str):
8
- q = (q or "").strip()
9
- if not q:
10
- return "請輸入算式或方程,例如:2x+3=11;或:sin(x)**2 + cos(x)**2;或:factor(x**2-9)"
11
- try:
12
- # 支援方程/聯立:可用分號或換行分隔
13
- if "=" in q:
14
- parts = [s.strip() for seg in q.split(";") for s in seg.split("\n")]
15
- eqs, syms = [], set()
16
- for s in parts:
17
- if not s:
18
- continue
19
- if "=" not in s:
20
- continue
21
- left, right = s.split("=", 1)
22
- eq = sp.Eq(sp.sympify(left), sp.sympify(right))
23
- eqs.append(eq)
24
- syms |= eq.free_symbols
25
- if hasattr(eq, "rhs"):
26
- syms |= eq.rhs.free_symbols
27
- if not syms:
28
- x = sp.symbols("x")
29
- syms = {x}
30
- sol = sp.solve(eqs, list(syms), dict=True)
31
- if not sol:
32
- return "無解或需要更多條件。"
33
- lines = []
34
- for i, s in enumerate(sol, 1):
35
- lines.append(f"解 {i}: " + ", ".join([f"{k} = {sp.simplify(v)}" for k, v in s.items()]))
36
- return "\n".join(lines)
37
 
38
- # 非方程:做一輪常見操作
39
- expr = sp.sympify(q)
40
- tips = []
41
- try:
42
- tips.append(f"簡化:{sp.simplify(expr)}")
43
- except Exception:
44
- tips.append(f"簡化:{expr}")
45
  try:
46
- fact = sp.factor(expr)
47
- if fact != expr:
48
- tips.append(f"因式分解:{fact}")
49
  except Exception:
50
  pass
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
  try:
52
- x = list(expr.free_symbols)[0] if expr.free_symbols else sp.symbols("x")
53
- tips.append(f"對 {x} 微分:{sp.diff(expr, x)}")
54
- tips.append(f" {x} 積分:{sp.integrate(expr, x)}")
55
- except Exception:
56
- pass
57
- return "\n".join(tips) if tips else f"結果:{expr}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
58
  except Exception as e:
59
- return f"解析失敗:{e}"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
- with gr.Blocks(title=TITLE) as demo:
62
- gr.Markdown(f"## {TITLE}\n貼上算式(可多行 / 用分號 `;` 分隔):")
63
- q = gr.Textbox(lines=6, label="題目 / 算式(可含聯立方程)")
64
- out = gr.Textbox(lines=10, label="輸出")
65
- gr.Button("送出 🚀").click(fn=solve_math, inputs=q, outputs=out)
 
 
66
 
67
  if __name__ == "__main__":
68
- demo.launch()
 
1
+
2
  import gradio as gr
3
  import sympy as sp
4
 
5
+ def default_symbols():
6
+ names = ["x","y","z","t","theta","a","b","c","n","m"]
7
+ d = {name: sp.symbols(name, real=True) for name in names}
8
+ d["pi"] = sp.pi
9
+ d["e"] = sp.E
10
+ d["sqrt"] = sp.sqrt
11
+ return d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
 
13
+ def parse_constraints(parts, syms):
14
+ cons = []
15
+ for p in parts:
16
+ s = p.strip()
17
+ if not s:
18
+ continue
 
19
  try:
20
+ rel = sp.sympify(s, locals=syms)
21
+ cons.append(rel)
 
22
  except Exception:
23
  pass
24
+ return cons
25
+
26
+ def solve_line(txt):
27
+ syms = default_symbols()
28
+
29
+ # constraints after comma: "eq, 0 <= theta < 2*pi"
30
+ if "," in txt:
31
+ main = txt.split(",", 1)[0].strip()
32
+ cons = parse_constraints(txt.split(",")[1:].copy(), syms)
33
+ else:
34
+ main = txt.strip()
35
+ cons = []
36
+
37
+ if not main:
38
+ return "Empty input."
39
+
40
+ if "=" in main:
41
+ left, right = main.split("=", 1)
42
  try:
43
+ eq = sp.Eq(sp.sympify(left, locals=syms), sp.sympify(right, locals=syms))
44
+ except Exception as e:
45
+ return f"Parse equation failed: {e}"
46
+
47
+ vars_set = set(eq.free_symbols)
48
+ if not vars_set:
49
+ vars_set = {sp.symbols("x", real=True)}
50
+ vars_list = list(vars_set)
51
+
52
+ # try solveset on first var with simple real-domain extraction
53
+ if cons:
54
+ v = vars_list[0]
55
+ domain = sp.S.Reals
56
+ try:
57
+ # If constraints form an And of relationals, keep as boolean condition.
58
+ cond = cons[0]
59
+ for c in cons[1:]:
60
+ cond = sp.And(cond, c)
61
+ # best-effort: do not over-process; pass domain=Reals
62
+ sol = sp.solveset(eq, v, domain=domain)
63
+ return f"solveset({v} in Reals): {sp.simplify(sol)}"
64
+ except Exception:
65
+ pass
66
+
67
+ try:
68
+ sols = sp.solve([eq], vars_list, dict=True)
69
+ if not sols:
70
+ return "No solution or need more conditions."
71
+ lines = []
72
+ for i, s in enumerate(sols, 1):
73
+ parts = []
74
+ for k, v in s.items():
75
+ parts.append(f"{k} = {sp.simplify(v)}")
76
+ lines.append("Solution " + str(i) + ": " + ", ".join(parts))
77
+ return "\n".join(lines)
78
+ except Exception as e:
79
+ return f"Solve failed: {e}"
80
+
81
+ # pure expression branch
82
+ try:
83
+ expr = sp.sympify(main, locals=syms)
84
  except Exception as e:
85
+ return f"Parse failed: {e}"
86
+
87
+ out = []
88
+ try:
89
+ out.append("Simplify: " + str(sp.simplify(expr)))
90
+ except Exception:
91
+ pass
92
+ try:
93
+ fact = sp.factor(expr)
94
+ if fact != expr:
95
+ out.append("Factor: " + str(fact))
96
+ except Exception:
97
+ pass
98
+ try:
99
+ v = list(expr.free_symbols)[0] if expr.free_symbols else sp.symbols("x", real=True)
100
+ out.append("d/d" + str(v) + ": " + str(sp.diff(expr, v)))
101
+ out.append("Integral d" + str(v) + ": " + str(sp.integrate(expr, v)))
102
+ except Exception:
103
+ pass
104
+
105
+ if out:
106
+ return "\n".join(out)
107
+ return "Result: " + str(expr)
108
+
109
+ def solve_math(q):
110
+ q = (q or "").strip()
111
+ if not q:
112
+ return "Enter expression(s) or equation(s). Use semicolons or newlines to separate.\nExamples:\n 2*x + 5 = 11\n sin(theta) = sqrt(3)/2, 0 <= theta < 2*pi\n factor(x**4 - 1)"
113
+ segs = []
114
+ for line in q.splitlines():
115
+ segs.extend([p for p in line.split(";")])
116
+ segs = [s.strip() for s in segs if s.strip()]
117
+ outputs = []
118
+ for s in segs:
119
+ outputs.append(">>> " + s + "\n" + solve_line(s))
120
+ return "\n\n".join(outputs)
121
 
122
+ with gr.Blocks(title="LanguageBridge — Math Fast Agent (SymPy)") as demo:
123
+ gr.Markdown("# LanguageBridge Math Fast Agent (SymPy)")
124
+ gr.Markdown("Paste expressions or equations. Add constraints after a comma. Examples:\n- 2*x + 5 = 11\n- sin(theta) = sqrt(3)/2, 0 <= theta < 2*pi\n- factor(x**4 - 1)")
125
+ q = gr.Textbox(lines=6, label="Problem / Expression (semicolon or newline for systems)")
126
+ out = gr.Textbox(lines=12, label="Output")
127
+ btn = gr.Button("Solve")
128
+ btn.click(fn=solve_math, inputs=q, outputs=out)
129
 
130
  if __name__ == "__main__":
131
+ demo.launch(share=True)