Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -30,34 +30,50 @@ def draw_graph(G, pos=None, title="Graph Visualization"):
|
|
30 |
nx.draw(G, pos=pos, with_labels=True, node_color='lightblue', node_size=500, font_size=10, font_weight='bold')
|
31 |
st.pyplot(plt)
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
def formula_to_string(formula):
|
44 |
def _to_string(formula, root):
|
45 |
-
# If there are no children, this is a variable node.
|
46 |
label = formula.nodes[root]["label"]
|
47 |
if not formula[root]:
|
48 |
return label
|
49 |
-
# Otherwise, this is an operator.
|
50 |
children = formula[root]
|
51 |
-
# If one child, the label must be a NOT operator.
|
52 |
if len(children) == 1:
|
53 |
child = nx.utils.arbitrary_element(children)
|
54 |
return f"{label}({_to_string(formula, child)})"
|
55 |
-
# NB "left" and "right" here are a little misleading: there is
|
56 |
-
# no order on the children of a node. That's okay because the
|
57 |
-
# Boolean AND and OR operators are symmetric. It just means that the
|
58 |
-
# order of the operands cannot be predicted and hence the
|
59 |
-
# function does not necessarily behave the same way on every
|
60 |
-
# invocation.
|
61 |
left, right = formula[root]
|
62 |
left_subformula = _to_string(formula, left)
|
63 |
right_subformula = _to_string(formula, right)
|
@@ -77,7 +93,7 @@ def algorithms_circuits():
|
|
77 |
)
|
78 |
|
79 |
if circuit_mode == "Default Example":
|
80 |
-
# Define the default circuit
|
81 |
circuit = nx.DiGraph()
|
82 |
# Layer 0
|
83 |
circuit.add_node(0, label="∧", layer=0)
|
@@ -119,46 +135,42 @@ def algorithms_circuits():
|
|
119 |
elif circuit_mode == "Create Your Own":
|
120 |
st.write("### Create Your Own Circuit")
|
121 |
|
122 |
-
#
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
nx.draw_networkx(circuit, pos, **options)
|
159 |
-
plt.title(formula_to_string(formula))
|
160 |
-
plt.axis("equal")
|
161 |
-
st.pyplot()
|
162 |
|
163 |
# Display the corresponding page based on sidebar option
|
164 |
if sidebar_option == "Algorithms: Circuits":
|
|
|
30 |
nx.draw(G, pos=pos, with_labels=True, node_color='lightblue', node_size=500, font_size=10, font_weight='bold')
|
31 |
st.pyplot(plt)
|
32 |
|
33 |
+
# Function to convert a sympy Boolean expression to a graph
|
34 |
+
def formula_to_circuit(formula):
|
35 |
+
circuit = nx.DiGraph()
|
36 |
+
node_id = 0
|
37 |
+
def add_formula_node(expr):
|
38 |
+
nonlocal node_id
|
39 |
+
# Create a unique node for each part of the formula
|
40 |
+
current_node = node_id
|
41 |
+
node_id += 1
|
42 |
+
circuit.add_node(current_node, label=str(expr))
|
43 |
+
return current_node
|
44 |
+
|
45 |
+
def build_circuit(expr):
|
46 |
+
if isinstance(expr, symbols):
|
47 |
+
# It's a variable, just return it as a node
|
48 |
+
return add_formula_node(expr)
|
49 |
+
elif isinstance(expr, Not):
|
50 |
+
# NOT operator
|
51 |
+
child = build_circuit(expr.args[0])
|
52 |
+
current_node = add_formula_node("¬")
|
53 |
+
circuit.add_edge(current_node, child)
|
54 |
+
return current_node
|
55 |
+
elif isinstance(expr, Or) or isinstance(expr, And):
|
56 |
+
# OR/AND operators
|
57 |
+
left = build_circuit(expr.args[0])
|
58 |
+
right = build_circuit(expr.args[1])
|
59 |
+
current_node = add_formula_node(str(expr.func))
|
60 |
+
circuit.add_edge(current_node, left)
|
61 |
+
circuit.add_edge(current_node, right)
|
62 |
+
return current_node
|
63 |
+
|
64 |
+
build_circuit(formula)
|
65 |
+
return circuit
|
66 |
+
|
67 |
+
# Function to convert a formula graph to a string for display
|
68 |
def formula_to_string(formula):
|
69 |
def _to_string(formula, root):
|
|
|
70 |
label = formula.nodes[root]["label"]
|
71 |
if not formula[root]:
|
72 |
return label
|
|
|
73 |
children = formula[root]
|
|
|
74 |
if len(children) == 1:
|
75 |
child = nx.utils.arbitrary_element(children)
|
76 |
return f"{label}({_to_string(formula, child)})"
|
|
|
|
|
|
|
|
|
|
|
|
|
77 |
left, right = formula[root]
|
78 |
left_subformula = _to_string(formula, left)
|
79 |
right_subformula = _to_string(formula, right)
|
|
|
93 |
)
|
94 |
|
95 |
if circuit_mode == "Default Example":
|
96 |
+
# Define the default circuit as before
|
97 |
circuit = nx.DiGraph()
|
98 |
# Layer 0
|
99 |
circuit.add_node(0, label="∧", layer=0)
|
|
|
135 |
elif circuit_mode == "Create Your Own":
|
136 |
st.write("### Create Your Own Circuit")
|
137 |
|
138 |
+
# Text input for the Boolean expression
|
139 |
+
boolean_expression = st.text_input("Enter a Boolean expression (e.g., ((x ∨ y) ∧ (y ∨ ¬(z)))):")
|
140 |
+
|
141 |
+
# Generate button
|
142 |
+
if st.button("Generate Circuit"):
|
143 |
+
if boolean_expression:
|
144 |
+
try:
|
145 |
+
# Parse the input expression
|
146 |
+
expr = eval(boolean_expression, {}, {"Or": Or, "And": And, "Not": Not, "x": symbols('x'), "y": symbols('y'), "z": symbols('z')})
|
147 |
+
|
148 |
+
# Convert the formula to a circuit
|
149 |
+
circuit = formula_to_circuit(expr)
|
150 |
+
|
151 |
+
# Display the formula as a string
|
152 |
+
st.write("Formula: ", formula_to_string(circuit))
|
153 |
+
|
154 |
+
# Visualize the circuit
|
155 |
+
labels = nx.get_node_attributes(circuit, "label")
|
156 |
+
options = {
|
157 |
+
"node_size": 600,
|
158 |
+
"alpha": 0.5,
|
159 |
+
"node_color": "blue",
|
160 |
+
"labels": labels,
|
161 |
+
"font_size": 22,
|
162 |
+
}
|
163 |
+
plt.figure(figsize=(8, 8))
|
164 |
+
pos = nx.multipartite_layout(circuit, subset_key="layer")
|
165 |
+
nx.draw_networkx(circuit, pos, **options)
|
166 |
+
plt.title(formula_to_string(circuit))
|
167 |
+
plt.axis("equal")
|
168 |
+
st.pyplot()
|
169 |
+
|
170 |
+
except Exception as e:
|
171 |
+
st.error(f"Error parsing the expression: {e}")
|
172 |
+
else:
|
173 |
+
st.error("Please enter a valid Boolean expression.")
|
|
|
|
|
|
|
|
|
174 |
|
175 |
# Display the corresponding page based on sidebar option
|
176 |
if sidebar_option == "Algorithms: Circuits":
|