Skip to content

Commit a4264a6

Browse files
GiggleLiuclaude
andauthored
feat: variant-aware reduction paths with resolve_path (#68)
* feat: add ResolvedPath, ReductionStep, EdgeKind types Add data types for variant-aware reduction paths: - ReductionStep: a node with problem name and variant map - EdgeKind: either a registered Reduction (with overhead) or NaturalCast - ResolvedPath: sequence of steps connected by edges, with helper methods Also add Serialize derives to Monomial, Polynomial, and ReductionOverhead to support serialization of the new EdgeKind::Reduction variant. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add find_best_entry for variant-aware ReductionEntry lookup Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add resolve_path for variant-level reduction paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: deprecate lookup_overhead, migrate KSat example to resolve_path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * rm plan files * refactor: remove explicit natural reduction, rely on resolve_path Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: add #[allow(deprecated)] to examples and fix formatting Allow deprecated lookup_overhead calls in examples pending migration, revert unintended macro indentation change, and apply rustfmt to tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add design.md describing variant-aware reduction paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add variant-aware path resolution section to docs/src/design.md Describes the two-phase resolution approach (name-level discovery + variant-level resolve_path), KSat disambiguation, natural cast insertion, and the execution model. Removes the mistakenly created root design.md. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add interactive reduction diagram design Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: add interactive reduction diagram implementation plan Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: remove unnecessary #[allow(dead_code)] from variant-aware path types ResolvedPath, ReductionStep, and EdgeKind are actively used in tests and the KSat example, so the dead_code suppression is no longer needed. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * update * refactor: extract inline JS/CSS from introduction.md to external files Move the ~340-line inline script and inline styles from the reduction graph in introduction.md into separate docs/src/static/reduction-graph.js and docs/src/static/reduction-graph.css files. Update book.toml to load cytoscape.min.js and the new files via additional-js/additional-css. Key changes: - Tooltip element renamed from #tooltip to #cy-tooltip to avoid conflicts - clearPath() is now a local function with addEventListener instead of inline onclick handler - DOMContentLoaded guard ensures the script only runs when #cy exists - No behavior change; pure mechanical extraction Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: switch reduction diagram to ELK stress layout Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: implement compound nodes for reduction diagram (collapsed view) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add expand/collapse for compound variant nodes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add variant edge filtering on click Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add search bar to reduction diagram Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: integrate path finding with compound node structure Restructure tap handler so path selection takes priority when a source node is already selected, allowing variant nodes to participate in path finding while still supporting single-click variant edge filtering. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add dashed style for natural cast edges Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: update diagram legend and help text for compound nodes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: polish reduction diagram interactions and edge cases - Fix CDN URL for cytoscape-elk (correct path: /dist/cytoscape-elk.js) - Add explicit ELK layout registration with cose fallback when CDN unavailable - Fix expand/collapse to only show variant edges when both endpoints are visible - Move search input styles to external CSS file Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add VariantParam trait, CastToParent, impl_variant_param!, variant_params! macros Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: add KValue trait with K2, K3, KN types for type-level K values Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: register SimpleGraph, UnitDiskGraph, HyperGraph with VariantParam Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * feat: register One, i32, f64 with VariantParam Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate KSatisfiability from const K to KValue type parameter Replace `KSatisfiability<const K: usize>` with `KSatisfiability<K: KValue>` using the new variant type system (K2, K3, KN types). Key changes: - KSatisfiability struct now uses PhantomData<K> with serde skip/bound - Reduction impls use concrete types (K2, K3, KN) instead of const generics since the #[reduction] proc macro requires concrete types - KSAT->SAT registered for KN (generic), K3, and K2 - SAT->KSAT registered for K3 (same as before) - KSAT->QUBO registered for K2 and K3 (same as before) - Variant IDs change from "2"/"3"/"N" to "K2"/"K3"/"KN" - Prelude exports K2, K3, KN, KValue, VariantParam, CastToParent Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: migrate KColoring from const K to KValue type parameter Replace KColoring<const K: usize, G> with KColoring<K: KValue, G> to use type-level K parameters (K1, K2, K3, K4, KN) from the variant system. Key changes: - Add K1 and K4 types, extend hierarchy: K1 < K2 < K3 < K4 < KN - Update KColoring model to use KValue trait with PhantomData<K> - Migrate all reduction rules (SAT->KColoring, KColoring->QUBO, KColoring->ILP) using helper function + macro pattern for concrete type registrations - Add k_hierarchy to ReductionGraph built from VariantTypeEntry inventory for proper subtype checking of K-value variants - Update all tests, examples, and integration tests Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: apply variant_params! macro to all Problem implementations Replace all hand-written variant() implementations with the variant_params! macro across 19 problem files. Add VariantParam trait implementations for GridGraph<i32> and Triangular graph types. Propagate VariantParam bounds to generic ReductionResult impls and test helpers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: unify variant hierarchy in ReductionGraph using VariantTypeEntry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: remove old GraphSubtypeEntry/WeightSubtypeEntry hierarchy system The unified VariantTypeEntry system now fully covers all graph and weight subtype registrations. Add VariantParam impls and VariantTypeEntry registrations for PlanarGraph and BipartiteGraph (the two marker types that were only in the old system), then remove GraphSubtypeEntry, WeightSubtypeEntry, GraphMarker trait, GraphSubtype trait, and the declare_graph_subtype!/declare_weight_subtype! macros. Rewrite graph_types tests to verify the new system. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * refactor: remove deprecated const_usize_str, short_type_name, const generic rewriting Remove legacy variant utilities replaced by the new VariantParam trait system: - const_usize_str and short_type_name from src/variant.rs - collect_const_generic_names and rewrite_const_generics from proc macro - Simplify make_variant_fn_body to call Problem::variant() directly - Remove corresponding tests from unit_tests/variant.rs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: update benchmark to use K3 type parameter instead of const generic Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: formatting fixes and regenerate artifacts after variant system redesign Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style: apply rustfmt to sat_ksat macro indentation Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * update * refactor: remove Grid type, flatten K hierarchy, clean up exports - Remove GridGraph/Grid type entirely; MappingResult stores positions, node_weights, grid_dimensions, and kind (GridKind enum) directly - Add KingsSubgraph and TriangularSubgraph as public graph types that compute edges on-the-fly from geometry - Remove backward-compat aliases from unitdiskmapping/mod.rs; all consumers now use canonical ksg:: and triangular:: paths - Flatten K value hierarchy: K1..K5 are direct children of KN with no chain between them (k-SAT/k-coloring with different k are independent problem classes) - Add K5 type - Regenerate static JSON exports with flat visualization format - Add variant hierarchy diagram (Typst → SVG) to design docs - Remove irrelevant plan files from this branch Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: compact JSON output for paper static files Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2b5f0fd commit a4264a6

165 files changed

Lines changed: 8643 additions & 12744 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

benches/solver_benchmarks.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use problemreductions::models::set::*;
88
use problemreductions::models::specialized::*;
99
use problemreductions::prelude::*;
1010
use problemreductions::topology::SimpleGraph;
11+
use problemreductions::variant::K3;
1112
use std::hint::black_box;
1213

1314
/// Benchmark MaximumIndependentSet on graphs of varying sizes.
@@ -138,7 +139,7 @@ fn bench_coloring(c: &mut Criterion) {
138139

139140
for n in [3, 4, 5, 6].iter() {
140141
let edges: Vec<(usize, usize)> = (0..*n - 1).map(|i| (i, i + 1)).collect();
141-
let problem = KColoring::<3, SimpleGraph>::new(*n, edges);
142+
let problem = KColoring::<K3, SimpleGraph>::new(*n, edges);
142143
let solver = BruteForce::new();
143144

144145
group.bench_with_input(BenchmarkId::new("path_3colors", n), n, |b, _| {

book.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ src = "docs/src"
99
default-theme = "navy"
1010
git-repository-url = "https://github.com/CodingThrust/problem-reductions"
1111
edit-url-template = "https://github.com/CodingThrust/problem-reductions/edit/main/{path}"
12-
additional-css = ["docs/src/static/theme-images.css"]
13-
additional-js = []
12+
additional-css = ["docs/src/static/theme-images.css", "docs/src/static/reduction-graph.css"]
13+
additional-js = ["docs/src/static/cytoscape.min.js", "docs/src/static/reduction-graph.js"]
1414
no-section-label = false
1515

1616
[output.html.fold]

docs/paper/lib.typ

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,27 +93,25 @@
9393

9494
// King's subgraph from JSON with weight-based coloring
9595
#let draw-grid-graph(data, cell-size: 0.2) = canvas(length: 1cm, {
96-
let grid-data = data.grid_graph
97-
let positions = grid-data.nodes.map(n => (n.col * cell-size, -n.row * cell-size))
98-
let fills = grid-data.nodes.map(n => weight-color(n.weight))
99-
let edges = grid-data.edges.map(e => (e.at(0), e.at(1)))
96+
let positions = data.nodes.map(n => (n.col * cell-size, -n.row * cell-size))
97+
let fills = data.nodes.map(n => weight-color(n.weight))
98+
let edges = data.edges.map(e => (e.at(0), e.at(1)))
10099
for (u, v) in edges { g-edge(positions.at(u), positions.at(v), stroke: 0.4pt + gray) }
101100
for (k, pos) in positions.enumerate() {
102101
g-node(pos, radius: 0.04, stroke: none, fill: fills.at(k))
103102
}
104103
})
105104

106105
// Triangular lattice from JSON with weight-based coloring
107-
// Matches Rust GridGraph::physical_position_static for Triangular (offset_even_cols=true)
106+
// Physical positions use triangular lattice transform (offset_even_cols=true)
108107
#let draw-triangular-graph(data, cell-size: 0.2) = canvas(length: 1cm, {
109-
let grid-data = data.grid_graph
110108
let sqrt3_2 = calc.sqrt(3) / 2
111-
let positions = grid-data.nodes.map(n => {
109+
let positions = data.nodes.map(n => {
112110
let offset = if calc.rem(n.col, 2) == 0 { 0.5 } else { 0.0 }
113111
((n.row + offset) * cell-size, -n.col * sqrt3_2 * cell-size)
114112
})
115-
let fills = grid-data.nodes.map(n => weight-color(n.weight))
116-
let edges = grid-data.edges.map(e => (e.at(0), e.at(1)))
113+
let fills = data.nodes.map(n => weight-color(n.weight))
114+
let edges = data.edges.map(e => (e.at(0), e.at(1)))
117115
for (u, v) in edges { g-edge(positions.at(u), positions.at(v), stroke: 0.3pt + gray) }
118116
for (k, pos) in positions.enumerate() {
119117
g-node(pos, radius: 0.025, stroke: none, fill: fills.at(k))

docs/paper/reductions.typ

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@
4343
"KSatisfiability": [$k$-SAT],
4444
"CircuitSAT": [CircuitSAT],
4545
"Factoring": [Factoring],
46-
"GridGraph": [GridGraph MIS],
47-
"Triangular": [Triangular MIS],
46+
"KingsSubgraph": [King's Subgraph MIS],
47+
"TriangularSubgraph": [Triangular Subgraph MIS],
4848
)
4949

5050
// Definition label: "def:<ProblemName>" — each definition block must have a matching label
@@ -828,7 +828,7 @@ The following reductions to Integer Linear Programming are straightforward formu
828828

829829
== Unit Disk Mapping
830830

831-
#reduction-rule("MaximumIndependentSet", "GridGraph")[
831+
#reduction-rule("MaximumIndependentSet", "KingsSubgraph")[
832832
@nguyen2023 Any MIS problem on a general graph $G$ can be reduced to MIS on a unit disk graph (King's subgraph) with at most quadratic overhead in the number of vertices.
833833
][
834834
_Construction (Copy-Line Method)._ Given $G = (V, E)$ with $n = |V|$:
@@ -885,7 +885,7 @@ The following reductions to Integer Linear Programming are straightforward formu
885885
caption: [Unit disk mappings of the Petersen graph. Blue: weight 1, red: weight 2, green: weight 3.],
886886
) <fig:petersen-mapping>
887887

888-
#reduction-rule("MaximumIndependentSet", "Triangular")[
888+
#reduction-rule("MaximumIndependentSet", "TriangularSubgraph")[
889889
@nguyen2023 Any MIS problem on a general graph $G$ can be reduced to MIS on a weighted triangular lattice graph with at most quadratic overhead in the number of vertices.
890890
][
891891
_Construction._ Same copy-line method as the KSG mapping, but uses a triangular lattice instead of a square grid. Crossing and simplifier gadgets are adapted for triangular geometry, producing a unit disk graph on a triangular grid where edges connect nodes within unit distance under the triangular metric.
Lines changed: 1 addition & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1 @@
1-
{
2-
"name": "Petersen",
3-
"num_vertices": 10,
4-
"edges": [
5-
[
6-
0,
7-
1
8-
],
9-
[
10-
1,
11-
2
12-
],
13-
[
14-
2,
15-
3
16-
],
17-
[
18-
3,
19-
4
20-
],
21-
[
22-
4,
23-
0
24-
],
25-
[
26-
5,
27-
7
28-
],
29-
[
30-
7,
31-
9
32-
],
33-
[
34-
9,
35-
6
36-
],
37-
[
38-
6,
39-
8
40-
],
41-
[
42-
8,
43-
5
44-
],
45-
[
46-
0,
47-
5
48-
],
49-
[
50-
1,
51-
6
52-
],
53-
[
54-
2,
55-
7
56-
],
57-
[
58-
3,
59-
8
60-
],
61-
[
62-
4,
63-
9
64-
]
65-
],
66-
"mis": 4
67-
}
1+
{"name":"Petersen","num_vertices":10,"edges":[[0,1],[1,2],[2,3],[3,4],[4,0],[5,7],[7,9],[9,6],[6,8],[8,5],[0,5],[1,6],[2,7],[3,8],[4,9]],"mis":4}

0 commit comments

Comments
 (0)