Skip to content

Design Decision: Type-erased names in ReductionGraph topology #10

@GiggleLiu

Description

@GiggleLiu

Context

When visualizing and querying the reduction graph, we faced an issue where generic types with different type parameters (e.g., SpinGlass<i32> vs SpinGlass<f64>) were treated as separate nodes, even though they represent the same problem class.

This caused:

  1. Duplicate nodes in the visualization with identical labels
  2. Path queries failing when source/target types had different weight parameters
  3. Confusion about whether MaxCut<i32> -> SpinGlass<f64> is a valid reduction path

Decision

We refactored ReductionGraph to use type-erased base names for the graph topology:

  • Graph nodes store base names (e.g., "SpinGlass") instead of TypeId
  • Multiple concrete types map to the same node: SpinGlass<i32>, SpinGlass<f64>"SpinGlass"
  • Path finding works regardless of weight type parameters

New API

// Generic API (extracts base name internally)
graph.find_paths::<MaxCut<i32>, SpinGlass<f64>>();  // Works!
graph.has_direct_reduction::<MaxCut<i32>, SpinGlass<f64>>();  // Works!

// String-based API
graph.find_paths_by_name("MaxCut", "SpinGlass");
graph.has_direct_reduction_by_name("Factoring", "CircuitSAT");

Potential Issues

1. Loss of type-level precision

The graph no longer distinguishes between SpinGlass<i32> and SpinGlass<f64>. If a reduction only works for specific type parameters, this information is lost in the topology.

Mitigation: The actual ReduceTo trait implementations still enforce type constraints at compile time.

2. Runtime type casting not implemented

While the topology now supports cross-type queries, the actual reduction execution still requires matching types. Users might expect:

let result: SpinGlass<f64> = reduce_along_path::<MaxCut<i32>, SpinGlass<f64>>(maxcut);

But this doesn't exist yet.

Future work: Implement auto-casting in reduction execution when types are convertible (e.g., i32 -> f64).

3. Base name extraction is string-based

We rely on consistent naming in the register! macro. If someone registers:

SpinGlass<i32> => "SpinGlass",
SpinGlass<f64> => "Ising",  // Different name!

They would create separate nodes.

Mitigation: Could add compile-time checks or use a trait to derive base names.

4. KSatisfiability loses the K parameter

KSatisfiability<3, i32> becomes "KSatisfiability", losing the information that it's specifically 3-SAT.

Consideration: Should KSatisfiability<3> and KSatisfiability<4> be different nodes? Currently they're merged.

Related Commits

  • cee4c8f - refactor: Use type-erased names for ReductionGraph topology
  • e6a588c - fix: Unify SpinGlass types in ReductionGraph visualization

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions