aciang's picture
Upload folder using huggingface_hub
8a4e70b verified
raw
history blame
4.29 kB
import gradio as gr
import sympy as sp
def default_symbols():
names = ["x","y","z","t","theta","a","b","c","n","m"]
d = {name: sp.symbols(name, real=True) for name in names}
d["pi"] = sp.pi
d["e"] = sp.E
d["sqrt"] = sp.sqrt
return d
def parse_constraints(parts, syms):
cons = []
for p in parts:
s = p.strip()
if not s:
continue
try:
rel = sp.sympify(s, locals=syms)
cons.append(rel)
except Exception:
pass
return cons
def solve_line(txt):
syms = default_symbols()
# constraints after comma: "eq, 0 <= theta < 2*pi"
if "," in txt:
main = txt.split(",", 1)[0].strip()
cons = parse_constraints(txt.split(",")[1:].copy(), syms)
else:
main = txt.strip()
cons = []
if not main:
return "Empty input."
if "=" in main:
left, right = main.split("=", 1)
try:
eq = sp.Eq(sp.sympify(left, locals=syms), sp.sympify(right, locals=syms))
except Exception as e:
return f"Parse equation failed: {e}"
vars_set = set(eq.free_symbols)
if not vars_set:
vars_set = {sp.symbols("x", real=True)}
vars_list = list(vars_set)
# try solveset on first var with simple real-domain extraction
if cons:
v = vars_list[0]
domain = sp.S.Reals
try:
# If constraints form an And of relationals, keep as boolean condition.
cond = cons[0]
for c in cons[1:]:
cond = sp.And(cond, c)
# best-effort: do not over-process; pass domain=Reals
sol = sp.solveset(eq, v, domain=domain)
return f"solveset({v} in Reals): {sp.simplify(sol)}"
except Exception:
pass
try:
sols = sp.solve([eq], vars_list, dict=True)
if not sols:
return "No solution or need more conditions."
lines = []
for i, s in enumerate(sols, 1):
parts = []
for k, v in s.items():
parts.append(f"{k} = {sp.simplify(v)}")
lines.append("Solution " + str(i) + ": " + ", ".join(parts))
return "\n".join(lines)
except Exception as e:
return f"Solve failed: {e}"
# pure expression branch
try:
expr = sp.sympify(main, locals=syms)
except Exception as e:
return f"Parse failed: {e}"
out = []
try:
out.append("Simplify: " + str(sp.simplify(expr)))
except Exception:
pass
try:
fact = sp.factor(expr)
if fact != expr:
out.append("Factor: " + str(fact))
except Exception:
pass
try:
v = list(expr.free_symbols)[0] if expr.free_symbols else sp.symbols("x", real=True)
out.append("d/d" + str(v) + ": " + str(sp.diff(expr, v)))
out.append("Integral d" + str(v) + ": " + str(sp.integrate(expr, v)))
except Exception:
pass
if out:
return "\n".join(out)
return "Result: " + str(expr)
def solve_math(q):
q = (q or "").strip()
if not q:
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)"
segs = []
for line in q.splitlines():
segs.extend([p for p in line.split(";")])
segs = [s.strip() for s in segs if s.strip()]
outputs = []
for s in segs:
outputs.append(">>> " + s + "\n" + solve_line(s))
return "\n\n".join(outputs)
with gr.Blocks(title="LanguageBridge — Math Fast Agent (SymPy)") as demo:
gr.Markdown("# LanguageBridge — Math Fast Agent (SymPy)")
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)")
q = gr.Textbox(lines=6, label="Problem / Expression (semicolon or newline for systems)")
out = gr.Textbox(lines=12, label="Output")
btn = gr.Button("Solve")
btn.click(fn=solve_math, inputs=q, outputs=out)
if __name__ == "__main__":
demo.launch(share=True)