Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
03f90c9
save
GiggleLiu Mar 14, 2026
3275cd7
docs: add variant default resolution design
GiggleLiu Mar 14, 2026
74ee19c
save
GiggleLiu Mar 14, 2026
e73d583
docs: refine CLI path behavior in variant plan
GiggleLiu Mar 14, 2026
37fc567
refactor(example-db): make rule builders canonical
GiggleLiu Mar 14, 2026
ba74eba
test(cli): round-trip canonical examples through solve
GiggleLiu Mar 14, 2026
91dbcf9
feat(example-db): finalize structural example database
GiggleLiu Mar 14, 2026
2a5be4a
update plan
GiggleLiu Mar 14, 2026
00c40de
docs: add variant implementation plan
GiggleLiu Mar 14, 2026
3a7ba81
test: add failing tests for VariantSpec, default_variant_for, and exp…
GiggleLiu Mar 14, 2026
cc3f77a
feat: add explicit variant defaults
GiggleLiu Mar 14, 2026
c22cdd4
feat: mark default problem variants
GiggleLiu Mar 14, 2026
a849e12
feat: unify CLI problem resolution with exact-node semantics
GiggleLiu Mar 14, 2026
aedd778
docs: align MCP tools and CLI docs with exact-node variant semantics
GiggleLiu Mar 14, 2026
0ef4534
fix: require exact source+target variant match in find_best_entry
GiggleLiu Mar 14, 2026
ade48b7
style: fix formatting in MCP tools and tests
GiggleLiu Mar 14, 2026
d2e5980
grand clean up
GiggleLiu Mar 14, 2026
d3f2f2a
feat(registry): add core dynamic problem types
GiggleLiu Mar 14, 2026
8e8d3ff
feat(macros): add transitional solver-kind dispatch generation
GiggleLiu Mar 14, 2026
df8de8f
feat(registry): register load serialize and solve dispatch metadata
GiggleLiu Mar 14, 2026
75dac09
refactor(registry): require solver kind in variant registrations
GiggleLiu Mar 14, 2026
acbd24c
refactor(cli): use registry-backed dynamic problem dispatch
GiggleLiu Mar 14, 2026
400c4cb
test(dispatch): finalize registry-backed dispatch verification
GiggleLiu Mar 14, 2026
f69eeb7
update
GiggleLiu Mar 14, 2026
42cf5e8
feat(registry): add problem type catalog and typed refs
GiggleLiu Mar 14, 2026
8692a53
refactor(cli): resolve problem specs through the catalog
GiggleLiu Mar 14, 2026
624b4c2
feat(models): declare catalog metadata alongside schemas
GiggleLiu Mar 14, 2026
acffc34
update
GiggleLiu Mar 14, 2026
8f128f5
feat(rules): add stable auto-generated rule IDs to reduction entries
GiggleLiu Mar 14, 2026
801f0dd
save
GiggleLiu Mar 14, 2026
bc41098
refactor(example-db): finalize per-module specs with invariant tests
GiggleLiu Mar 14, 2026
e7941b1
feat(core): add Problem::problem_type() catalog bridge method
GiggleLiu Mar 14, 2026
0b14243
fix: remove unused imports and suppress dead_code warnings in specs
GiggleLiu Mar 14, 2026
c68853d
update
GiggleLiu Mar 14, 2026
bb405ab
update
GiggleLiu Mar 14, 2026
36de7eb
update
GiggleLiu Mar 14, 2026
8007cde
test: improve coverage for export, variant, analysis, and registry
GiggleLiu Mar 14, 2026
f655a09
chore: remove ephemeral plan files from PR
GiggleLiu Mar 14, 2026
f4e96ab
update
GiggleLiu Mar 14, 2026
5dee8ce
docs: update CLAUDE.md model lists and trait hierarchy
GiggleLiu Mar 14, 2026
f60cfad
docs: replace hardcoded model/rule lists with CLI commands in CLAUDE.md
GiggleLiu Mar 14, 2026
e1b3d0a
feat(cli): add `pred list --rules` to enumerate all reduction rules
GiggleLiu Mar 14, 2026
a271a76
feat(cli): add complexity to `pred list`, improve `--rules` format, u…
GiggleLiu Mar 14, 2026
5ad7cb1
fix(cli): improve `pred list` and `pred list --rules` table formatting
GiggleLiu Mar 14, 2026
2bd35c6
refactor: remove 3SAT alias, use KSAT/K3 instead
GiggleLiu Mar 14, 2026
2921a8c
perf: remove mcp from default CLI features for faster dev builds
GiggleLiu Mar 14, 2026
ce22dd3
feat: add `make mcp` target for CLI with MCP support
GiggleLiu Mar 14, 2026
2399ca5
fix: remove unused mut from variant_values
GiggleLiu Mar 14, 2026
b927d04
revert: restore single-line overhead in `pred list --rules`
GiggleLiu Mar 14, 2026
4832d9f
fix cli
GiggleLiu Mar 14, 2026
1e90d30
fix tests
GiggleLiu Mar 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 27 additions & 16 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,8 @@ make diagrams # Generate SVG diagrams from Typst (light + dark)
make examples # Generate example JSON for paper
make compare # Generate and compare Rust mapping exports
make jl-testdata # Regenerate Julia parity test data (requires julia)
make cli # Build the pred CLI tool (release mode)
make cli # Build the pred CLI tool (without MCP, fast)
make mcp # Build the pred CLI tool with MCP server support
make cli-demo # Run closed-loop CLI demo (exercises all commands)
make mcp-test # Run MCP server tests (unit + integration)
make run-plan # Execute a plan with Claude autorun
Expand All @@ -64,11 +65,12 @@ make release V=x.y.z # Tag and push a new release (CI publishes to crates.io)

### Core Modules
- `src/models/` - Problem implementations organized by input structure:
- `graph/` - Problems on graphs (MIS, MaxClique, MaxCut, MinVC, MinDS, MaxMatching, MaximalIS, KColoring, TSP, SpinGlass, BicliqueCover)
- `formula/` - Logical formulas and circuits (SAT, k-SAT, CircuitSAT)
- `set/` - Set systems (MinSetCovering, MaxSetPacking)
- `algebraic/` - Matrices, linear systems, lattices (QUBO, ILP, CVP, BMF)
- `misc/` - Unique input structures (BinPacking, PaintShop, Factoring)
- `graph/` - Graph-input problems
- `formula/` - Boolean formulas and circuits
- `set/` - Set systems (universe + subsets)
- `algebraic/` - Matrices, linear systems, lattices
- `misc/` - Unique input structures
- Run `pred list` for the full catalog of problems, variants, and reductions; `pred show <name>` for details on a specific problem
- `src/rules/` - Reduction rules + inventory registration
- `src/solvers/` - BruteForce solver, ILP solver (feature-gated)
- `src/traits.rs` - `Problem`, `OptimizationProblem`, `SatisfactionProblem` traits
Expand All @@ -91,7 +93,8 @@ Problem (core trait — all problems must implement)
├── fn dims(&self) -> Vec<usize> // config space: [2, 2, 2] for 3 binary variables
├── fn evaluate(&self, config) -> Metric
├── fn variant() -> Vec<(&str, &str)> // e.g., [("graph","SimpleGraph"), ("weight","i32")]
└── fn num_variables(&self) -> usize // default: dims().len()
├── fn num_variables(&self) -> usize // default: dims().len()
└── fn problem_type() -> ProblemType // catalog bridge: registry lookup by NAME

OptimizationProblem : Problem<Metric = SolutionSize<Self::Value>> (extension for optimization)
Expand All @@ -111,7 +114,7 @@ enum Direction { Maximize, Minimize }

### Key Patterns
- `variant_params!` macro implements `Problem::variant()` — e.g., `crate::variant_params![G, W]` for two type params, `crate::variant_params![]` for none (see `src/variant.rs`)
- `declare_variants!` proc macro registers concrete type instantiations with best-known complexity must appear in every model file (see `src/models/graph/maximum_independent_set.rs`). Variable names in complexity strings are validated at compile time against actual getter methods.
- `declare_variants!` proc macro registers concrete type instantiations with best-known complexity and registry-backed dynamic dispatch metadata — every entry must specify `opt` or `sat`, and one entry per problem may be marked `default` (see `src/models/graph/maximum_independent_set.rs`). Variable names in complexity strings are validated at compile time against actual getter methods.
- Problems parameterized by graph type `G` and optionally weight type `W` (problem-dependent)
- `ReductionResult` provides `target_problem()` and `extract_solution()`
- `Solver::find_best()` → `Option<Vec<usize>>` for optimization problems; `Solver::find_satisfying()` → `Option<Vec<usize>>` for `Metric = bool`
Expand Down Expand Up @@ -142,25 +145,31 @@ impl ReduceTo<Target> for Source { ... }
- `Expr::parse()` provides runtime parsing for cross-check tests that compare compiled vs symbolic evaluation

### Problem Names
Problem types use explicit optimization prefixes:
- `MaximumIndependentSet`, `MaximumClique`, `MaximumMatching`, `MaximumSetPacking`
- `MinimumVertexCover`, `MinimumDominatingSet`, `MinimumSetCovering`
- No prefix: `MaxCut`, `SpinGlass`, `QUBO`, `ILP`, `Satisfiability`, `KSatisfiability`, `CircuitSAT`, `Factoring`, `MaximalIS`, `PaintShop`, `BicliqueCover`, `BMF`, `KColoring`, `TravelingSalesman`
Problem types use explicit optimization prefixes (`Maximum...`, `Minimum...`) or no prefix. Run `pred list` for the full catalog. Common aliases (e.g., `MIS` → `MaximumIndependentSet`, `MVC` → `MinimumVertexCover`) are shown in the `Aliases` column.

### Problem Variant IDs
### Problem Variants
Reduction graph nodes use variant key-value pairs from `Problem::variant()`:
- Base: `MaximumIndependentSet` (empty variant = defaults)
- Graph variant: `MaximumIndependentSet {graph: "KingsSubgraph", weight: "One"}`
- Weight variant: `MaximumIndependentSet {graph: "SimpleGraph", weight: "f64"}`
- Default variant ranking: `SimpleGraph`, `One`, `KN` are considered default values; variants with the most default values sort first
- Nodes come exclusively from `#[reduction]` registrations; natural edges between same-name variants are inferred from the graph/weight subtype partial order
- Each primitive reduction is determined by the exact `(source_variant, target_variant)` endpoint pair
- `#[reduction]` accepts only `overhead = { ... }`

### Extension Points
- New models register dynamic load/serialize/brute-force dispatch through `declare_variants!` in the model file, not by adding manual match arms in the CLI
- Exact registry dispatch lives in `src/registry/`; alias resolution and partial/default variant resolution live in `problemreductions-cli/src/problem_name.rs`
- `pred create` UX lives in `problemreductions-cli/src/commands/create.rs`
- Canonical paper and CLI examples live in `src/example_db/model_builders.rs` and `src/example_db/rule_builders.rs`

## Conventions

### File Naming
- Reduction files: `src/rules/<source>_<target>.rs` (e.g., `maximumindependentset_qubo.rs`)
- Model files: `src/models/<category>/<name>.rs` — category is by input structure: `graph/` (graph input), `formula/` (boolean formula/circuit), `set/` (universe + subsets), `algebraic/` (matrix/linear system/lattice), `misc/` (other)
- Example files: `examples/reduction_<source>_to_<target>.rs` (must have `pub fn run()` + `fn main() { run() }`)
- Canonical examples: builder functions in `src/example_db/rule_builders.rs` and `src/example_db/model_builders.rs`
- Example binaries in `examples/`: utility/export tools and pedagogical demos only (not per-reduction files)
- Test naming: `test_<source>_to_<target>_closed_loop`

### Paper (docs/paper/reductions.typ)
Expand Down Expand Up @@ -194,14 +203,15 @@ See Key Patterns above for solver API signatures. Follow the reference files for

### File Organization

Unit tests in `src/unit_tests/` linked via `#[path]` (see Core Modules above). Integration tests in `tests/suites/`, consolidated through `tests/main.rs`. Example tests in `tests/suites/examples.rs` using `include!` for direct invocation.
Unit tests in `src/unit_tests/` linked via `#[path]` (see Core Modules above). Integration tests in `tests/suites/`, consolidated through `tests/main.rs`. Canonical example-db coverage lives in `src/unit_tests/example_db.rs`.

## Documentation Locations
- `README.md` — Project overview and quickstart
- `.claude/` — Claude Code instructions and skills
- `docs/book/` — mdBook user documentation (built with `make doc`)
- `docs/paper/reductions.typ` — Typst paper with problem definitions and reduction theorems
- `examples/` — Reduction example code (also used in paper and tests)
- `src/example_db/` — Canonical model/rule examples: `model_builders.rs`, `rule_builders.rs` (in-memory builders), `specs.rs` (per-module invariant specs), consumed by `pred create --example` and paper exports
- `examples/` — Export utilities, graph-analysis helpers, and pedagogical demos

## Documentation Requirements

Expand Down Expand Up @@ -254,3 +264,4 @@ Overhead expressions describe how target problem size relates to source problem
2. Check that each field (e.g., `num_vertices`, `num_edges`, `num_sets`) matches the constructed target problem
3. Watch for common errors: universe elements mismatch (edge indices vs vertex indices), worst-case edge counts in intersection graphs (quadratic, not linear), constant factors in circuit constructions
4. Test with concrete small instances: construct a source problem, run the reduction, and compare target sizes against the formula
5. Ensure there is only one primitive reduction registration for each exact source/target variant pair; wrap shared helpers instead of registering duplicate endpoints
39 changes: 28 additions & 11 deletions .claude/skills/add-model/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,10 @@ Read these first to understand the patterns:
- **Satisfaction problem:** `src/models/formula/sat.rs`
- **Model tests:** `src/unit_tests/models/graph/maximum_independent_set.rs`
- **Trait definitions:** `src/traits.rs` (`Problem`, `OptimizationProblem`, `SatisfactionProblem`)
- **CLI dispatch:** `problemreductions-cli/src/dispatch.rs`
- **Registry dispatch boundary:** `src/registry/mod.rs`, `src/registry/variant.rs`
- **CLI aliases:** `problemreductions-cli/src/problem_name.rs`
- **CLI creation:** `problemreductions-cli/src/commands/create.rs`
- **Canonical model examples:** `src/example_db/model_builders.rs`

## Step 1: Determine the category

Expand Down Expand Up @@ -92,16 +94,20 @@ Add `declare_variants!` at the bottom of the model file (after the trait impls,

```rust
crate::declare_variants! {
ProblemName<SimpleGraph, i32> => "1.1996^num_vertices",
ProblemName<SimpleGraph, One> => "1.1996^num_vertices",
opt ProblemName<SimpleGraph, i32> => "1.1996^num_vertices",
default opt ProblemName<SimpleGraph, One> => "1.1996^num_vertices",
}
```

- Each entry must include an explicit solver kind:
- `opt` for optimization problems (`BruteForce::find_best`)
- `sat` for satisfaction problems (`BruteForce::find_satisfying`)
- Mark exactly one concrete variant `default` when the problem has multiple registered variants
- The complexity string references the getter method names from Step 1.5 (e.g., `num_vertices`) — variable names are validated at compile time against actual getters, so typos cause compile errors
- One entry per supported `(graph, weight)` combination
- The string is parsed as an `Expr` AST — supports `+`, `-`, `*`, `/`, `^`, `exp()`, `log()`, `sqrt()`
- Use only concrete numeric values (e.g., `"1.1996^num_vertices"`, not `"(2-epsilon)^num_vertices"`)
- A compiled `complexity_eval_fn` is auto-generated alongside the symbolic expression
- A compiled `complexity_eval_fn` plus registry-backed load/serialize/solve dispatch metadata are auto-generated alongside the symbolic expression
- See `src/models/graph/maximum_independent_set.rs` for the reference pattern

## Step 3: Register the model
Expand All @@ -112,13 +118,14 @@ Update these files to register the new problem type:
2. `src/models/mod.rs` -- add to the appropriate re-export line
3. `src/lib.rs` or `prelude` -- if the type should be in `prelude::*`, add it there

## Step 4: Register in CLI
## Step 4: Register for CLI discovery

Update the CLI dispatch table so `pred` can load, solve, and serialize the new problem:
The CLI now loads, serializes, and brute-force solves problems through the core registry. Do **not** add manual match arms in `problemreductions-cli/src/dispatch.rs`.

1. **`problemreductions-cli/src/dispatch.rs`:**
- Add a match arm in `load_problem()` -- use `deser_opt::<T>` for optimization or `deser_sat::<T>` for satisfaction
- Add a match arm in `serialize_any_problem()` -- use `try_ser::<T>`
1. **Registry-backed dispatch comes from `declare_variants!`:**
- Make sure every concrete variant you want the CLI to load is listed in `declare_variants!`
- Use the correct `opt`/`sat` marker per entry
- Mark the intended default variant with `default` when applicable

2. **`problemreductions-cli/src/problem_name.rs`:**
- Add a lowercase alias mapping in `resolve_alias()` (e.g., `"newproblem" => "NewProblem".to_string()`)
Expand All @@ -139,6 +146,15 @@ Update `problemreductions-cli/src/commands/create.rs` so `pred create <ProblemNa

4. **Schema alignment**: The `ProblemSchemaEntry` fields should list **constructor parameters** (what the user provides), not internal derived fields. For example, if `m` and `n` are derived from a matrix, only list `matrix` and `k` in the schema.

## Step 4.6: Add canonical model example to example_db

Add a builder function in `src/example_db/model_builders.rs` that constructs a small, canonical instance for this model. Register it in `build_model_examples()`.

This example is now the canonical source for:
- `pred create --example <PROBLEM_SPEC>`
- paper/example exports
- example-db invariants tested in `src/unit_tests/example_db.rs`

## Step 5: Write unit tests

Create `src/unit_tests/models/<category>/<name>.rs`:
Expand Down Expand Up @@ -233,12 +249,13 @@ If running standalone (not inside `make run-plan`), invoke [review-implementatio
| Missing `#[path]` test link | Add `#[cfg(test)] #[path = "..."] mod tests;` at file bottom |
| Wrong `dims()` | Must match the actual configuration space (e.g., `vec![2; n]` for binary) |
| Not registering in `mod.rs` | Must update both `<category>/mod.rs` and `models/mod.rs` |
| Forgetting `declare_variants!` | Required for variant complexity metadata used by the paper's auto-generated table |
| Forgetting CLI dispatch | Must add match arms in `dispatch.rs` (`load_problem` + `serialize_any_problem`) |
| Forgetting `declare_variants!` | Required for variant complexity metadata and registry-backed load/serialize/solve dispatch |
| Wrong `declare_variants!` syntax | Every entry now needs `opt` or `sat`; one entry per problem may be marked `default` |
| Forgetting CLI alias | Must add lowercase entry in `problem_name.rs` `resolve_alias()` |
| Inventing short aliases | Only use well-established literature abbreviations (MIS, SAT, TSP); do NOT invent new ones |
| Forgetting CLI create | Must add creation handler in `commands/create.rs` and flags in `cli.rs` |
| Missing from CLI help table | Must add entry to "Flags by problem type" table in `cli.rs` `after_help` |
| Schema lists derived fields | Schema should list constructor params, not internal fields (e.g., `matrix, k` not `matrix, m, n, k`) |
| Missing canonical model example | Add a builder in `src/example_db/model_builders.rs` and keep it aligned with paper/example workflows |
| Forgetting trait_consistency | Must add entry in `test_all_problems_implement_trait_correctly` (and `test_direction` for optimization) in `src/unit_tests/trait_consistency.rs` |
| Paper example not tested | Must include `test_<name>_paper_example` that verifies the exact instance, solution, and solution count shown in the paper |
Loading
Loading