Skip to content

Commit 14ee1df

Browse files
GiggleLiuclaude
andcommitted
feat: add ConcreteVariantEntry for non-SimpleGraph variant nodes
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c38f87a commit 14ee1df

3 files changed

Lines changed: 50 additions & 1 deletion

File tree

src/rules/graph.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
1111
use crate::graph_types::{GraphSubtypeEntry, WeightSubtypeEntry};
1212
use crate::rules::cost::PathCostFn;
13-
use crate::rules::registry::{ReductionEntry, ReductionOverhead};
13+
use crate::rules::registry::{ConcreteVariantEntry, ReductionEntry, ReductionOverhead};
1414
use crate::types::ProblemSize;
1515
use ordered_float::OrderedFloat;
1616
use petgraph::algo::all_simple_paths;
@@ -21,6 +21,13 @@ use std::any::TypeId;
2121
use std::cmp::Reverse;
2222
use std::collections::{BinaryHeap, HashMap, HashSet};
2323

24+
// Register concrete variants for problems that support non-SimpleGraph graph types.
25+
// These generate additional nodes in the JSON export.
26+
inventory::submit! { ConcreteVariantEntry { name: "MaximumIndependentSet", variant: &[("graph", "GridGraph"), ("weight", "Unweighted")] } }
27+
inventory::submit! { ConcreteVariantEntry { name: "MaximumIndependentSet", variant: &[("graph", "UnitDiskGraph"), ("weight", "Unweighted")] } }
28+
inventory::submit! { ConcreteVariantEntry { name: "MaxCut", variant: &[("graph", "GridGraph"), ("weight", "Unweighted")] } }
29+
inventory::submit! { ConcreteVariantEntry { name: "SpinGlass", variant: &[("graph", "GridGraph"), ("weight", "f64")] } }
30+
2431
/// JSON-serializable representation of the reduction graph.
2532
#[derive(Debug, Clone, Serialize)]
2633
pub struct ReductionGraphJson {
@@ -673,6 +680,14 @@ impl ReductionGraph {
673680
));
674681
}
675682

683+
// Also collect nodes from ConcreteVariantEntry registrations
684+
for entry in inventory::iter::<ConcreteVariantEntry> {
685+
node_set.insert((
686+
entry.name.to_string(),
687+
Self::variant_to_map(entry.variant),
688+
));
689+
}
690+
676691
// Build nodes with categories and doc paths
677692
let mut nodes: Vec<NodeJson> = node_set
678693
.iter()

src/rules/registry.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,15 @@ impl std::fmt::Debug for ReductionEntry {
8989

9090
inventory::collect!(ReductionEntry);
9191

92+
/// A registered concrete problem variant (for JSON export nodes).
93+
/// Variants registered here appear as nodes even without explicit reduction rules.
94+
pub struct ConcreteVariantEntry {
95+
pub name: &'static str,
96+
pub variant: &'static [(&'static str, &'static str)],
97+
}
98+
99+
inventory::collect!(ConcreteVariantEntry);
100+
92101
#[cfg(test)]
93102
#[path = "../unit_tests/rules/registry.rs"]
94103
mod tests;

src/unit_tests/rules/graph.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,3 +813,28 @@ fn test_json_variant_content() {
813813
"Edge involving MaximumIndependentSet should exist"
814814
);
815815
}
816+
817+
#[test]
818+
fn test_concrete_variant_nodes_in_json() {
819+
let graph = ReductionGraph::new();
820+
let json = graph.to_json();
821+
822+
// GridGraph variants should appear as nodes
823+
let mis_gridgraph = json.nodes.iter().any(|n| {
824+
n.name == "MaximumIndependentSet"
825+
&& n.variant.get("graph") == Some(&"GridGraph".to_string())
826+
});
827+
assert!(mis_gridgraph, "MIS/GridGraph node should exist");
828+
829+
let mis_unitdisk = json.nodes.iter().any(|n| {
830+
n.name == "MaximumIndependentSet"
831+
&& n.variant.get("graph") == Some(&"UnitDiskGraph".to_string())
832+
});
833+
assert!(mis_unitdisk, "MIS/UnitDiskGraph node should exist");
834+
835+
let maxcut_gridgraph = json.nodes.iter().any(|n| {
836+
n.name == "MaxCut"
837+
&& n.variant.get("graph") == Some(&"GridGraph".to_string())
838+
});
839+
assert!(maxcut_gridgraph, "MaxCut/GridGraph node should exist");
840+
}

0 commit comments

Comments
 (0)