AI-Quotient commited on
Commit
34a47f0
·
verified ·
1 Parent(s): dd4b396

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +99 -159
app.py CHANGED
@@ -1,144 +1,109 @@
1
- from google import genai
2
- from google.genai import types
3
  import gradio as gr
4
  import os
5
 
 
6
 
 
 
 
7
 
8
- MODEL_ID = "gemini-2.0-flash-thinking-exp"
9
- from google import genai
10
- client = genai.Client(api_key=os.getenv('api_key'))
11
 
12
- def llm_response(text):
13
- response = client.models.generate_content(
14
- model=MODEL_ID,
15
- contents= text)
16
- return response.text
17
-
18
- def pvsnp(problem):
19
- classification = llm_response(f'''
20
- You are an expert in computational complexity theory, specializing in both classical complexity classes (P, NP, NP-complete, NP-hard) and modern developments (e.g., parameterized complexity, fine-grained complexity, Minimum Circuit Size Problem).
21
-
22
- Your task is to classify a given problem into one of the following categories:
23
-
24
- P: Solvable in deterministic polynomial time.
25
-
26
- NP: Verifiable in polynomial time.
27
-
28
- NP-complete: Both in NP and NP-hard.
29
-
30
- NP-hard: At least as hard as NP-complete problems, possibly outside NP.
31
-
32
- Beyond NP: Likely in PSPACE, EXPTIME, or undecidable.
33
-
34
- Other: Fits alternative complexity classes (e.g., BPP, co-NP).
35
-
36
- Problem Description:
37
- {problem}
38
-
39
- If the given problem is a NP-hard problem, decompose the NP-hard problem into polynomial-time solvable subproblems without solving them.
40
-
41
- 🔹 Inputs:
42
- A formal definition and instance of the NP-hard problem (e.g., SAT, TSP, Graph Coloring).
43
-
44
- Optional: Constraints or domain knowledge.
45
-
46
- 🔹 Decomposition Process:
47
- Graph Representation & Structural Analysis
48
-
49
- Convert the problem into a graph (if applicable).
50
-
51
- Identify independent or tractable substructures.
52
-
53
- Classification of Subproblems
54
-
55
- Detect polynomially solvable parts (e.g., tree structures, bipartite graphs).
56
-
57
- Separate them from harder components.
58
-
59
- Partitioning & Transformation
60
-
61
- Break the problem into independent or loosely connected subproblems.
62
-
63
- Ensure each subproblem is in P or provably easier than the original.
64
-
65
- Output a structured breakdown.
66
-
67
- 🔹 Outputs:
68
- A list of P-complexity subproblems.
69
-
70
- A dependency graph of their relationships in ASCII format.
71
-
72
- A complexity analysis report quantifying decomposition effectiveness.
73
-
74
- Guidelines for Classification:
75
- Problem Analysis
76
-
77
- Determine if the problem is a decision, optimization, or function computation problem.
78
-
79
- Identify key input/output characteristics and constraints.
80
-
81
- Complexity Insights
82
-
83
- Check for polynomial-time solvability via known techniques (dynamic programming, greedy methods).
84
-
85
- Assess reductions to/from well-studied problems.
86
-
87
- Advanced Considerations
88
-
89
- Incorporate recent research (e.g., MCSP's implications for NP-completeness).
90
-
91
- Evaluate parameterized complexity (FPT results) and fine-grained complexity (SETH, other conjectures).
92
-
93
- Consider probabilistic or average-case complexity aspects.
94
-
95
- Justification
96
-
97
- Provide a concise explanation for the classification, referencing key problem features and relevant research.
98
-
99
- Your Classification and Explanation:
100
- ''')
101
-
102
- return classification
103
-
104
- def critic_analysis(classification_output):
105
- critic = llm_response(f'''"You are PolyCritic, an expert in computational complexity and problem decomposition. Your goal is to critically evaluate whether a given
106
- NP-hard problem, when broken into P-solvable subproblems, can be efficiently recombined to yield the full solution. Here is the problem and the analysis: {classification_output}
107
-
108
- Instructions:
109
- 1️⃣ Input: A decomposed NP-hard problem along with its P-solvable subproblems.
110
- 2️⃣ Step 1 - Validate Subproblems:
111
-
112
- Do these subproblems fully cover the original problem?
113
-
114
- Are they correctly categorized as P?
115
- 3️⃣ Step 2 - Analyze Recombination Complexity:
116
-
117
- Can the subproblem solutions be combined in polynomial time?
118
-
119
- If not, what is the bottleneck? (e.g., exponential merging, missing constraints)
120
- 4️⃣ Step 3 - Provide Verdict:
121
-
122
- If recombination is efficient, explain why this suggests progress towards P = NP.
123
-
124
- If inefficient, identify where complexity remains and suggest next steps.
125
- 5️⃣ Step 4 - Provide Complexity Insights:
126
-
127
- Offer insights into whether certain structural patterns predict efficient recombination.
128
-
129
- Suggest improvements in decomposition strategies.
130
-
131
- Example Analysis Format:
132
- 💡 Problem: Traveling Salesperson (TSP)
133
- 🔍 Subproblems: Shortest paths between city clusters (P-solvable)
134
- ⚖ Recombination Complexity: Exponential growth in possible paths when merging clusters
135
- 🚨 Verdict: Recombination remains NP-hard → Decomposition needs refinement
136
 
137
- 👉 Your task is to apply this structured critique to any NP-hard problem and determine if it truly reduces to P.''')
138
- return critic
139
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
140
 
141
- '''
142
  iface = gr.Interface(
143
  fn=pvsnp,
144
  inputs=gr.Textbox(label="What problem would you like to classify as P or NP?"),
@@ -150,29 +115,4 @@ iface = gr.Interface(
150
  )
151
 
152
  # Launch the app
153
- iface.launch() '''
154
-
155
- with gr.Blocks(theme=gr.themes.Ocean()) as app:
156
- gr.Markdown("# PolyProb & PolyCritic AI 🤖")
157
- gr.Markdown('''PolyProb and PolyCritic are AI Agents that help users classify a problem into categories such as P, NP, NP-complete, NP-hard while
158
- providing clear, concise explanations of its reasoning. As part of AI Quotient’s Millennium Math Challenge, it is the first step towards solving the P vs NP problem.''')
159
-
160
- with gr.Row():
161
- problem_input = gr.Textbox(label="Enter a computational problem")
162
- classify_button = gr.Button("Classify")
163
-
164
- classification_output = gr.Markdown(label="Classification (P or NP)")
165
-
166
- classify_button.click(pvsnp, inputs=problem_input, outputs=[classification_output])
167
-
168
- evaluate_button = gr.Button("Evaluate Recombination Complexity")
169
- recombination_output = gr.Textbox(label="Recombination Complexity")
170
-
171
- evaluate_button.click(critic_analysis, inputs=classification_output, outputs=recombination_output)
172
-
173
- #results_button = gr.Button("Show Stored Results")
174
- #results_display = gr.Textbox(label="Stored Results")
175
-
176
- #results_button.click(get_stored_results, outputs=results_display)
177
-
178
- app.launch()
 
 
 
1
  import gradio as gr
2
  import os
3
 
4
+ os.environ["OPENAI_API_KEY"] = os.getenv('api_key')
5
 
6
+ import math
7
+ import types
8
+ import uuid
9
 
10
+ from langchain.chat_models import init_chat_model
11
+ from langchain.embeddings import init_embeddings
12
+ from langgraph.store.memory import InMemoryStore
13
 
14
+ from langgraph_bigtool import create_agent
15
+ from langgraph_bigtool.utils import (
16
+ convert_positional_only_function_to_tool
17
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
+ # Collect functions from `math` built-in
20
+ all_tools = []
21
+ for function_name in dir(math):
22
+ function = getattr(math, function_name)
23
+ if not isinstance(
24
+ function, types.BuiltinFunctionType
25
+ ):
26
+ continue
27
+ # This is an idiosyncrasy of the `math` library
28
+ if tool := convert_positional_only_function_to_tool(
29
+ function
30
+ ):
31
+ all_tools.append(tool)
32
+
33
+ # Create registry of tools. This is a dict mapping
34
+ # identifiers to tool instances.
35
+ tool_registry = {
36
+ str(uuid.uuid4()): tool
37
+ for tool in all_tools
38
+ }
39
+
40
+ # Index tool names and descriptions in the LangGraph
41
+ # Store. Here we use a simple in-memory store.
42
+ embeddings = init_embeddings("openai:text-embedding-3-small")
43
+
44
+ store = InMemoryStore(
45
+ index={
46
+ "embed": embeddings,
47
+ "dims": 1536,
48
+ "fields": ["description"],
49
+ }
50
+ )
51
+ for tool_id, tool in tool_registry.items():
52
+ store.put(
53
+ ("tools",),
54
+ tool_id,
55
+ {
56
+ "description": f"{tool.name}: {tool.description}",
57
+ },
58
+ )
59
+
60
+ # Initialize agent
61
+ llm = init_chat_model("openai:gpt-4o-mini")
62
+
63
+ builder = create_agent(llm, tool_registry)
64
+ agent = builder.compile(store=store)
65
+
66
+ from langchain_core.tools import Tool
67
+ import sympy
68
+ from sympy import symbols
69
+
70
+ def make_sympy_tool(func, name, description):
71
+ def _tool(expr: str) -> str:
72
+ local_symbols = symbols("x y z a b c n")
73
+ parsed_expr = sympy.sympify(expr, locals={s.name: s for s in local_symbols})
74
+ result = func(parsed_expr)
75
+ return str(result)
76
+
77
+ return Tool.from_function(
78
+ name=name,
79
+ description=description,
80
+ func=_tool
81
+ )
82
+
83
+ from sympy import simplify, expand, factor
84
+
85
+ sympy_tools = [
86
+ make_sympy_tool(simplify, "simplify", "Simplifies a symbolic expression"),
87
+ make_sympy_tool(expand, "expand", "Expands a symbolic expression"),
88
+ make_sympy_tool(factor, "factor", "Factors a symbolic expression"),
89
+ ]
90
+
91
+ for tool in sympy_tools:
92
+ tool_id = str(uuid.uuid4())
93
+ tool_registry[tool_id] = tool
94
+ store.put(
95
+ ("tools",),
96
+ tool_id,
97
+ {"description": f"{tool.name}: {tool.description}"},
98
+ )
99
+
100
+ builder = create_agent(llm, tool_registry)
101
+ agent = builder.compile(store=store)
102
+
103
+
104
+
105
+
106
 
 
107
  iface = gr.Interface(
108
  fn=pvsnp,
109
  inputs=gr.Textbox(label="What problem would you like to classify as P or NP?"),
 
115
  )
116
 
117
  # Launch the app
118
+ iface.launch()