Skip to main content

Tutorial 12 — Diffing Two Topology Versions

Objective: Use diff() to show what changed between a v1 and v2 network design, enabling version control for quantum network configurations.

Network topologies evolve over time — adding nodes, adjusting link parameters, removing unused infrastructure. The diff() function provides structured output you can use in CI/CD, changelogs, or team reviews.

Use the Repo's Existing v1/v2 Files

from qnet_core import diff

v1_path = "network_v1.qnet" # 2 nodes, 1 link
v2_path = "network_v2.qnet" # 3 nodes, 2 links — extended version

result = diff(v1_path, v2_path)

print(f"Summary: {result.get('summary', 'N/A')}\n")

if result.get("nodes_added"):
print("Nodes ADDED:")
for n in result["nodes_added"]:
print(f" + {n}")

if result.get("nodes_removed"):
print("Nodes REMOVED:")
for n in result["nodes_removed"]:
print(f" - {n}")

if result.get("nodes_modified"):
print("Nodes MODIFIED:")
for n in result["nodes_modified"]:
print(f" ~ {n}")

if result.get("links_added"):
print("\nLinks ADDED:")
for l in result["links_added"]:
print(f" + {l}")

if result.get("links_removed"):
print("\nLinks REMOVED:")
for l in result["links_removed"]:
print(f" - {l}")

if result.get("links_modified"):
print("\nLinks MODIFIED:")
for l in result["links_modified"]:
print(f" ~ {l}")

Create Two Custom Versions and Diff Them

from qnet_core import QNetFile, save_qnet_file_wrapper

# Version A — baseline
v_a = QNetFile(name="version_a")
v_a.add_node("X", memory_lifetime_ms=500.0)
v_a.add_node("Y", memory_lifetime_ms=1000.0)
v_a.add_link("l1", src="X", to="Y", distance_km=10.0, base_fidelity=0.95, generation_rate_hz=1_000.0)

# Version B — changes: modified X's T2, added node Z, modified l1 params, added link
v_b = QNetFile(name="version_b")
v_b.add_node("X", memory_lifetime_ms=800.0) # changed T2 from 500→800
v_b.add_node("Y", memory_lifetime_ms=1000.0) # unchanged
v_b.add_node("Z", memory_lifetime_ms=600.0) # NEW node
v_b.add_link("l1", src="X", to="Y", distance_km=20.0, base_fidelity=0.90, generation_rate_hz=800.0) # modified
v_b.add_link("l2", src="Y", to="Z", distance_km=15.0, base_fidelity=0.88, generation_rate_hz=700.0) # NEW link

save_qnet_file_wrapper(v_a, "examples/v_a.qnet")
save_qnet_file_wrapper(v_b, "examples/v_b.qnet")

diff_result = diff("examples/v_a.qnet", "examples/v_b.qnet")
print(f"Summary: {diff_result.get('summary', 'N/A')}")
for key in ("nodes_added", "nodes_removed", "nodes_modified",
"links_added", "links_removed", "links_modified"):
items = diff_result.get(key, [])
if items:
print(f" {key}: {items}")

Diff Return Format

The function returns a dict with these keys (all lists of strings):

KeyContent
summaryHuman-readable one-line summary
nodes_addedList of new node IDs
nodes_removedList of removed node IDs
nodes_modifiedList of modified node descriptions
links_addedList of new link descriptions
links_removedList of removed link descriptions
links_modifiedList of modified link descriptions
errorPresent only if a file failed to load: {"error": "..."}

Programmatic Diff with Snapshots

For comparing topologies in code (not on disk), use diff_topologies():

from qnet_core import diff_topologies, TopologySnapshot, TopologyMetadata, TopologyConfig

snap1 = TopologySnapshot(
metadata=TopologyMetadata(name="v1", version="1.0"),
nodes=[...], # list of NodeDefinition
links=[...], # list of LinkDefinition
config=TopologyConfig(alpha_loss=0.22, gamma_swapping=0.9),
)

snap2 = TopologySnapshot(...)

diff = diff_topologies(snap1, snap2)
print(diff.summary)
# Access: diff.nodes_added, diff.nodes_removed, diff.nodes_modified
# diff.links_added, diff.links_removed, diff.links_modified

What's next