Fix #227: Add PartitionIntoPathsOfLength2 model#638
Conversation
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #638 +/- ##
========================================
Coverage 96.86% 96.86%
========================================
Files 264 266 +2
Lines 35196 35358 +162
========================================
+ Hits 34091 34250 +159
- Misses 1105 1108 +3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Implementation SummaryChanges
Deviations from Plan
Open Questions
|
There was a problem hiding this comment.
Pull request overview
Adds a new NP-complete satisfaction problem model, PartitionIntoPathsOfLength2, and wires it into the library API surface, CLI, and paper documentation so it can be instantiated/serialized and solved with existing solvers (e.g., BruteForce).
Changes:
- Introduces
PartitionIntoPathsOfLength2<G>graph model with schema registration, variant declaration, serde support, and unit tests. - Exposes the new model via
modelsexports and the crateprelude. - Adds CLI alias/dispatch/create support and documents the problem in the Typst paper.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
src/models/graph/partition_into_paths_of_length_2.rs |
New model implementation + schema registration + variants + tests module hook |
src/unit_tests/models/graph/partition_into_paths_of_length_2.rs |
Unit tests covering satisfiable/unsatisfiable cases, edge cases, and serialization |
src/models/graph/mod.rs |
Registers module + re-export + docs list entry |
src/models/mod.rs |
Re-exports model at crate::models level |
src/lib.rs |
Adds model to prelude exports |
problemreductions-cli/src/problem_name.rs |
Adds lowercase alias resolution for the new problem |
problemreductions-cli/src/dispatch.rs |
Adds load/serialize dispatch arms for the new problem |
problemreductions-cli/src/commands/create.rs |
Adds pred create PartitionIntoPathsOfLength2 support |
problemreductions-cli/src/cli.rs |
Documents required flags for CLI creation |
docs/paper/reductions.typ |
Adds paper definition entry and display name mapping |
docs/paper/examples/maximumindependentset_to_maximumclique.json |
Reorders variant keys (formatting-only change) |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| // Check each group induces at least 2 edges | ||
| for group_id in 0..q { | ||
| let mut edge_count = 0; | ||
| for (u, v) in self.graph.edges() { | ||
| if config[u] == group_id && config[v] == group_id { | ||
| edge_count += 1; | ||
| } | ||
| } | ||
| if edge_count < 2 { | ||
| return false; | ||
| } | ||
| } | ||
|
|
| inventory::submit! { | ||
| ProblemSchemaEntry { | ||
| name: "PartitionIntoPathsOfLength2", | ||
| module_path: module_path!(), | ||
| description: "Partition vertices into triples each inducing a path of length 2", | ||
| fields: &[ | ||
| FieldInfo { name: "graph", type_name: "G", description: "The underlying graph G=(V,E) with |V| divisible by 3" }, | ||
| ], | ||
| } | ||
| } |
| // Invalid partition: {0,1,3}, {2,4,5}, {6,7,8} | ||
| // Group {0,1,3}: edges (0,1) and (0,3) and (1, nothing with 3) — 2 edges present, valid | ||
| // Group {2,4,5}: edges (4,5) and (2,5) — 2 edges present, valid | ||
| // This is actually valid too |
src/models/graph/mod.rs
Outdated
| //! - [`MaximumMatching`]: Maximum weight matching | ||
| //! - [`TravelingSalesman`]: Traveling Salesman (minimum weight Hamiltonian cycle) | ||
| //! - [`SpinGlass`]: Ising model Hamiltonian | ||
| //! - [`PartitionIntoPathsOfLength2`]: Partition vertices into P3 paths |
| // PartitionIntoPathsOfLength2 | ||
| "PartitionIntoPathsOfLength2" => { | ||
| let (graph, _) = parse_graph(args).map_err(|e| { | ||
| anyhow::anyhow!( | ||
| "{e}\n\nUsage: pred create PartitionIntoPathsOfLength2 --graph 0-1,1-2,3-4,4-5" | ||
| ) | ||
| })?; | ||
| ( | ||
| ser(problemreductions::models::graph::PartitionIntoPathsOfLength2::new(graph))?, | ||
| resolved_variant.clone(), | ||
| ) |
| ProblemSchemaEntry { | ||
| name: "PartitionIntoPathsOfLength2", | ||
| module_path: module_path!(), | ||
| description: "Partition vertices into triples each inducing a path of length 2", |
Merge adds PartitionIntoPathsOfLength2 (PR branch) alongside all new models from main (HamiltonianPath, MinimumSumMulticenter, etc.) and adopts main's registry-based dispatch in CLI files. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix ProblemSchemaEntry to include new required fields (display_name, aliases, dimensions) - Add `sat` keyword to declare_variants! macro call - Optimize is_valid_partition to single-pass edge counting (was O(q*m)) - Fix description to say "at least two edges (P3 or triangle)" instead of just "path of length 2" - Fix misleading test comment about "invalid partition" - Add CLI validation for vertex count divisible by 3 (prevents panic) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix missing closing bracket in paper problem-def block - Fix display_name casing to match paper convention (lowercase prepositions) - Add trait_consistency test entry - Add canonical model example specs (example-db) - Register example specs in graph/mod.rs Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Review Pipeline Report
Fixes Applied
🤖 Generated by review-pipeline |
Summary
Add the PartitionIntoPathsOfLength2 satisfaction problem model: given a graph G = (V, E) with |V| = 3q, determine whether V can be partitioned into q disjoint triples such that each triple induces at least 2 edges (a path of length 2 or a triangle).
Fixes #227