Skip to content

Commit 3ee5da8

Browse files
GiggleLiuclaude
andauthored
Design: trait system refactoring for contributor ergonomics (#50)
* docs: add trait system refactoring design plan Design for simplifying types and interfaces to lower the contributor barrier. Key changes: NumericSize supertrait, Weights trait (with real Unweighted type), minimal Problem trait (dims + evaluate), removal of CSP trait, and trait-bound-based macro extraction. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: add trait refactoring implementation plan 12-task plan with TDD approach: NumericSize/Weights traits, ProblemV2 minimal trait (dims + evaluate), OptimizationProblemV2, simplified ReductionResult, trait-bound-based macro, and parallel migration strategy. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * save * feat: add NumericSize trait, Weights trait, and refactored Unweighted 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ProblemV2, OptimizationProblemV2, and Direction 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ReductionResultV2 and ReduceToV2 traits 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ProblemV2 impl for MaximumIndependentSet (proof of concept) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ProblemV2 impl for MinimumVertexCover 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ProblemV2 impl for MaximumClique 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ProblemV2 impl for MaxCut 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ProblemV2 impl for MaximumMatching 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ProblemV2 impl for MinimumDominatingSet 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ProblemV2 impl for MaximalIS 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ProblemV2 impl for KColoring 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add ProblemV2 impls for all remaining models Add ProblemV2 and OptimizationProblemV2 implementations for: - Optimization: QUBO, SpinGlass, ILP - Satisfiability: Satisfiability (SAT), KSatisfiability (KSAT) - Set: MaximumSetPacking, MinimumSetCovering - Specialized: CircuitSAT, Factoring, PaintShop, BMF, BicliqueCover Pattern: Maximization problems return W::min_value() for invalid configs, minimization problems return W::max_value(), satisfaction problems use Metric=bool. All models now have ProblemV2 impls. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * feat: add SolverV2 trait and BruteForce impl with DimsIterator Add SolverV2 trait with three methods: find_best_v2 for optimization, find_satisfying and find_all_satisfying for satisfaction problems. Add DimsIterator for per-variable dimension enumeration. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: suppress unknown clippy lint warnings Add #[allow(unknown_lints)] before clippy::manual_is_multiple_of which is only available in newer clippy versions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * style: apply rustfmt formatting 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * chore: add claude-output.log to .gitignore 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * docs: add SolutionSize enum implementation plan * feat: add SolutionSize enum for explicit validity tracking 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * feat: add is_better method to SolutionSize for direction-aware comparison 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: update Solver trait and OptimizationProblem for is_better - Add is_better method to OptimizationProblem trait for direction-aware metric comparison - Remove NumericSizeBounds constraint from Solver::find_best - Remove find_all_satisfying from Solver trait (keep as internal method) - Update BruteForce to use problem.is_better() instead of direct comparison - Remove is_infeasible_metric helper and find_best_float method 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: migrate entire codebase to SolutionSize enum - Update all graph models (MIS, MVC, MaxCut, etc.) - Update set models (MaximumSetPacking, MinimumSetCovering) - Update optimization models (SpinGlass, QUBO, ILP) - Update specialized models (PaintShop, BMF, BicliqueCover) - Update all reduction rules to handle SolutionSize - Update examples and tests for new API - Remove f64 variant tests (SolutionSize requires Ord) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * fix: remove unused BruteForce fields and fix clippy warning - Remove atol/rtol fields (no longer needed without find_best_float) - Remove approx_equal method (dead code) - Fix needless_borrow warning in example 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * refactor: convert example tests to direct calls, clean up reduction macro, update docs - Convert 30 example subprocess tests to direct function calls via include! (examples expose pub fn run(), test harness calls directly — ~40s → ~17s) - Remove redundant source_graph/target_graph from all #[reduction] macros (SimpleGraph is the default, no override needed) - Update .claude/CLAUDE.md trait hierarchy for new API - Rewrite .claude/rules/ to point to reference source files instead of inline snippets that drift when the API changes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * refactor: simplify OptimizationProblem trait and unify all metrics to SolutionSize Remove is_better/is_feasible from OptimizationProblem - they are now derived from the metric type and direction. Add supertrait bound Problem<Metric = SolutionSize<Self::Value>> so the solver calls metric.is_valid() and metric.is_better() directly. - Remove NumericSizeBounds trait (dead code) - Migrate 8 unconstrained models (SpinGlass, QUBO, BMF, etc.) from raw W/i32 to SolutionSize<W> - Migrate 3 constrained models from sentinel values to SolutionSize::Invalid - Unify cut_size/compute_cut_weight into single public cut_size function - Update all tests, examples, and documentation Each model's OptimizationProblem impl shrinks from ~15 lines to ~4 lines. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> * fix: address PR review comments - Relax KColoring W bounds to Clone + Default + 'static (W unused in logic) - Panic on unbounded ILP variables in dims() instead of silent failure - Fix extra space in minimumvertexcover_minimumsetcovering test - Remove duplicate test_dims_iterator_zero_dim in config.rs - Restore variant_to_map calls in all 21 example files (was exporting empty maps) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent bf0c0e6 commit 3ee5da8

181 files changed

Lines changed: 7006 additions & 7164 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.

.claude/CLAUDE.md

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -34,47 +34,49 @@ make test clippy # Must pass before PR
3434
- `src/models/` - Problem implementations (SAT, Graph, Set, Optimization)
3535
- `src/rules/` - Reduction rules + inventory registration
3636
- `src/solvers/` - BruteForce solver, ILP solver (feature-gated)
37-
- `src/traits.rs` - `Problem`, `ConstraintSatisfactionProblem` traits
37+
- `src/traits.rs` - `Problem`, `OptimizationProblem` traits
3838
- `src/rules/traits.rs` - `ReduceTo<T>`, `ReductionResult` traits
3939
- `src/registry/` - Compile-time reduction metadata collection
4040
- `src/unit_tests/` - Unit test files (mirroring `src/` structure, referenced via `#[path]`)
41-
- `tests/main.rs` - Integration tests (modules in `tests/suites/`)
41+
- `tests/main.rs` - Integration tests (modules in `tests/suites/`); example tests use `include!` for direct invocation (no subprocess)
4242
- `tests/data/` - Ground truth JSON for integration tests
4343
- `scripts/` - Python test data generation scripts (managed with `uv`)
4444
- `docs/plans/` - Implementation plans
4545

4646
### Trait Hierarchy
4747

4848
```
49-
Problem (core trait - all problems must implement)
49+
Problem (core trait all problems must implement)
5050
51-
├── const NAME: &'static str // Problem name, e.g., "MaximumIndependentSet"
52-
├── type GraphType: GraphMarker // Graph topology marker
53-
├── type Weight: NumericWeight // Weight type (i32, f64, Unweighted)
54-
├── type Size // Objective value type
51+
├── const NAME: &'static str // e.g., "MaximumIndependentSet"
52+
├── type Metric: Clone // SolutionSize<W> for optimization, bool for satisfaction
53+
├── fn dims(&self) -> Vec<usize> // config space: [2, 2, 2] for 3 binary variables
54+
├── fn evaluate(&self, config) -> Metric
55+
├── fn variant() -> Vec<(&str, &str)> // [("graph","SimpleGraph"), ("weight","i32")]
56+
└── fn num_variables(&self) -> usize // default: dims().len()
57+
58+
OptimizationProblem : Problem<Metric = SolutionSize<Self::Value>> (extension for optimization)
5559
56-
├── fn num_variables(&self) -> usize
57-
├── fn num_flavors(&self) -> usize // Usually 2 for binary problems
58-
├── fn problem_size(&self) -> ProblemSize
59-
├── fn energy_mode(&self) -> EnergyMode
60-
├── fn solution_size(&self, config) -> SolutionSize
61-
└── ... (default methods: variables, flavors, is_valid_config)
62-
63-
ConstraintSatisfactionProblem : Problem (extension for CSPs)
64-
65-
├── fn constraints(&self) -> Vec<LocalConstraint>
66-
├── fn objectives(&self) -> Vec<LocalSolutionSize>
67-
├── fn weights(&self) -> Vec<Self::Size>
68-
├── fn set_weights(&mut self, weights)
69-
├── fn is_weighted(&self) -> bool
70-
└── ... (default methods: is_satisfied, compute_objective)
60+
├── type Value: PartialOrd + Clone // inner objective type (i32, f64, etc.)
61+
└── fn direction(&self) -> Direction // Maximize or Minimize
62+
```
63+
64+
**Satisfaction problems** (e.g., `Satisfiability`) use `Metric = bool` and do not implement `OptimizationProblem`.
65+
66+
**Optimization problems** (e.g., `MaximumIndependentSet`) use `Metric = SolutionSize<W>` where:
67+
```rust
68+
enum SolutionSize<T> { Valid(T), Invalid } // Invalid = infeasible config
69+
enum Direction { Maximize, Minimize }
7170
```
7271

7372
### Key Patterns
7473
- Problems parameterized by weight type `W` and graph type `G`
7574
- `ReductionResult` provides `target_problem()` and `extract_solution()`
75+
- `Solver::find_best()` for optimization problems, `Solver::find_satisfying()` for `Metric = bool`
7676
- Graph types: SimpleGraph, GridGraph, UnitDiskGraph, Hypergraph
7777
- Weight types: `Unweighted` (marker), `i32`, `f64`
78+
- Weight management via inherent methods (`weights()`, `set_weights()`, `is_weighted()`), not traits
79+
- `NumericSize` supertrait bundles common numeric bounds (`Clone + Default + PartialOrd + Num + Zero + Bounded + AddAssign + 'static`)
7880

7981
### Problem Names
8082
Problem types use explicit optimization prefixes:
@@ -94,7 +96,7 @@ Reduction graph nodes use variant IDs: `ProblemName[/GraphType][/Weighted]`
9496
### File Naming
9597
- Reduction files: `src/rules/<source>_<target>.rs` (e.g., `maximumindependentset_qubo.rs`)
9698
- Model files: `src/models/<category>/<name>.rs` (e.g., `maximum_independent_set.rs`)
97-
- Example files: `examples/reduction_<source>_to_<target>.rs`
99+
- Example files: `examples/reduction_<source>_to_<target>.rs` (must have `pub fn run()` + `fn main() { run() }`)
98100
- Test naming: `test_<source>_to_<target>_closed_loop`
99101

100102
### Paper (docs/paper/reductions.typ)

.claude/rules/adding-models.md

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,35 @@ paths:
55

66
# Adding a Model (Problem Type)
77

8-
**Reference implementation:** `src/models/graph/kcoloring.rs`
8+
**Reference implementations — read these first:**
9+
- **Optimization problem:** `src/models/graph/maximum_independent_set.rs``Problem` + `OptimizationProblem` with `Metric = SolutionSize<W>`
10+
- **Satisfaction problem:** `src/models/satisfiability/sat.rs``Problem` with `Metric = bool`
11+
- **Reference test:** `src/unit_tests/models/graph/maximum_independent_set.rs`
912

1013
## Steps
1114

12-
1. **Create** `src/models/<category>/<name>.rs` — follow the reference for struct definition, `Problem` impl, and optionally `ConstraintSatisfactionProblem` impl.
15+
1. **Create** `src/models/<category>/<name>.rs` — follow the reference for struct definition, `Problem` impl, and `OptimizationProblem` impl (if applicable).
1316
2. **Register** in `src/models/<category>/mod.rs`.
1417
3. **Add tests** in `src/unit_tests/models/<category>/<name>.rs` (linked via `#[path]`).
1518
4. **Document** in `docs/paper/reductions.typ`: add `display-name` entry and `#problem-def("Name")[definition...]`.
1619

20+
## Trait Implementations
21+
22+
Every problem must implement `Problem` (see `src/traits.rs`). Key points:
23+
24+
- **`type Metric`**`SolutionSize<W>` for optimization, `bool` for satisfaction
25+
- **`fn dims()`** — configuration space dimensions (e.g., `vec![2; n]` for n binary variables)
26+
- **`fn evaluate()`** — return `SolutionSize::Valid(value)` / `SolutionSize::Invalid` for optimization, or `bool` for satisfaction
27+
- **`fn variant()`** — graph and weight type metadata for the reduction registry
28+
29+
Optimization problems additionally implement `OptimizationProblem` (see `src/traits.rs`):
30+
- **`type Value`** — the inner objective type (e.g., `i32`, `f64`, `W`)
31+
- **`fn direction()`**`Direction::Maximize` or `Direction::Minimize`
32+
33+
The supertrait `Problem<Metric = SolutionSize<Self::Value>>` ensures the solver can call `metric.is_valid()` and `metric.is_better()` directly — no per-problem customization needed.
34+
35+
Weight management (`weights()`, `set_weights()`, `is_weighted()`) goes on inherent `impl` blocks, not traits. See the reference implementation for the pattern.
36+
1737
## Categories
1838

1939
- `src/models/satisfiability/` — Satisfiability, KSatisfiability, CircuitSAT

.claude/rules/adding-reductions.md

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ paths:
55

66
# Adding a Reduction Rule (A -> B)
77

8-
**Reference implementation:** `src/rules/minimumvertexcover_maximumindependentset.rs`
9-
**Reference test:** `src/unit_tests/rules/minimumvertexcover_maximumindependentset.rs`
10-
**Reference example:** `examples/reduction_minimumvertexcover_to_maximumindependentset.rs`
11-
**Reference paper entry:** `docs/paper/reductions.typ` (search for `MinimumVertexCover` `MaximumIndependentSet`)
8+
**Reference implementations — read these first:**
9+
- **Reduction rule:** `src/rules/minimumvertexcover_maximumindependentset.rs``ReductionResult` + `ReduceTo` + `#[reduction]` macro
10+
- **Unit test:** `src/unit_tests/rules/minimumvertexcover_maximumindependentset.rs` — closed-loop + edge cases
11+
- **Example program:** `examples/reduction_minimumvertexcover_to_maximumindependentset.rs` — create, reduce, solve, extract, verify, export
12+
- **Paper entry:** `docs/paper/reductions.typ` (search for `MinimumVertexCover` `MaximumIndependentSet`)
13+
- **Traits:** `src/rules/traits.rs``ReductionResult` and `ReduceTo` trait definitions
1214

1315
## 0. Before Writing Code
1416

@@ -21,9 +23,10 @@ paths:
2123
## 1. Implement
2224

2325
Create `src/rules/<source>_<target>.rs` following the reference. Key pieces:
24-
- `ReductionResult` struct + impl (`target_problem`, `extract_solution`, `source_size`, `target_size`)
25-
- `#[reduction(...)]` macro on `ReduceTo<Target> for Source` impl (auto-generates `inventory::submit!`)
26-
- `#[cfg(test)] #[path = ...]` linking to unit tests
26+
27+
- **`ReductionResult` struct + impl**`target_problem()` + `extract_solution()` (see reference)
28+
- **`ReduceTo` impl with `#[reduction(...)]` macro** — auto-generates `inventory::submit!`; only `overhead` attribute needed (graph/weight types are inferred, defaulting to `SimpleGraph`/`Unweighted`)
29+
- **`#[cfg(test)] #[path = ...]`** linking to unit tests
2730

2831
Register in `src/rules/mod.rs`.
2932

@@ -36,6 +39,14 @@ Register in `src/rules/mod.rs`.
3639

3740
Add `examples/reduction_<source>_to_<target>.rs` — create, reduce, solve, extract, verify, export JSON (see reference example).
3841

42+
Examples must expose `pub fn run()` with `fn main() { run() }` so they can be tested directly via `include!` (no subprocess). Use regular comments (`//`) not inner doc comments (`//!`), and hardcode the example name instead of using `env!("CARGO_BIN_NAME")`.
43+
44+
Register the example in `tests/suites/examples.rs` by adding:
45+
```rust
46+
example_test!(reduction_<source>_to_<target>);
47+
example_fn!(test_<source>_to_<target>, reduction_<source>_to_<target>);
48+
```
49+
3950
## 4. Document
4051

4152
Update `docs/paper/reductions.typ` — add `reduction-rule("Source", "Target", ...)` with proof sketch (see `rules/documentation.md`).

.claude/rules/testing.md

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Testing Requirements
22

3-
**Reference test:** `src/unit_tests/rules/minimumvertexcover_maximumindependentset.rs`
3+
**Reference implementations — read these first:**
4+
- **Reduction test:** `src/unit_tests/rules/minimumvertexcover_maximumindependentset.rs` — closed-loop pattern
5+
- **Model test:** `src/unit_tests/models/graph/maximum_independent_set.rs` — evaluation, serialization
6+
- **Solver test:** `src/unit_tests/solvers/brute_force.rs``find_best` + `find_satisfying`
7+
- **Trait definitions:** `src/traits.rs` (`Problem`, `OptimizationProblem`), `src/solvers/mod.rs` (`Solver`)
48

59
## Coverage
610

@@ -12,6 +16,14 @@ New code must have >95% test coverage. Run `make coverage` to check.
1216
- Model tests: `test_<model>_basic`, `test_<model>_serialization`
1317
- Solver tests: `test_<solver>_<problem>`
1418

19+
## Key Testing Patterns
20+
21+
Follow the reference files above for exact API usage. Summary:
22+
23+
- `solver.find_best(&problem)` — for optimization problems (`OptimizationProblem`, `Metric = SolutionSize<W>`)
24+
- `solver.find_satisfying(&problem)` — for satisfaction problems (`Metric = bool`)
25+
- `problem.evaluate(&config)` — returns `SolutionSize::Valid(value)` / `SolutionSize::Invalid` for optimization, `bool` for satisfaction
26+
1527
## File Organization
1628

1729
Unit tests live in `src/unit_tests/`, mirroring `src/` structure. Source files reference them via `#[path]`:
@@ -25,6 +37,18 @@ mod tests;
2537

2638
Integration tests are in `tests/suites/`, consolidated through `tests/main.rs`.
2739

40+
## Example Tests
41+
42+
**Reference:** `tests/suites/examples.rs` — macro-based test harness
43+
44+
Example programs (`examples/reduction_*.rs`) are tested via `include!` in `tests/suites/examples.rs` — each example is compiled directly into the test binary (no subprocess overhead). Each example must expose a `pub fn run()` entry point. See any existing example (e.g., `examples/reduction_minimumvertexcover_to_maximumindependentset.rs`) for the pattern:
45+
46+
- `pub fn run()` with logic + `fn main() { run() }`
47+
- Regular comments (`//`) not inner doc comments (`//!`)
48+
- Hardcoded example name, not `env!("CARGO_BIN_NAME")`
49+
50+
The test harness auto-registers each example as a separate `#[test]`, so `cargo test` runs them in parallel.
51+
2852
## Before PR
2953

3054
```bash

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,6 @@ pkgref/
7474

7575
# Generated example outputs
7676
docs/paper/examples/
77+
78+
# Claude Code logs
79+
claude-output.log

Makefile

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Makefile for problemreductions
22

3-
.PHONY: help build test fmt clippy doc mdbook paper examples clean coverage rust-export compare qubo-testdata export-schemas release
3+
.PHONY: help build test fmt clippy doc mdbook paper examples clean coverage rust-export compare qubo-testdata export-schemas release run-plan
44

55
# Default target
66
help:
@@ -22,6 +22,7 @@ help:
2222
@echo " export-schemas - Export problem schemas to JSON"
2323
@echo " qubo-testdata - Regenerate QUBO test data (requires uv)"
2424
@echo " release V=x.y.z - Tag and push a new release (triggers CI publish)"
25+
@echo " run-plan - Execute a plan with Claude autorun (latest plan in docs/plans/)"
2526

2627
# Build the project
2728
build:
@@ -146,3 +147,30 @@ compare: rust-export
146147
echo "Julia: $$(jq '{nodes: .num_grid_nodes, overhead: .mis_overhead, tape: .num_tape_entries}' tests/data/$${graph}_triangular_trace.json)"; \
147148
echo "Rust: $$(jq '{nodes: .stages[3].num_nodes, overhead: .total_overhead, tape: ((.crossing_tape | length) + (.simplifier_tape | length))}' tests/data/$${graph}_rust_triangular.json)"; \
148149
done
150+
151+
# Run a plan with Claude
152+
# Usage: make run-plan [INSTRUCTIONS="..."] [OUTPUT=output.log] [AGENT_TYPE=claude]
153+
# PLAN_FILE defaults to the most recently modified file in docs/plans/
154+
INSTRUCTIONS ?=
155+
OUTPUT ?= claude-output.log
156+
AGENT_TYPE ?= claude
157+
158+
run-plan:
159+
PLAN_FILE ?= $(shell ls -t docs/plans/*.md 2>/dev/null | head -1)
160+
@NL=$$'\n'; \
161+
BRANCH=$$(git branch --show-current); \
162+
if [ "$(AGENT_TYPE)" = "claude" ]; then \
163+
PROCESS="1. Read the plan file$${NL}2. Use /subagent-driven-development to execute tasks$${NL}3. Push: git push origin $$BRANCH$${NL}4. Post summary"; \
164+
else \
165+
PROCESS="1. Read the plan file$${NL}2. Execute the tasks step by step. For each task, implement and test before moving on.$${NL}3. Push: git push origin $$BRANCH$${NL}4. Post summary"; \
166+
fi; \
167+
PROMPT="Execute the plan in '$${PLAN_FILE}'."; \
168+
if [ -n "$(INSTRUCTIONS)" ]; then \
169+
PROMPT="$${PROMPT}$${NL}$${NL}## Additional Instructions$${NL}$(INSTRUCTIONS)"; \
170+
fi; \
171+
PROMPT="$${PROMPT}$${NL}$${NL}## Process$${NL}$${PROCESS}$${NL}$${NL}## Rules$${NL}- Tests should be strong enough to catch regressions.$${NL}- Do not modify tests to make them pass.$${NL}- Test failure must be reported."; \
172+
echo "=== Prompt ===" && echo "$$PROMPT" && echo "===" ; \
173+
claude --dangerously-skip-permissions \
174+
--model claude-opus-4-6 \
175+
--max-turns 500 \
176+
-p "$$PROMPT" 2>&1 | tee "$(OUTPUT)"

benches/solver_benchmarks.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
//! Benchmarks for the BruteForce solver on various problem types.
22
33
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
4-
use std::hint::black_box;
54
use problemreductions::models::graph::*;
6-
use problemreductions::topology::SimpleGraph;
75
use problemreductions::models::optimization::*;
86
use problemreductions::models::satisfiability::*;
97
use problemreductions::models::set::*;
108
use problemreductions::models::specialized::*;
119
use problemreductions::prelude::*;
10+
use problemreductions::topology::SimpleGraph;
11+
use std::hint::black_box;
1212

1313
/// Benchmark MaximumIndependentSet on graphs of varying sizes.
1414
fn bench_independent_set(c: &mut Criterion) {
@@ -78,19 +78,19 @@ fn bench_satisfiability(c: &mut Criterion) {
7878
})
7979
.collect();
8080

81-
let problem = Satisfiability::<i32>::new(*num_vars, clauses);
81+
let problem = Satisfiability::new(*num_vars, clauses);
8282
let solver = BruteForce::new();
8383

8484
group.bench_with_input(BenchmarkId::new("3-sat", num_vars), num_vars, |b, _| {
85-
b.iter(|| solver.find_best(black_box(&problem)))
85+
b.iter(|| solver.find_all_satisfying(black_box(&problem)))
8686
});
8787
}
8888

8989
group.finish();
9090
}
9191

9292
/// Benchmark SpinGlass on varying sizes.
93-
#[allow(clippy::manual_is_multiple_of)] // Type inference issues with is_multiple_of
93+
#[allow(unknown_lints, clippy::manual_is_multiple_of)] // Type inference issues with is_multiple_of
9494
fn bench_spin_glass(c: &mut Criterion) {
9595
let mut group = c.benchmark_group("SpinGlass");
9696

@@ -142,7 +142,7 @@ fn bench_coloring(c: &mut Criterion) {
142142
let solver = BruteForce::new();
143143

144144
group.bench_with_input(BenchmarkId::new("path_3colors", n), n, |b, _| {
145-
b.iter(|| solver.find_best(black_box(&problem)))
145+
b.iter(|| solver.find_all_satisfying(black_box(&problem)))
146146
});
147147
}
148148

@@ -194,13 +194,14 @@ fn bench_comparison(c: &mut Criterion) {
194194
let solver = BruteForce::new();
195195

196196
// MaximumIndependentSet with 8 vertices
197-
let is_problem = MaximumIndependentSet::<SimpleGraph, i32>::new(8, vec![(0, 1), (2, 3), (4, 5), (6, 7)]);
197+
let is_problem =
198+
MaximumIndependentSet::<SimpleGraph, i32>::new(8, vec![(0, 1), (2, 3), (4, 5), (6, 7)]);
198199
group.bench_function("MaximumIndependentSet", |b| {
199200
b.iter(|| solver.find_best(black_box(&is_problem)))
200201
});
201202

202203
// SAT with 8 variables
203-
let sat_problem = Satisfiability::<i32>::new(
204+
let sat_problem = Satisfiability::new(
204205
8,
205206
vec![
206207
CNFClause::new(vec![1, 2, 3]),
@@ -210,7 +211,7 @@ fn bench_comparison(c: &mut Criterion) {
210211
],
211212
);
212213
group.bench_function("Satisfiability", |b| {
213-
b.iter(|| solver.find_best(black_box(&sat_problem)))
214+
b.iter(|| solver.find_all_satisfying(black_box(&sat_problem)))
214215
});
215216

216217
// SpinGlass with 8 spins

0 commit comments

Comments
 (0)