Aroy1997 commited on
Commit
ca82ef2
ยท
verified ยท
1 Parent(s): 8714049

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +190 -0
app.py ADDED
@@ -0,0 +1,190 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ import gradio as gr
3
+ import numpy as np
4
+ import matplotlib.pyplot as plt
5
+ import sympy as sp
6
+ import yaml
7
+ import requests
8
+
9
+ x, y = sp.symbols('x y')
10
+
11
+ # Load theorems database
12
+ def load_theorems(file="theorems.yaml"):
13
+ with open(file, 'r') as f:
14
+ return yaml.safe_load(f)
15
+
16
+ theorems_db = load_theorems()
17
+
18
+ # Helper to construct LLM explanation prompt
19
+ def build_llm_prompt(context, eq_type="polynomial"):
20
+ selected = [t for t in theorems_db if ("polynomial" in t["tags"] if eq_type == "polynomial" else "linear" in t["tags"])]
21
+ theory_context = "\n".join([f"{t['name']}: {t['short_explanation']}" for t in selected])
22
+ return f"Context:\n{theory_context}\n\nQuestion:\nExplain how the following was solved:\n{context}"
23
+
24
+ # Call LLM microservice
25
+ def get_llm_explanation(context, url, eq_type):
26
+ try:
27
+ prompt = build_llm_prompt(context, eq_type)
28
+ resp = requests.post(f"{url}/explain", json={"prompt": prompt})
29
+ if resp.status_code == 200:
30
+ return resp.json().get("explanation", "โŒ No explanation returned.")
31
+ return f"โŒ LLM returned status {resp.status_code}"
32
+ except Exception as e:
33
+ return f"โŒ LLM request failed: {e}"
34
+
35
+ # Generate polynomial template
36
+ def generate_polynomial_template(degree):
37
+ terms = [f"a{i}*x^{degree - i}" for i in range(degree)] + [f"a{degree}"]
38
+ return " + ".join(terms) + " = 0"
39
+
40
+ # Solve and plot polynomial
41
+ def solve_polynomial(degree, coeff_string):
42
+ try:
43
+ coeffs = [sp.sympify(s) for s in coeff_string.strip().split()]
44
+ if len(coeffs) != degree + 1:
45
+ return f"โš ๏ธ Please enter exactly {degree + 1} coefficients.", None, None
46
+
47
+ poly = sum([coeffs[i] * x**(degree - i) for i in range(degree + 1)])
48
+ simplified = sp.simplify(poly)
49
+
50
+ # Factor step-by-step
51
+ factored_steps = []
52
+ current_expr = simplified
53
+ while True:
54
+ factored = sp.factor(current_expr)
55
+ if factored == current_expr:
56
+ break
57
+ factored_steps.append(factored)
58
+ current_expr = factored
59
+
60
+ roots = sp.solve(sp.Eq(simplified, 0), x)
61
+ root_display = []
62
+ for i, r in enumerate(roots):
63
+ r_simplified = sp.nsimplify(r, rational=True)
64
+ root_display.append(f"r_{{{i+1}}} = {sp.latex(r_simplified)}")
65
+
66
+ steps_output = f"### ๐Ÿง Polynomial Expression\n\n$$ {sp.latex(poly)} = 0 $$\n\n"
67
+ steps_output += f"### โœ๏ธ Simplified\n\n$$ {sp.latex(simplified)} = 0 $$\n\n"
68
+
69
+ if factored_steps:
70
+ steps_output += f"### ๐Ÿชœ Step-by-Step Factorization\n\n"
71
+ for i, step in enumerate(factored_steps, 1):
72
+ steps_output += f"**Step {i}:** $$ {sp.latex(step)} = 0 $$\n\n"
73
+ else:
74
+ steps_output += f"### ๐Ÿคท No further factorization possible\n\n"
75
+
76
+ steps_output += "### ๐Ÿฅฎ Roots\n\n$$ " + " \\quad ".join(root_display) + " $$"
77
+
78
+ f_lambdified = sp.lambdify(x, simplified, modules=["numpy"])
79
+ x_vals = np.linspace(-10, 10, 400)
80
+ y_vals = f_lambdified(x_vals)
81
+
82
+ fig, ax = plt.subplots(figsize=(6, 4))
83
+ ax.plot(x_vals, y_vals, label="Polynomial")
84
+ ax.axhline(0, color='black', linewidth=0.5)
85
+ ax.axvline(0, color='black', linewidth=0.5)
86
+ ax.grid(True)
87
+ ax.set_title("๐Ÿ“ˆ Graph of the Polynomial")
88
+ ax.set_xlabel("x")
89
+ ax.set_ylabel("f(x)")
90
+
91
+ real_roots = [sp.N(r.evalf()) for r in roots if sp.im(r) == 0]
92
+ for r in real_roots:
93
+ ax.plot([float(r)], [0], 'ro', label="Real Root")
94
+
95
+ ax.legend()
96
+
97
+ return steps_output, fig, steps_output
98
+
99
+ except Exception as e:
100
+ return f"โŒ Error: {e}", None, ""
101
+
102
+ # Solve linear system
103
+ def solve_linear_system(eq1_str, eq2_str):
104
+ try:
105
+ eq1 = sp.sympify(eq1_str)
106
+ eq2 = sp.sympify(eq2_str)
107
+
108
+ sol = sp.solve((eq1, eq2), (x, y), dict=True)
109
+
110
+ steps = "### ๐Ÿ” Solving System\n\n"
111
+ steps += f"**Equation 1:** $$ {sp.latex(eq1)} $$\n\n"
112
+ steps += f"**Equation 2:** $$ {sp.latex(eq2)} $$\n\n"
113
+
114
+ if sol:
115
+ sol = sol[0]
116
+ steps += f"**Solution:** $$ x = {sp.latex(sol[x])}, \\ y = {sp.latex(sol[y])} $$\n\n"
117
+ else:
118
+ steps += "**No unique solution or inconsistent system**\n"
119
+
120
+ x_vals = np.linspace(-10, 10, 400)
121
+ f1 = sp.solve(eq1, y)
122
+ f2 = sp.solve(eq2, y)
123
+
124
+ fig, ax = plt.subplots(figsize=(6, 4))
125
+ if f1 and f2:
126
+ y1 = sp.lambdify(x, f1[0], modules=['numpy'])(x_vals)
127
+ y2 = sp.lambdify(x, f2[0], modules=['numpy'])(x_vals)
128
+ ax.plot(x_vals, y1, label='Equation 1')
129
+ ax.plot(x_vals, y2, label='Equation 2')
130
+
131
+ if sol:
132
+ px = float(sp.N(sol[x]))
133
+ py = float(sp.N(sol[y]))
134
+ ax.plot(px, py, 'ro')
135
+ ax.annotate(f"({px:.2f}, {py:.2f})", (px, py), textcoords="offset points", xytext=(10, 5), ha='center', color='red')
136
+
137
+ ax.axhline(0, color='black', linewidth=0.5)
138
+ ax.axvline(0, color='black', linewidth=0.5)
139
+ ax.set_title("๐Ÿ“‰ Graph of the Linear System")
140
+ ax.set_xlabel("x")
141
+ ax.set_ylabel("y")
142
+ ax.grid(True)
143
+ ax.legend()
144
+
145
+ return steps, fig, steps
146
+
147
+ except Exception as e:
148
+ return f"โŒ Error: {e}", None, ""
149
+
150
+ # UI
151
+ def build_ui():
152
+ with gr.Blocks() as demo:
153
+ gr.Markdown("## ๐Ÿ”ข Polynomial & Linear System Solver with Step-by-Step Explanation")
154
+
155
+ with gr.Tab("Polynomial"):
156
+ with gr.Row():
157
+ degree_slider = gr.Slider(1, 8, value=3, step=1, label="Degree")
158
+ template_display = gr.Textbox(label="Template", interactive=False)
159
+
160
+ coeff_input = gr.Textbox(label="Coefficients", placeholder="e.g. 1 -3 sqrt(2) -pi")
161
+ steps_md = gr.Markdown()
162
+ plot_output = gr.Plot()
163
+ error_box = gr.Textbox(visible=False)
164
+ explanation_md = gr.Markdown()
165
+ llm_url = gr.Textbox(label="LLM URL", placeholder="https://your-llm.ngrok-free.app")
166
+
167
+ degree_slider.change(generate_polynomial_template, degree_slider, template_display)
168
+ solve_btn = gr.Button("Solve Polynomial", variant="primary")
169
+ solve_btn.click(solve_polynomial, [degree_slider, coeff_input], [steps_md, plot_output, error_box])
170
+
171
+ explain_btn = gr.Button("Explain Polynomial Solution", variant="primary")
172
+ explain_btn.click(lambda context, url: get_llm_explanation(context, url, "polynomial"), [steps_md, llm_url], explanation_md)
173
+
174
+ with gr.Tab("Linear System"):
175
+ eq1_input = gr.Textbox(label="Equation 1", placeholder="2*x + 3*y - 6")
176
+ eq2_input = gr.Textbox(label="Equation 2", placeholder="-x + y - 2")
177
+ sys_steps = gr.Markdown()
178
+ sys_plot = gr.Plot()
179
+ sys_explain = gr.Markdown()
180
+
181
+ solve_sys_btn = gr.Button("Solve Linear System", variant="primary")
182
+ solve_sys_btn.click(solve_linear_system, [eq1_input, eq2_input], [sys_steps, sys_plot])
183
+
184
+ explain_sys_btn = gr.Button("Explain Linear Solution", variant="primary")
185
+ explain_sys_btn.click(lambda context, url: get_llm_explanation(context, url, "linear"), [sys_steps, llm_url], sys_explain)
186
+
187
+ return demo
188
+
189
+ if __name__ == "__main__":
190
+ build_ui().launch()