amirali1985 commited on
Commit
3ef0762
·
1 Parent(s): 2106e26

minimal circuit.

Browse files
Files changed (1) hide show
  1. app.py +25 -13
app.py CHANGED
@@ -1,11 +1,12 @@
1
  import os
2
  import glob
3
  from pathlib import Path
4
- import traceback
5
 
6
  import gradio as gr
7
  import jpype
8
  import jpype.imports
 
 
9
  from jpype import JClass, getDefaultJVMPath
10
 
11
  def _find_psl_jars() -> list[str]:
@@ -20,7 +21,6 @@ def _find_psl_jars() -> list[str]:
20
  # 2) Local ./jars
21
  this_dir = Path(__file__).resolve().parent
22
  jars_dir = f"{this_dir}/.jars"
23
- print(f"Jars dir is {jars_dir}")
24
  jars.extend(glob.glob(f"{jars_dir}/*.jar"))
25
 
26
  # Deduplicate while preserving order
@@ -171,30 +171,43 @@ def _pred_name(lit: str) -> str:
171
  def _is_negated(lit: str) -> bool:
172
  return lit.strip().startswith('!')
173
 
174
- def rules_to_graphviz_image_bytes(rules=RULES) -> bytes:
 
 
 
 
175
  g = Digraph(name="CircuitMinimality", format="png", engine="dot")
176
  g.attr(rankdir="LR", fontname="Helvetica")
177
  g.node_attr.update(shape="box", style="rounded,filled", fillcolor="#f8f8f8", fontname="Helvetica")
178
 
 
 
 
 
 
 
179
  # Nodes
180
  preds = set()
181
  for r in rules:
182
- preds.update(_pred_name(x) for x in (r["body"] + [r["head"]]))
183
  for p in sorted(preds):
184
  g.node(p)
185
 
186
  # Edges
187
  for r in rules:
188
  head_lit = r["head"]
189
- head_pred = _pred_name(head_lit)
190
- neg_head = _is_negated(head_lit)
191
  color = "#2ca02c" if not neg_head else "#d62728"
192
  style = "solid" if not neg_head else "dashed"
193
  label = f"{r['name']} ({'HARD' if r.get('hard', False) else r.get('weight', '')})".strip()
194
  for b in r["body"]:
195
- g.edge(_pred_name(b), head_pred, color=color, fontcolor=color, style=style, penwidth="2", label=label)
196
 
197
- return g.pipe(format="png")
 
 
 
198
 
199
  def _rules_commentary_md(rules=RULES) -> str:
200
  lines = ["### Rule Commentary", ""]
@@ -227,14 +240,13 @@ add_rules(model, RULES)
227
 
228
  # 3) Build commentary and graph image
229
  COMMENTARY_MD = _rules_commentary_md(RULES)
230
- GRAPH_PNG = rules_to_graphviz_image_bytes(RULES)
231
 
232
- # --- Static Gradio UI ---
233
- with gr.Blocks(title="PSL Minimal-Circuit Rules") as demo:
234
- gr.Markdown("## PSL Minimal-Circuit • Overview")
235
  gr.Markdown(f"**JVM status:**\n\n{JVM_STATUS}")
236
  gr.Markdown(COMMENTARY_MD)
237
- gr.Image(value=GRAPH_PNG, label="Rule Graph (green = positive head, red dashed = negated head)")
238
 
239
  if __name__ == "__main__":
240
  demo.launch()
 
1
  import os
2
  import glob
3
  from pathlib import Path
 
4
 
5
  import gradio as gr
6
  import jpype
7
  import jpype.imports
8
+
9
+ from graphviz import Digraph
10
  from jpype import JClass, getDefaultJVMPath
11
 
12
  def _find_psl_jars() -> list[str]:
 
21
  # 2) Local ./jars
22
  this_dir = Path(__file__).resolve().parent
23
  jars_dir = f"{this_dir}/.jars"
 
24
  jars.extend(glob.glob(f"{jars_dir}/*.jar"))
25
 
26
  # Deduplicate while preserving order
 
171
  def _is_negated(lit: str) -> bool:
172
  return lit.strip().startswith('!')
173
 
174
+ def rules_to_graphviz_file(rules=RULES, basename: str = "rules_graph") -> str:
175
+ """
176
+ Render Graphviz to a PNG on disk and return the filepath.
177
+ Produces 'basename.png' next to your app.
178
+ """
179
  g = Digraph(name="CircuitMinimality", format="png", engine="dot")
180
  g.attr(rankdir="LR", fontname="Helvetica")
181
  g.node_attr.update(shape="box", style="rounded,filled", fillcolor="#f8f8f8", fontname="Helvetica")
182
 
183
+ def pred_name(lit: str) -> str:
184
+ return lit.lstrip('!').split('(')[0].strip()
185
+
186
+ def is_negated(lit: str) -> bool:
187
+ return lit.strip().startswith('!')
188
+
189
  # Nodes
190
  preds = set()
191
  for r in rules:
192
+ preds.update(pred_name(x) for x in (r["body"] + [r["head"]]))
193
  for p in sorted(preds):
194
  g.node(p)
195
 
196
  # Edges
197
  for r in rules:
198
  head_lit = r["head"]
199
+ head_pred = pred_name(head_lit)
200
+ neg_head = is_negated(head_lit)
201
  color = "#2ca02c" if not neg_head else "#d62728"
202
  style = "solid" if not neg_head else "dashed"
203
  label = f"{r['name']} ({'HARD' if r.get('hard', False) else r.get('weight', '')})".strip()
204
  for b in r["body"]:
205
+ g.edge(pred_name(b), head_pred, color=color, fontcolor=color, style=style, penwidth="2", label=label)
206
 
207
+ # Render to file: returns full path without extension; add '.png'
208
+ out = g.render(filename=basename, cleanup=True) # writes basename.png
209
+ png_path = out if out.endswith(".png") else f"{out}.png"
210
+ return png_path
211
 
212
  def _rules_commentary_md(rules=RULES) -> str:
213
  lines = ["### Rule Commentary", ""]
 
240
 
241
  # 3) Build commentary and graph image
242
  COMMENTARY_MD = _rules_commentary_md(RULES)
243
+ GRAPH_PATH = rules_to_graphviz_file(RULES, basename="rules_graph")
244
 
245
+ with gr.Blocks(title="PSL Minimal-Circuit Rules (Static)") as demo:
246
+ gr.Markdown("## PSL Minimal-Circuit • Static Overview")
 
247
  gr.Markdown(f"**JVM status:**\n\n{JVM_STATUS}")
248
  gr.Markdown(COMMENTARY_MD)
249
+ gr.Image(value=GRAPH_PATH, label="Rule Graph (green = positive head, red dashed = negated head)")
250
 
251
  if __name__ == "__main__":
252
  demo.launch()