Problem
Some primitive reduction rules have overhead that is equal to (or could be worse than) a composite path through other rules. These rules are not strictly necessary from an overhead perspective.
Analysis
Using pred path --all to enumerate all paths for each direct edge and comparing overheads, we found 6 genuinely redundant primitive rules (plus 3 trivial cast-composed duplicates):
Genuinely redundant (composite path through different problem types)
| # |
Primitive Rule |
Best Composite Path |
Overhead |
| 1 |
KColoring → QUBO |
KColoring → ILP → QUBO |
num_vars = num_vertices^2 (equal) |
| 2 |
MIS → ILP |
MIS → MVC → ILP |
num_vars=n, num_constraints=m (equal) |
| 3 |
MIS → QUBO |
MIS → ILP → QUBO or MIS → MVC → QUBO |
num_vars=n (equal) |
| 4 |
MaxSetPacking → ILP |
SetPacking → MIS → ILP |
num_vars=n, num_constraints=n^2 (equal) |
| 5 |
MVC → ILP |
MVC → MinSetCovering → ILP or MVC → MIS → ILP |
num_vars=n, num_constraints=m (equal) |
| 6 |
MVC → QUBO |
MVC → ILP → QUBO or MVC → MIS → QUBO |
num_vars=n (equal) |
Cast-composed (trivially equal via zero-cost variant casts)
| # |
Primitive Rule |
Composite Path |
| 7 |
KSatisfiability/K2 → Satisfiability |
K2 → KN (cast) → Satisfiability |
| 8 |
KSatisfiability/K3 → Satisfiability |
K3 → KN (cast) → Satisfiability |
| 9 |
MIS/One → MIS/KingsSubgraph/i32 |
One→i32 (cast) → KingsSubgraph/i32 |
Note
"Equal overhead" does not mean these rules should be removed — direct rules are valuable for:
- Simpler solution extraction (fewer intermediate steps)
- Educational/documentation clarity
- Direct encoding may be numerically better in practice
But having an automated check helps us:
- Avoid adding new rules that are strictly dominated
- Understand the structure of the reduction graph
- Make informed decisions about which rules to keep
Proposed Solution
Create a Rust utility (not a CLI subcommand) that:
- Enumerates all primitive edges from the
ReductionGraph
- For each edge, finds all alternative composite paths (using existing
find_all_paths)
- Composes overheads along each path (using existing
ReductionOverhead::compose)
- Compares overhead expressions by asymptotic order:
log < polynomial < exponential, and within polynomial by degree
- Reports any primitive rule where a composite path has equal or smaller overhead
Key infrastructure already available
ReductionGraph::find_all_paths() — path enumeration
ReductionOverhead::compose() — overhead composition via Expr::substitute
Expr::is_polynomial() — classification
Expr::eval() — numeric evaluation for comparison
Comparison approach
Compare overhead expressions from a computational complexity perspective:
- Classify growth rate:
O(log n) < O(n^k) < O(c^n) < O(n^n)
- Within polynomial: compare degree
- Use numeric evaluation at multiple test points as a fallback
Problem
Some primitive reduction rules have overhead that is equal to (or could be worse than) a composite path through other rules. These rules are not strictly necessary from an overhead perspective.
Analysis
Using
pred path --allto enumerate all paths for each direct edge and comparing overheads, we found 6 genuinely redundant primitive rules (plus 3 trivial cast-composed duplicates):Genuinely redundant (composite path through different problem types)
num_vars = num_vertices^2(equal)num_vars=n, num_constraints=m(equal)num_vars=n(equal)num_vars=n, num_constraints=n^2(equal)num_vars=n, num_constraints=m(equal)num_vars=n(equal)Cast-composed (trivially equal via zero-cost variant casts)
Note
"Equal overhead" does not mean these rules should be removed — direct rules are valuable for:
But having an automated check helps us:
Proposed Solution
Create a Rust utility (not a CLI subcommand) that:
ReductionGraphfind_all_paths)ReductionOverhead::compose)log < polynomial < exponential, and within polynomial by degreeKey infrastructure already available
ReductionGraph::find_all_paths()— path enumerationReductionOverhead::compose()— overhead composition viaExpr::substituteExpr::is_polynomial()— classificationExpr::eval()— numeric evaluation for comparisonComparison approach
Compare overhead expressions from a computational complexity perspective:
O(log n)<O(n^k)<O(c^n)<O(n^n)