@@ -23,9 +23,57 @@ make test clippy export-graph # Must pass before PR
2323- ` src/models/ ` - Problem implementations (SAT, Graph, Set, Optimization)
2424- ` src/rules/ ` - Reduction rules + inventory registration
2525- ` src/solvers/ ` - BruteForce solver, ILP solver (feature-gated)
26- - ` src/traits/ ` - ` Problem ` , ` ConstraintSatisfactionProblem ` , ` ReduceTo<T> ` traits
26+ - ` src/traits.rs ` - ` Problem ` , ` ConstraintSatisfactionProblem ` traits
27+ - ` src/rules/traits.rs ` - ` ReduceTo<T> ` , ` ReductionResult ` traits
2728- ` src/registry/ ` - Compile-time reduction metadata collection
2829
30+ ### Trait Hierarchy
31+
32+ ```
33+ Problem (core trait - all problems must implement)
34+ │
35+ ├── const NAME: &'static str // Problem name, e.g., "IndependentSet"
36+ ├── type GraphType: GraphMarker // Graph topology marker
37+ ├── type Weight: NumericWeight // Weight type (i32, f64, Unweighted)
38+ ├── type Size // Objective value type
39+ │
40+ ├── fn num_variables(&self) -> usize
41+ ├── fn num_flavors(&self) -> usize // Usually 2 for binary problems
42+ ├── fn problem_size(&self) -> ProblemSize
43+ ├── fn energy_mode(&self) -> EnergyMode
44+ ├── fn solution_size(&self, config) -> SolutionSize
45+ └── ... (default methods: variables, flavors, is_valid_config)
46+
47+ ConstraintSatisfactionProblem : Problem (extension for CSPs)
48+ │
49+ ├── fn constraints(&self) -> Vec<LocalConstraint>
50+ ├── fn objectives(&self) -> Vec<LocalSolutionSize>
51+ ├── fn weights(&self) -> Vec<Self::Size>
52+ ├── fn set_weights(&mut self, weights)
53+ ├── fn is_weighted(&self) -> bool
54+ └── ... (default methods: is_satisfied, compute_objective)
55+ ```
56+
57+ ### Problem Implementations
58+
59+ | Problem | ` Problem ` | ` ConstraintSatisfactionProblem ` |
60+ | ---------| :---------:| :-------------------------------:|
61+ | IndependentSet | ✓ | ✓ |
62+ | VertexCovering | ✓ | ✓ |
63+ | DominatingSet | ✓ | ✓ |
64+ | Matching | ✓ | ✓ |
65+ | MaxCut | ✓ | ✗ |
66+ | Coloring | ✓ | ✓ |
67+ | Satisfiability | ✓ | ✓ |
68+ | KSatisfiability | ✓ | ✓ |
69+ | SetPacking | ✓ | ✓ |
70+ | SetCovering | ✓ | ✓ |
71+ | SpinGlass | ✓ | ✗ |
72+ | QUBO | ✓ | ✗ |
73+ | ILP | ✓ | ✗ |
74+ | CircuitSAT | ✓ | ✗ |
75+ | Factoring | ✓ | ✗ |
76+
2977### Key Patterns
3078- Problems parameterized by weight type ` W ` and graph type ` G `
3179- ` ReductionResult ` provides ` target_problem() ` and ` extract_solution() `
@@ -38,22 +86,101 @@ make test clippy export-graph # Must pass before PR
3886- Model files: ` src/models/<category>/<name>.rs `
3987- Test naming: ` test_<source>_to_<target>_closed_loop `
4088
41- ### Reduction Pattern
89+ ### Reduction Pattern (Recommended: Using Macro)
4290``` rust
43- impl ReduceTo <TargetProblem > for SourceProblem {
91+ use problemreductions :: reduction;
92+
93+ #[reduction(
94+ overhead = { ReductionOverhead :: new(vec! [... ]) }
95+ )]
96+ impl ReduceTo <TargetProblem <Unweighted >> for SourceProblem <Unweighted > {
4497 type Result = ReductionSourceToTarget ;
4598 fn reduce_to (& self ) -> Self :: Result { ... }
4699}
100+ ```
101+
102+ The ` #[reduction] ` macro automatically:
103+ - Extracts type names from the impl signature
104+ - Detects weighted vs unweighted from type parameters (` Unweighted ` vs ` i32 ` /` f64 ` )
105+ - Detects graph types from type parameters (e.g., ` GridGraph ` , ` SimpleGraph ` )
106+ - Generates the ` inventory::submit! ` call
47107
48- inventory :: submit! { ReductionEntry { source_name , target_name , ... } }
108+ Optional macro attributes:
109+ - ` source_graph = "..." ` - Override detected source graph type
110+ - ` target_graph = "..." ` - Override detected target graph type
111+ - ` source_weighted = true/false ` - Override weighted detection
112+ - ` target_weighted = true/false ` - Override weighted detection
113+ - ` overhead = { ... } ` - Specify reduction overhead
114+
115+ ### Manual Registration (Alternative)
116+ ``` rust
117+ inventory :: submit! {
118+ ReductionEntry {
119+ source_name : " SourceProblem" ,
120+ target_name : " TargetProblem" ,
121+ source_variant : & [(" graph" , " SimpleGraph" ), (" weight" , " Unweighted" )],
122+ target_variant : & [(" graph" , " SimpleGraph" ), (" weight" , " Unweighted" )],
123+ overhead_fn : || ReductionOverhead :: new (... ),
124+ }
125+ }
49126```
50127
128+ ### Weight Types
129+ - ` Unweighted ` - Marker type for unweighted problems (all weights = 1)
130+ - ` i32 ` , ` f64 ` , etc. - Concrete weight types for weighted problems
131+
132+ ### Problem Variant IDs
133+ Reduction graph nodes use variant IDs: ` ProblemName[/GraphType][/Weighted] `
134+ - Base: ` IndependentSet ` (SimpleGraph, unweighted)
135+ - Graph variant: ` IndependentSet/GridGraph `
136+ - Weighted variant: ` IndependentSet/Weighted `
137+ - Both: ` IndependentSet/GridGraph/Weighted `
138+
51139## Anti-patterns
52140- Don't create reductions without closed-loop tests
53141- Don't forget ` inventory::submit! ` registration (graph won't update)
54142- Don't hardcode weights - use generic ` W ` parameter
55143- Don't skip ` make clippy ` before PR
56144
145+ ## Documentation Requirements
146+
147+ The technical paper (` docs/paper/reductions.typ ` ) must include:
148+
149+ 1 . ** Table of Contents** - Auto-generated outline of all sections
150+ 2 . ** Problem Data Structures** - For each problem definition, include the Rust struct with fields in a code block
151+ 3 . ** Reduction Examples** - For each reduction theorem, include a minimal working example showing:
152+ - Creating the source problem
153+ - Reducing to target problem
154+ - Solving and extracting solution back
155+ - Based on closed-loop tests from ` tests/reduction_tests.rs `
156+
157+ ### Documentation Pattern
158+ ``` typst
159+ #definition("Problem Name")[
160+ Mathematical definition...
161+ ]
162+
163+ // Rust data structure
164+ ```rust
165+ pub struct ProblemName<W = i32> {
166+ field1: Type1,
167+ field2: Type2,
168+ }
169+ `` `
170+
171+ #theorem[
172+ *(Source → Target)* Reduction description...
173+ ]
174+
175+ // Minimal working example
176+ ```rust
177+ let source = SourceProblem::new(...);
178+ let reduction = ReduceTo::<TargetProblem>::reduce_to(&source);
179+ let target = reduction.target_problem();
180+ // ... solve and extract
181+ `` `
182+ ```
183+
57184## Contributing
58185See ` .claude/rules/ ` for detailed guides:
59186- ` adding-reductions.md ` - How to add reduction rules
0 commit comments