Spaces:
Runtime error
Runtime error
Update app.py
Browse files
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 |
-
|
| 9 |
-
from
|
| 10 |
-
|
| 11 |
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 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 |
-
|
| 138 |
-
|
| 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()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|