summrs commited on
Commit
b39c815
·
verified ·
1 Parent(s): 0638ab3

import subprocess
import math
import gradio as gr

# Ensure required packages are installed
def install(package):
subprocess.check_call(["pip", "install", package])

install("gradio")

# =========================
# Mathematical Formulas (from the paper and our implementation)
# =========================
formulas = {
"Wiener Index (W)":
"W = Σ d(u,v)\nwhere d(u,v) is the shortest-path distance between every unordered pair of vertices.",
"First Zagreb Index (M₁)":
"M₁ = Σ [deg(v)] for v ∈ V(G)\n(This sums the degrees of all vertices.)",
"Second Zagreb Index (M₂)":
"M₂ = Σ [deg(u) × deg(v)] for each edge uv ∈ E(G)\n(This sums the product of the degrees for each edge.)",
"Randić Index (R)":
"R = Σ [1 / √(deg(u) × deg(v))] for each edge uv ∈ E(G)\n(This measures connectivity by using the inverse square root of vertex degree products.)",
"Atom-Bond Connectivity Index (ABC)":
"ABC = Σ √((deg(u)+deg(v)-2)/(deg(u)×deg(v))) for each edge uv ∈ E(G)\n(This index relates to the molecular stability in chemical graphs.)",
"Augmented Zagreb Index (AZI)":
"AZI = Σ [(deg(u)×deg(v))/(deg(u)+deg(v)-2)]³ for each edge uv ∈ E(G)\n(This index amplifies the contribution of high-degree vertices.)",
"Geometric-Arithmetic Index (GA)":
"GA = Σ [2×√(deg(u)×deg(v))/(deg(u)+deg(v))] for each edge uv ∈ E(G)\n(This index blends the geometric and arithmetic means of vertex degrees.)",
"Sum-Connectivity Index (SCI)":
"SCI = Σ [1/√(deg(u)+deg(v))] for each edge uv ∈ E(G)\n(This index focuses on the sum of the degrees.)",
"Harmonic Index (Harm)":
"Harm = Σ [2/(deg(u)+deg(v))] for each edge uv ∈ E(G)\n(A measure emphasizing balanced degrees.)",
"Gutman Index (Gut)":
"Gut = Σ [deg(u)×deg(v)×d(u,v)] for every unordered pair u,v\n(This index combines connectivity with distance information.)",
"Eccentric Connectivity Index (ECI)":
"ECI = Σ [deg(v)×ecc(v)] for every vertex v\n(Here, ecc(v) is the maximum distance from v to any other vertex.)",
"Total Eccentricity (TE)":
"TE = Σ [ecc(v)] for every vertex v\n(This sums the eccentricity of each vertex.)",
"Harary Index (H)":
"H = Σ [1/d(u,v)] for every unordered pair u,v\n(This sums the reciprocals of distances for each vertex pair.)"
}

# ==========================
# Functions to update which input groups are visible based on the selected index
# ==========================
def update_inputs(selected_index):
# Indices that use vertex-based values only: M₁, TE, ECI.
vertex_vis = selected_index in ["First Zagreb Index (M₁)", "Total Eccentricity (TE)",
"Eccentric Connectivity Index (ECI)"]
# Indices that use edge-based inputs: M₂, R, ABC, AZI, GA, SCI, Harm.
edge_vis = selected_index in ["Second Zagreb Index (M₂)",
"Randić Index (R)",
"Atom-Bond Connectivity Index (ABC)",
"Augmented Zagreb Index (AZI)",
"Geometric-Arithmetic Index (GA)",
"Sum-Connectivity Index (SCI)",
"Harmonic Index (Harm)"]
# Gutman index uses its own group.
gutman_vis = (selected_index == "Gutman Index (Gut)")
# Wiener and Harary indices use distance inputs.
distance_vis = selected_index in ["Wiener Index (W)", "Harary Index (H)"]
return (
gr.update(visible=vertex_vis),
gr.update(visible=edge_vis),
gr.update(visible=gutman_vis),
gr.update(visible=distance_vis)
)

# ==========================
# Calculation Functions
# (For simplicity, we assume a triangle graph with 3 vertices, 3 edges, and 3 unordered pairs.)
# ==========================
def solve_index(selected_index, vertex_deg1, vertex_deg2, vertex_deg3,
vertex_ecc1, vertex_ecc2, vertex_ecc3,
edge1_a, edge1_b, edge2_a, edge2_b, edge3_a, edge3_b,
gutman_degs, gutman_dists,
distance1, distance2, distance3):
try:
# -----------------------
# Vertex-based Calculations
# -----------------------
if selected_index == "First Zagreb Index (M₁)":
degrees = [vertex_deg1, vertex_deg2, vertex_deg3]
result = sum(degrees)
steps = [
f"Step 1: Record the degree of each vertex: {degrees}.",
f"Step 2: Sum all vertex degrees since M₁ is defined as Σ deg(v): {degrees[0]} + {degrees[1]} + {degrees[2]} = {result}."
]
return f"### First Zagreb Index (M₁)\n{formulas[selected_index]}\n\nDetailed Steps:\n" + "\n".join(steps)

elif selected_index == "Total Eccentricity (TE)":
ecc = [vertex_ecc1, vertex_ecc2, vertex_ecc3]
result = sum(ecc)
steps = [
f"Step 1: Record the eccentricity (maximum distance) for each vertex: {ecc}.",
f"Step 2: Sum all eccentricities since TE is defined as Σ ecc(v): {ecc[0]} + {ecc[1]} + {ecc[2]} = {result}."
]
return f"### Total Eccentricity (TE)\n{formulas[selected_index]}\n\nDetailed Steps:\n" + "\n".join(steps)

elif selected_index == "Eccentric Connectivity Index (ECI)":
pairs = [(vertex_deg1, vertex_ecc1), (vertex_deg2, vertex_ecc2), (vertex_deg3, vertex_ecc3)]
contributions = [d * e for d, e in pairs]
result = sum(contributions)
steps = [
f"Step 1: For each vertex, record the pair (degree, eccentricity): {pairs}.",
f"Step 2: Multiply the degree and eccentricity for each vertex: {contributions} (because ECI = Σ [deg(v)×ecc(v)]).",
f"Step 3: Sum these products: {contributions[0]} + {contributions[1]} + {contributions[2]} = {result}."
]
return f"### Eccentric Connectivity Index (ECI)\n{formulas[selected_index]}\n\nDetailed Steps:\n" + "\n".join(steps)

# -----------------------
# Edge-based Calculations
# -----------------------
elif selected_index in ["Second Zagreb Index (M₂)", "Randić Index (R)",
"Atom-Bond Connectivity Index (ABC)", "Augmented Zagreb Index (AZI)",
"Geometric-Arithmetic Index (GA)", "Sum-Connectivity Index (SCI)",
"Harmonic Index (Harm)"]:
edges = [(edge1_a, edge1_b), (edge2_a, edge2_b), (edge3_a, edge3_b)]
if selected_index == "Second Zagreb Index (M₂)":
products = [a * b for a, b in edges]
result = sum(products)
steps = [
f"Step 1: Each edge connects two vertices with degrees as given: {edges}.",
f"Step 2: For each edge, multiply the degrees: {products} (since M₂ sums the product for each edge).",
f"Step 3: Sum these products: {products[0]} + {products[1]} + {products[2]} = {result}."
]
elif selected_index == "Randić Index (R)":
values = [1 / math.sqrt(a * b) for a, b in edges]
result = sum(values)
steps = [
f"Step 1: Record the degree pairs for each edge: {edges}.",
f"Step 2: For each edge, compute 1/√(deg(u)×deg(v)): {['{:.4f}'.format(v) for v in values]}.",
f"Step 3: Sum these values to obtain R: {result:.4f}."
]
elif selected_index == "Atom-Bond Connectivity Index (ABC)":
values = [math.sqrt((a + b - 2) / (a * b)) for a, b in edges]
result = sum(values)
steps = [
f"Step 1: For each edge, note the degree pair: {edges}.",
f"Step 2: Compute √((deg(u)+deg(v)-2)/(deg(u)×deg(v))) for each edge: {['{:.4f}'.format(v) for v in values]}.",
f"Step 3: Sum the results: {result:.4f}."
]
elif selected_index == "Augmented Zagreb Index (AZI)":
values = []
for a, b in edges:
denom = a + b - 2
val = (a * b / denom) ** 3 if denom != 0 else 0
values.append(val)
result = sum(values)
steps = [
f"Step 1: For each edge, record degrees: {edges}.",
f"Step 2: For each, compute ( (deg(u)×deg(v))/(deg(u)+deg(v)-2) )³: {['{:.4f}'.format(v) for v in values]}.",
f"Step 3: Sum these values: {result:.4f}."
]
elif selected_index == "Geometric-Arithmetic Index (GA)":
values = [(2 * math.sqrt(a * b))/(a + b) for a, b in edges]
result = sum(values)
steps = [
f"Step 1: Record edge degree pairs: {edges}.",
f"Step 2: For each edge, calculate 2×√(deg(u)×deg(v))/(deg(u)+deg(v)): {['{:.4f}'.format(v) for v in values]}.",
f"Step 3: Sum to obtain GA: {result:.4f}."
]
elif selected_index == "Sum-Connectivity Index (SCI)":
values = [1 / math.sqrt(a + b) for a, b in edges]
result = sum(values)
steps = [
f"Step 1: Note the degree pairs for each edge: {edges}.",
f"Step 2: For each edge, compute 1/√(deg(u)+deg(v)): {['{:.4f}'.format(v) for v in values]}.",
f"Step 3: Sum the computed values to get SCI: {result:.4f}."
]
elif selected_index == "Harmonic Index (Harm)":
values = [2 / (a + b) for a, b in edges]
result = sum(values)
steps = [
f"Step 1: Record the edge degree pairs: {edges}.",
f"Step 2: For each edge, compute 2/(deg(u)+deg(v)): {['{:.4f}'.format(v) for v in values]}.",
f"Step 3: Sum these values

Files changed (1) hide show
  1. app.py +305 -0
app.py ADDED
@@ -0,0 +1,305 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import subprocess
2
+ import math
3
+ import gradio as gr
4
+
5
+ # Ensure required packages are installed
6
+ def install(package):
7
+ subprocess.check_call(["pip", "install", package])
8
+
9
+ install("gradio")
10
+
11
+ # =========================
12
+ # Mathematical Formulas (from the paper and our implementation)
13
+ # =========================
14
+ formulas = {
15
+ "Wiener Index (W)":
16
+ "W = Σ d(u,v)\nwhere d(u,v) is the shortest-path distance between every unordered pair of vertices.",
17
+ "First Zagreb Index (M₁)":
18
+ "M₁ = Σ [deg(v)] for v ∈ V(G)\n(This sums the degrees of all vertices.)",
19
+ "Second Zagreb Index (M₂)":
20
+ "M₂ = Σ [deg(u) × deg(v)] for each edge uv ∈ E(G)\n(This sums the product of the degrees for each edge.)",
21
+ "Randić Index (R)":
22
+ "R = Σ [1 / √(deg(u) × deg(v))] for each edge uv ∈ E(G)\n(This measures connectivity by using the inverse square root of vertex degree products.)",
23
+ "Atom-Bond Connectivity Index (ABC)":
24
+ "ABC = Σ √((deg(u)+deg(v)-2)/(deg(u)×deg(v))) for each edge uv ∈ E(G)\n(This index relates to the molecular stability in chemical graphs.)",
25
+ "Augmented Zagreb Index (AZI)":
26
+ "AZI = Σ [(deg(u)×deg(v))/(deg(u)+deg(v)-2)]³ for each edge uv ∈ E(G)\n(This index amplifies the contribution of high-degree vertices.)",
27
+ "Geometric-Arithmetic Index (GA)":
28
+ "GA = Σ [2×√(deg(u)×deg(v))/(deg(u)+deg(v))] for each edge uv ∈ E(G)\n(This index blends the geometric and arithmetic means of vertex degrees.)",
29
+ "Sum-Connectivity Index (SCI)":
30
+ "SCI = Σ [1/√(deg(u)+deg(v))] for each edge uv ∈ E(G)\n(This index focuses on the sum of the degrees.)",
31
+ "Harmonic Index (Harm)":
32
+ "Harm = Σ [2/(deg(u)+deg(v))] for each edge uv ∈ E(G)\n(A measure emphasizing balanced degrees.)",
33
+ "Gutman Index (Gut)":
34
+ "Gut = Σ [deg(u)×deg(v)×d(u,v)] for every unordered pair u,v\n(This index combines connectivity with distance information.)",
35
+ "Eccentric Connectivity Index (ECI)":
36
+ "ECI = Σ [deg(v)×ecc(v)] for every vertex v\n(Here, ecc(v) is the maximum distance from v to any other vertex.)",
37
+ "Total Eccentricity (TE)":
38
+ "TE = Σ [ecc(v)] for every vertex v\n(This sums the eccentricity of each vertex.)",
39
+ "Harary Index (H)":
40
+ "H = Σ [1/d(u,v)] for every unordered pair u,v\n(This sums the reciprocals of distances for each vertex pair.)"
41
+ }
42
+
43
+ # ==========================
44
+ # Functions to update which input groups are visible based on the selected index
45
+ # ==========================
46
+ def update_inputs(selected_index):
47
+ # Indices that use vertex-based values only: M₁, TE, ECI.
48
+ vertex_vis = selected_index in ["First Zagreb Index (M₁)", "Total Eccentricity (TE)",
49
+ "Eccentric Connectivity Index (ECI)"]
50
+ # Indices that use edge-based inputs: M₂, R, ABC, AZI, GA, SCI, Harm.
51
+ edge_vis = selected_index in ["Second Zagreb Index (M₂)",
52
+ "Randić Index (R)",
53
+ "Atom-Bond Connectivity Index (ABC)",
54
+ "Augmented Zagreb Index (AZI)",
55
+ "Geometric-Arithmetic Index (GA)",
56
+ "Sum-Connectivity Index (SCI)",
57
+ "Harmonic Index (Harm)"]
58
+ # Gutman index uses its own group.
59
+ gutman_vis = (selected_index == "Gutman Index (Gut)")
60
+ # Wiener and Harary indices use distance inputs.
61
+ distance_vis = selected_index in ["Wiener Index (W)", "Harary Index (H)"]
62
+ return (
63
+ gr.update(visible=vertex_vis),
64
+ gr.update(visible=edge_vis),
65
+ gr.update(visible=gutman_vis),
66
+ gr.update(visible=distance_vis)
67
+ )
68
+
69
+ # ==========================
70
+ # Calculation Functions
71
+ # (For simplicity, we assume a triangle graph with 3 vertices, 3 edges, and 3 unordered pairs.)
72
+ # ==========================
73
+ def solve_index(selected_index, vertex_deg1, vertex_deg2, vertex_deg3,
74
+ vertex_ecc1, vertex_ecc2, vertex_ecc3,
75
+ edge1_a, edge1_b, edge2_a, edge2_b, edge3_a, edge3_b,
76
+ gutman_degs, gutman_dists,
77
+ distance1, distance2, distance3):
78
+ try:
79
+ # -----------------------
80
+ # Vertex-based Calculations
81
+ # -----------------------
82
+ if selected_index == "First Zagreb Index (M₁)":
83
+ degrees = [vertex_deg1, vertex_deg2, vertex_deg3]
84
+ result = sum(degrees)
85
+ steps = [
86
+ f"Step 1: Record the degree of each vertex: {degrees}.",
87
+ f"Step 2: Sum all vertex degrees since M₁ is defined as Σ deg(v): {degrees[0]} + {degrees[1]} + {degrees[2]} = {result}."
88
+ ]
89
+ return f"### First Zagreb Index (M₁)\n{formulas[selected_index]}\n\nDetailed Steps:\n" + "\n".join(steps)
90
+
91
+ elif selected_index == "Total Eccentricity (TE)":
92
+ ecc = [vertex_ecc1, vertex_ecc2, vertex_ecc3]
93
+ result = sum(ecc)
94
+ steps = [
95
+ f"Step 1: Record the eccentricity (maximum distance) for each vertex: {ecc}.",
96
+ f"Step 2: Sum all eccentricities since TE is defined as Σ ecc(v): {ecc[0]} + {ecc[1]} + {ecc[2]} = {result}."
97
+ ]
98
+ return f"### Total Eccentricity (TE)\n{formulas[selected_index]}\n\nDetailed Steps:\n" + "\n".join(steps)
99
+
100
+ elif selected_index == "Eccentric Connectivity Index (ECI)":
101
+ pairs = [(vertex_deg1, vertex_ecc1), (vertex_deg2, vertex_ecc2), (vertex_deg3, vertex_ecc3)]
102
+ contributions = [d * e for d, e in pairs]
103
+ result = sum(contributions)
104
+ steps = [
105
+ f"Step 1: For each vertex, record the pair (degree, eccentricity): {pairs}.",
106
+ f"Step 2: Multiply the degree and eccentricity for each vertex: {contributions} (because ECI = Σ [deg(v)×ecc(v)]).",
107
+ f"Step 3: Sum these products: {contributions[0]} + {contributions[1]} + {contributions[2]} = {result}."
108
+ ]
109
+ return f"### Eccentric Connectivity Index (ECI)\n{formulas[selected_index]}\n\nDetailed Steps:\n" + "\n".join(steps)
110
+
111
+ # -----------------------
112
+ # Edge-based Calculations
113
+ # -----------------------
114
+ elif selected_index in ["Second Zagreb Index (M₂)", "Randić Index (R)",
115
+ "Atom-Bond Connectivity Index (ABC)", "Augmented Zagreb Index (AZI)",
116
+ "Geometric-Arithmetic Index (GA)", "Sum-Connectivity Index (SCI)",
117
+ "Harmonic Index (Harm)"]:
118
+ edges = [(edge1_a, edge1_b), (edge2_a, edge2_b), (edge3_a, edge3_b)]
119
+ if selected_index == "Second Zagreb Index (M₂)":
120
+ products = [a * b for a, b in edges]
121
+ result = sum(products)
122
+ steps = [
123
+ f"Step 1: Each edge connects two vertices with degrees as given: {edges}.",
124
+ f"Step 2: For each edge, multiply the degrees: {products} (since M₂ sums the product for each edge).",
125
+ f"Step 3: Sum these products: {products[0]} + {products[1]} + {products[2]} = {result}."
126
+ ]
127
+ elif selected_index == "Randić Index (R)":
128
+ values = [1 / math.sqrt(a * b) for a, b in edges]
129
+ result = sum(values)
130
+ steps = [
131
+ f"Step 1: Record the degree pairs for each edge: {edges}.",
132
+ f"Step 2: For each edge, compute 1/√(deg(u)×deg(v)): {['{:.4f}'.format(v) for v in values]}.",
133
+ f"Step 3: Sum these values to obtain R: {result:.4f}."
134
+ ]
135
+ elif selected_index == "Atom-Bond Connectivity Index (ABC)":
136
+ values = [math.sqrt((a + b - 2) / (a * b)) for a, b in edges]
137
+ result = sum(values)
138
+ steps = [
139
+ f"Step 1: For each edge, note the degree pair: {edges}.",
140
+ f"Step 2: Compute √((deg(u)+deg(v)-2)/(deg(u)×deg(v))) for each edge: {['{:.4f}'.format(v) for v in values]}.",
141
+ f"Step 3: Sum the results: {result:.4f}."
142
+ ]
143
+ elif selected_index == "Augmented Zagreb Index (AZI)":
144
+ values = []
145
+ for a, b in edges:
146
+ denom = a + b - 2
147
+ val = (a * b / denom) ** 3 if denom != 0 else 0
148
+ values.append(val)
149
+ result = sum(values)
150
+ steps = [
151
+ f"Step 1: For each edge, record degrees: {edges}.",
152
+ f"Step 2: For each, compute ( (deg(u)×deg(v))/(deg(u)+deg(v)-2) )³: {['{:.4f}'.format(v) for v in values]}.",
153
+ f"Step 3: Sum these values: {result:.4f}."
154
+ ]
155
+ elif selected_index == "Geometric-Arithmetic Index (GA)":
156
+ values = [(2 * math.sqrt(a * b))/(a + b) for a, b in edges]
157
+ result = sum(values)
158
+ steps = [
159
+ f"Step 1: Record edge degree pairs: {edges}.",
160
+ f"Step 2: For each edge, calculate 2×√(deg(u)×deg(v))/(deg(u)+deg(v)): {['{:.4f}'.format(v) for v in values]}.",
161
+ f"Step 3: Sum to obtain GA: {result:.4f}."
162
+ ]
163
+ elif selected_index == "Sum-Connectivity Index (SCI)":
164
+ values = [1 / math.sqrt(a + b) for a, b in edges]
165
+ result = sum(values)
166
+ steps = [
167
+ f"Step 1: Note the degree pairs for each edge: {edges}.",
168
+ f"Step 2: For each edge, compute 1/√(deg(u)+deg(v)): {['{:.4f}'.format(v) for v in values]}.",
169
+ f"Step 3: Sum the computed values to get SCI: {result:.4f}."
170
+ ]
171
+ elif selected_index == "Harmonic Index (Harm)":
172
+ values = [2 / (a + b) for a, b in edges]
173
+ result = sum(values)
174
+ steps = [
175
+ f"Step 1: Record the edge degree pairs: {edges}.",
176
+ f"Step 2: For each edge, compute 2/(deg(u)+deg(v)): {['{:.4f}'.format(v) for v in values]}.",
177
+ f"Step 3: Sum these values for the final Harmonic Index: {result:.4f}."
178
+ ]
179
+ return f"### {selected_index}\n{formulas[selected_index]}\n\nDetailed Steps:\n" + "\n".join(steps)
180
+
181
+ # -----------------------
182
+ # Gutman Index: Requires vertex degrees and distances
183
+ # -----------------------
184
+ elif selected_index == "Gutman Index (Gut)":
185
+ degs = [float(x) for x in gutman_degs.split(',')]
186
+ dists = [float(x) for x in gutman_dists.split(',')]
187
+ # For a triangle, the unordered pairs are (1,2), (1,3), and (2,3)
188
+ total = degs[0]*degs[1]*dists[0] + degs[0]*degs[2]*dists[1] + degs[1]*degs[2]*dists[2]
189
+ steps = [
190
+ f"Step 1: The vertex degrees are recorded as: {degs}.",
191
+ f"Step 2: The shortest-path distances for unordered vertex pairs (1,2), (1,3), and (2,3) are: {dists}.",
192
+ f"Step 3: For each pair, multiply deg(u)×deg(v)×d(u,v):",
193
+ f" For (1,2): {degs[0]}×{degs[1]}×{dists[0]} = {degs[0]*degs[1]*dists[0]},",
194
+ f" For (1,3): {degs[0]}×{degs[2]}×{dists[1]} = {degs[0]*degs[2]*dists[1]},",
195
+ f" For (2,3): {degs[1]}×{degs[2]}×{dists[2]} = {degs[1]*degs[2]*dists[2]}.",
196
+ f"Step 4: Sum all products: {total}."
197
+ ]
198
+ return f"### Gutman Index (Gut)\n{formulas[selected_index]}\n\nDetailed Steps:\n" + "\n".join(steps)
199
+
200
+ # -----------------------
201
+ # Distance-based: Wiener and Harary indices
202
+ # -----------------------
203
+ elif selected_index in ["Wiener Index (W)", "Harary Index (H)"]:
204
+ dists = [distance1, distance2, distance3]
205
+ if selected_index == "Wiener Index (W)":
206
+ result = sum(dists)
207
+ steps = [
208
+ f"Step 1: Record the shortest-path distances for each unordered pair: {dists}.",
209
+ f"Step 2: Sum all distances: {dists[0]} + {dists[1]} + {dists[2]} = {result}."
210
+ ]
211
+ return f"### Wiener Index (W)\n{formulas[selected_index]}\n\nDetailed Steps:\n" + "\n".join(steps)
212
+ else: # Harary Index (H)
213
+ values = [1/d if d != 0 else 0 for d in dists]
214
+ result = sum(values)
215
+ steps = [
216
+ f"Step 1: Record the shortest-path distances: {dists}.",
217
+ f"Step 2: Compute the reciprocal for each distance (1/d): {['{:.4f}'.format(1/d) if d!=0 else 'undefined' for d in dists]}.",
218
+ f"Step 3: Sum these reciprocals: {result:.4f}."
219
+ ]
220
+ return f"### Harary Index (H)\n{formulas[selected_index]}\n\nDetailed Steps:\n" + "\n".join(steps)
221
+ else:
222
+ return "Index not recognized."
223
+ except Exception as e:
224
+ return f"Error: {e}"
225
+
226
+ # ==========================
227
+ # Build the Gradio Interface with Dynamic Input Groups
228
+ # ==========================
229
+ with gr.Blocks() as demo:
230
+ gr.Markdown("## Topological Index Calculator\n\nSelect an index and enter the required values in the relevant fields. The fields below will change based on the chosen index. (For illustration, this example uses a fixed triangle graph with 3 vertices, 3 edges, and 3 unordered pairs.)")
231
+
232
+ index_dropdown = gr.Dropdown(
233
+ label="Select an Index",
234
+ choices=[
235
+ "Wiener Index (W)",
236
+ "First Zagreb Index (M₁)",
237
+ "Second Zagreb Index (M₂)",
238
+ "Randić Index (R)",
239
+ "Atom-Bond Connectivity Index (ABC)",
240
+ "Augmented Zagreb Index (AZI)",
241
+ "Geometric-Arithmetic Index (GA)",
242
+ "Sum-Connectivity Index (SCI)",
243
+ "Harmonic Index (Harm)",
244
+ "Gutman Index (Gut)",
245
+ "Eccentric Connectivity Index (ECI)",
246
+ "Total Eccentricity (TE)",
247
+ "Harary Index (H)"
248
+ ]
249
+ )
250
+
251
+ # Group 1: Vertex-based inputs (for M₁, TE, ECI)
252
+ with gr.Group(visible=False) as vertex_group:
253
+ gr.Markdown("### Vertex Inputs\nEnter the degree and/or eccentricity for each vertex.")
254
+ vertex_deg1 = gr.Number(label="Vertex 1 Degree", value=2)
255
+ vertex_deg2 = gr.Number(label="Vertex 2 Degree", value=2)
256
+ vertex_deg3 = gr.Number(label="Vertex 3 Degree", value=2)
257
+ vertex_ecc1 = gr.Number(label="Vertex 1 Eccentricity", value=1)
258
+ vertex_ecc2 = gr.Number(label="Vertex 2 Eccentricity", value=1)
259
+ vertex_ecc3 = gr.Number(label="Vertex 3 Eccentricity", value=1)
260
+
261
+ # Group 2: Edge-based inputs (for M₂, R, ABC, AZI, GA, SCI, Harm)
262
+ with gr.Group(visible=False) as edge_group:
263
+ gr.Markdown("### Edge Inputs\nFor each edge, enter the degree of each end vertex.")
264
+ with gr.Row():
265
+ edge1_a = gr.Number(label="Edge 1: Vertex A Degree", value=2)
266
+ edge1_b = gr.Number(label="Edge 1: Vertex B Degree", value=2)
267
+ with gr.Row():
268
+ edge2_a = gr.Number(label="Edge 2: Vertex A Degree", value=2)
269
+ edge2_b = gr.Number(label="Edge 2: Vertex B Degree", value=2)
270
+ with gr.Row():
271
+ edge3_a = gr.Number(label="Edge 3: Vertex A Degree", value=2)
272
+ edge3_b = gr.Number(label="Edge 3: Vertex B Degree", value=2)
273
+
274
+ # Group 3: Gutman inputs (for Gutman Index)
275
+ with gr.Group(visible=False) as gutman_group:
276
+ gr.Markdown("### Gutman Index Inputs\nEnter vertex degrees and the distances for each unordered vertex pair.")
277
+ gutman_degs = gr.Textbox(label="Vertex Degrees (comma-separated)", value="2,2,2")
278
+ gutman_dists = gr.Textbox(label="Distances for pairs ((1,2), (1,3), (2,3)) (comma-separated)", value="1,1,1")
279
+
280
+ # Group 4: Distance-based inputs (for Wiener and Harary indices)
281
+ with gr.Group(visible=False) as distance_group:
282
+ gr.Markdown("### Distance Inputs\nEnter the shortest-path distance for each unordered vertex pair.")
283
+ distance1 = gr.Number(label="Distance for Pair 1", value=1)
284
+ distance2 = gr.Number(label="Distance for Pair 2", value=1)
285
+ distance3 = gr.Number(label="Distance for Pair 3", value=1)
286
+
287
+ output_box = gr.Textbox(label="Step-by-Step Detailed Solution", lines=20)
288
+ solve_btn = gr.Button("Solve")
289
+
290
+ # Update input group visibility when index is selected
291
+ index_dropdown.change(fn=update_inputs,
292
+ inputs=index_dropdown,
293
+ outputs=[vertex_group, edge_group, gutman_group, distance_group])
294
+
295
+ # Run calculations when Solve is clicked
296
+ solve_btn.click(fn=solve_index,
297
+ inputs=[index_dropdown,
298
+ vertex_deg1, vertex_deg2, vertex_deg3,
299
+ vertex_ecc1, vertex_ecc2, vertex_ecc3,
300
+ edge1_a, edge1_b, edge2_a, edge2_b, edge3_a, edge3_b,
301
+ gutman_degs, gutman_dists,
302
+ distance1, distance2, distance3],
303
+ outputs=output_box)
304
+
305
+ demo.launch()