Skip to content

Commit 3c8b3d4

Browse files
committed
Merge branch 'main' of github.com:CodingThrust/problem-reductions
2 parents d468e49 + 237db5c commit 3c8b3d4

55 files changed

Lines changed: 7571 additions & 243 deletions

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: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ make diagrams # Generate SVG diagrams from Typst (light + dark)
2727
make examples # Generate example JSON for paper
2828
make compare # Generate and compare Rust mapping exports
2929
make jl-testdata # Regenerate Julia parity test data (requires julia)
30+
make cli # Build the pred CLI tool (release mode)
31+
make cli-demo # Run closed-loop CLI demo (exercises all commands)
3032
make run-plan # Execute a plan with Claude autorun
3133
make release V=x.y.z # Tag and push a new release (CI publishes to crates.io)
3234
```
@@ -48,6 +50,7 @@ make test clippy # Must pass before PR
4850
- `src/traits.rs` - `Problem`, `OptimizationProblem`, `SatisfactionProblem` traits
4951
- `src/rules/traits.rs` - `ReduceTo<T>`, `ReductionResult` traits
5052
- `src/registry/` - Compile-time reduction metadata collection
53+
- `problemreductions-cli/` - `pred` CLI tool (separate crate in workspace)
5154
- `src/unit_tests/` - Unit test files (mirroring `src/` structure, referenced via `#[path]`)
5255
- `tests/main.rs` - Integration tests (modules in `tests/suites/`); example tests use `include!` for direct invocation (no subprocess)
5356
- `tests/data/` - Ground truth JSON for integration tests
@@ -149,6 +152,13 @@ See Key Patterns above for solver API signatures. Follow the reference files for
149152

150153
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.
151154

155+
## Documentation Locations
156+
- `README.md` — Project overview and quickstart
157+
- `.claude/` — Claude Code instructions and skills
158+
- `docs/book/` — mdBook user documentation (built with `make doc`)
159+
- `docs/paper/reductions.typ` — Typst paper with problem definitions and reduction theorems
160+
- `examples/` — Reduction example code (also used in paper and tests)
161+
152162
## Documentation Requirements
153163

154164
**Reference:** search `docs/paper/reductions.typ` for `MinimumVertexCover` `MaximumIndependentSet` to see a complete problem-def + reduction-rule example.

.github/workflows/ci.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ jobs:
2222
components: clippy
2323
- uses: Swatinem/rust-cache@v2
2424
- name: Run clippy
25-
run: cargo clippy --all-targets --all-features -- -D warnings
25+
run: cargo clippy --all-targets --features ilp-highs -- -D warnings
2626

2727
# Build and test
2828
test:
@@ -34,13 +34,13 @@ jobs:
3434
- uses: Swatinem/rust-cache@v2
3535

3636
- name: Build
37-
run: cargo build --all-features --verbose
37+
run: cargo build --features ilp-highs --verbose
3838

3939
- name: Run tests
40-
run: cargo test --all-features --verbose
40+
run: cargo test --features ilp-highs --verbose
4141

4242
- name: Run doc tests
43-
run: cargo test --doc --all-features --verbose
43+
run: cargo test --doc --features ilp-highs --verbose
4444

4545
# Code coverage
4646
coverage:
@@ -55,7 +55,7 @@ jobs:
5555
- name: Install cargo-llvm-cov
5656
uses: taiki-e/install-action@cargo-llvm-cov
5757
- name: Generate coverage
58-
run: cargo llvm-cov --all-features --workspace --lcov --output-path lcov.info
58+
run: cargo llvm-cov --features ilp-highs --workspace --lcov --output-path lcov.info
5959
- name: Upload to codecov.io
6060
uses: codecov/codecov-action@v4
6161
with:

Cargo.toml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[workspace]
2-
members = [".", "problemreductions-macros"]
2+
members = [".", "problemreductions-macros", "problemreductions-cli"]
33

44
[package]
55
name = "problemreductions"
@@ -12,8 +12,15 @@ keywords = ["np-hard", "optimization", "reduction", "sat", "graph"]
1212
categories = ["algorithms", "science"]
1313

1414
[features]
15-
default = ["ilp"]
16-
ilp = ["good_lp"]
15+
default = ["ilp-highs"]
16+
ilp = ["ilp-highs"] # backward compat shorthand
17+
ilp-solver = [] # marker: enables ILP solver code
18+
ilp-highs = ["ilp-solver", "dep:good_lp", "good_lp/highs"]
19+
ilp-coin-cbc = ["ilp-solver", "dep:good_lp", "good_lp/coin_cbc"]
20+
ilp-clarabel = ["ilp-solver", "dep:good_lp", "good_lp/clarabel"]
21+
ilp-scip = ["ilp-solver", "dep:good_lp", "good_lp/scip"]
22+
ilp-lpsolve = ["ilp-solver", "dep:good_lp", "good_lp/lpsolve"]
23+
ilp-microlp = ["ilp-solver", "dep:good_lp", "good_lp/microlp"]
1724

1825
[dependencies]
1926
petgraph = { version = "0.8", features = ["serde-1"] }
@@ -22,7 +29,7 @@ serde = { version = "1.0", features = ["derive"] }
2229
serde_json = "1.0"
2330
thiserror = "2.0"
2431
num-traits = "0.2"
25-
good_lp = { version = "1.8", default-features = false, features = ["highs"], optional = true }
32+
good_lp = { version = "1.8", default-features = false, optional = true }
2633
inventory = "0.3"
2734
ordered-float = "5.0"
2835
rand = "0.9"

Makefile

Lines changed: 152 additions & 9 deletions
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 run-plan diagrams jl-testdata
3+
.PHONY: help build test fmt clippy doc mdbook paper examples clean coverage rust-export compare qubo-testdata export-schemas release run-plan diagrams jl-testdata cli cli-demo
44

55
# Default target
66
help:
@@ -24,15 +24,17 @@ help:
2424
@echo " qubo-testdata - Regenerate QUBO test data (requires uv)"
2525
@echo " jl-testdata - Regenerate Julia parity test data (requires julia)"
2626
@echo " release V=x.y.z - Tag and push a new release (triggers CI publish)"
27+
@echo " cli - Build the pred CLI tool"
28+
@echo " cli-demo - Run closed-loop CLI demo (build + exercise all commands)"
2729
@echo " run-plan - Execute a plan with Claude autorun (latest plan in docs/plans/)"
2830

2931
# Build the project
3032
build:
31-
cargo build --all-features
33+
cargo build --features ilp-highs
3234

3335
# Run all tests (including ignored tests)
3436
test:
35-
cargo test --all-features -- --include-ignored
37+
cargo test --features ilp-highs -- --include-ignored
3638

3739
# Format code
3840
fmt:
@@ -44,14 +46,14 @@ fmt-check:
4446

4547
# Run clippy
4648
clippy:
47-
cargo clippy --all-targets --all-features -- -D warnings
49+
cargo clippy --all-targets --features ilp-highs -- -D warnings
4850

4951
# Build mdBook documentation
5052
doc:
5153
cargo run --example export_graph
5254
cargo run --example export_schemas
5355
mdbook build docs
54-
RUSTDOCFLAGS="--default-theme=dark" cargo doc --all-features --no-deps
56+
RUSTDOCFLAGS="--default-theme=dark" cargo doc --features ilp-highs --no-deps
5557
rm -rf docs/book/api
5658
cp -r target/doc docs/book/api
5759

@@ -70,7 +72,7 @@ diagrams:
7072
mdbook:
7173
cargo run --example export_graph
7274
cargo run --example export_schemas
73-
RUSTDOCFLAGS="--default-theme=dark" cargo doc --all-features --no-deps
75+
RUSTDOCFLAGS="--default-theme=dark" cargo doc --features ilp-highs --no-deps
7476
mdbook build
7577
rm -rf book/api
7678
cp -r target/doc book/api
@@ -85,9 +87,9 @@ examples:
8587
@mkdir -p docs/paper/examples
8688
@for example in $(REDUCTION_EXAMPLES); do \
8789
echo "Running $$example..."; \
88-
cargo run --all-features --example $$example || exit 1; \
90+
cargo run --features ilp-highs --example $$example || exit 1; \
8991
done
90-
cargo run --all-features --example export_petersen_mapping
92+
cargo run --features ilp-highs --example export_petersen_mapping
9193

9294
# Export problem schemas to JSON
9395
export-schemas:
@@ -102,7 +104,7 @@ paper: examples
102104
# Generate coverage report (requires: cargo install cargo-llvm-cov)
103105
coverage:
104106
@command -v cargo-llvm-cov >/dev/null 2>&1 || { echo "Installing cargo-llvm-cov..."; cargo install cargo-llvm-cov; }
105-
cargo llvm-cov --all-features --workspace --html --open
107+
cargo llvm-cov --features ilp-highs --workspace --html --open
106108

107109
# Clean build artifacts
108110
clean:
@@ -135,6 +137,10 @@ endif
135137
git push origin main --tags
136138
@echo "v$(V) pushed — CI will publish to crates.io"
137139

140+
# Build the pred CLI tool
141+
cli:
142+
cargo build -p problemreductions-cli --release
143+
138144
# Generate Rust mapping JSON exports for all graphs and modes
139145
GRAPHS := diamond bull house petersen
140146
MODES := unweighted weighted triangular
@@ -191,3 +197,140 @@ run-plan:
191197
--verbose \
192198
--max-turns 500 \
193199
-p "$$PROMPT" 2>&1 | tee "$(OUTPUT)"
200+
201+
# Closed-loop CLI demo: exercises all commands end-to-end
202+
PRED := cargo run -p problemreductions-cli --release --
203+
CLI_DEMO_DIR := /tmp/pred-cli-demo
204+
cli-demo: cli
205+
@echo "=== pred CLI closed-loop demo ==="
206+
@rm -rf $(CLI_DEMO_DIR) && mkdir -p $(CLI_DEMO_DIR)
207+
@set -e; \
208+
PRED="./target/release/pred"; \
209+
\
210+
echo ""; \
211+
echo "--- 1. list: all registered problems ---"; \
212+
$$PRED list; \
213+
$$PRED list -o $(CLI_DEMO_DIR)/problems.json; \
214+
\
215+
echo ""; \
216+
echo "--- 2. show: inspect MIS (variants, fields, reductions) ---"; \
217+
$$PRED show MIS; \
218+
$$PRED show MIS -o $(CLI_DEMO_DIR)/mis_info.json; \
219+
\
220+
echo ""; \
221+
echo "--- 3. to: explore 2-hop outgoing neighborhood ---"; \
222+
$$PRED to MIS --hops 2; \
223+
$$PRED to MIS --hops 2 -o $(CLI_DEMO_DIR)/mis_hops.json; \
224+
\
225+
echo ""; \
226+
echo "--- 4. from: incoming neighbors ---"; \
227+
$$PRED from QUBO --hops 1; \
228+
\
229+
echo ""; \
230+
echo "--- 5. path: find reduction paths ---"; \
231+
$$PRED path MIS QUBO; \
232+
$$PRED path MIS QUBO -o $(CLI_DEMO_DIR)/path_mis_qubo.json; \
233+
$$PRED path Factoring SpinGlass; \
234+
$$PRED path MIS QUBO --cost minimize:num_variables; \
235+
\
236+
echo ""; \
237+
echo "--- 6. path --all: enumerate all paths ---"; \
238+
$$PRED path MIS QUBO --all; \
239+
$$PRED path MIS QUBO --all -o $(CLI_DEMO_DIR)/all_paths/; \
240+
\
241+
echo ""; \
242+
echo "--- 7. export-graph: full reduction graph ---"; \
243+
$$PRED export-graph -o $(CLI_DEMO_DIR)/graph.json; \
244+
\
245+
echo ""; \
246+
echo "--- 8. create: build problem instances ---"; \
247+
$$PRED create MIS --edges 0-1,1-2,2-3,3-4,4-0 -o $(CLI_DEMO_DIR)/mis.json; \
248+
$$PRED create MIS --edges 0-1,1-2,2-3 --weights 2,1,3,1 -o $(CLI_DEMO_DIR)/mis_weighted.json; \
249+
$$PRED create SAT --num-vars 3 --clauses "1,2;-1,3;2,-3" -o $(CLI_DEMO_DIR)/sat.json; \
250+
$$PRED create 3SAT --num-vars 4 --clauses "1,2,3;-1,2,-3;1,-2,3" -o $(CLI_DEMO_DIR)/3sat.json; \
251+
$$PRED create QUBO --matrix "1,-0.5;-0.5,2" -o $(CLI_DEMO_DIR)/qubo.json; \
252+
$$PRED create KColoring --k 3 --edges 0-1,1-2,2-0 -o $(CLI_DEMO_DIR)/kcol.json; \
253+
$$PRED create SpinGlass --edges 0-1,1-2 -o $(CLI_DEMO_DIR)/sg.json; \
254+
$$PRED create MaxCut --edges 0-1,1-2,2-0 -o $(CLI_DEMO_DIR)/maxcut.json; \
255+
$$PRED create MVC --edges 0-1,1-2,2-3 -o $(CLI_DEMO_DIR)/mvc.json; \
256+
$$PRED create MaximumMatching --edges 0-1,1-2,2-3 -o $(CLI_DEMO_DIR)/matching.json; \
257+
$$PRED create Factoring --target 15 --bits-m 4 --bits-n 4 -o $(CLI_DEMO_DIR)/factoring.json; \
258+
$$PRED create Factoring --target 21 --bits-m 3 --bits-n 3 -o $(CLI_DEMO_DIR)/factoring2.json; \
259+
\
260+
echo ""; \
261+
echo "--- 9. evaluate: test configurations ---"; \
262+
$$PRED evaluate $(CLI_DEMO_DIR)/mis.json --config 1,0,1,0,0; \
263+
$$PRED evaluate $(CLI_DEMO_DIR)/mis.json --config 1,1,0,0,0; \
264+
$$PRED evaluate $(CLI_DEMO_DIR)/sat.json --config 0,1,1; \
265+
$$PRED evaluate $(CLI_DEMO_DIR)/mis.json --config 1,0,1,0,0 -o $(CLI_DEMO_DIR)/eval.json; \
266+
\
267+
echo ""; \
268+
echo "--- 10. solve: direct ILP (auto-reduces to ILP) ---"; \
269+
$$PRED solve $(CLI_DEMO_DIR)/mis.json; \
270+
$$PRED solve $(CLI_DEMO_DIR)/mis.json -o $(CLI_DEMO_DIR)/sol_ilp.json; \
271+
\
272+
echo ""; \
273+
echo "--- 11. solve: brute-force ---"; \
274+
$$PRED solve $(CLI_DEMO_DIR)/mis.json --solver brute-force; \
275+
\
276+
echo ""; \
277+
echo "--- 12. solve: weighted MIS ---"; \
278+
$$PRED solve $(CLI_DEMO_DIR)/mis_weighted.json; \
279+
\
280+
echo ""; \
281+
echo "--- 13. reduce: MIS → QUBO (auto-discover path) ---"; \
282+
$$PRED reduce $(CLI_DEMO_DIR)/mis.json --to QUBO -o $(CLI_DEMO_DIR)/bundle_qubo.json; \
283+
\
284+
echo ""; \
285+
echo "--- 14. solve bundle: brute-force on reduced QUBO ---"; \
286+
$$PRED solve $(CLI_DEMO_DIR)/bundle_qubo.json --solver brute-force; \
287+
\
288+
echo ""; \
289+
echo "--- 15. reduce --via: use explicit path file ---"; \
290+
$$PRED reduce $(CLI_DEMO_DIR)/mis.json --via $(CLI_DEMO_DIR)/path_mis_qubo.json -o $(CLI_DEMO_DIR)/bundle_via.json; \
291+
\
292+
echo ""; \
293+
echo "--- 16. solve bundle with ILP: MIS → MVC → ILP ---"; \
294+
$$PRED reduce $(CLI_DEMO_DIR)/mis.json --to MVC -o $(CLI_DEMO_DIR)/bundle_mvc.json; \
295+
$$PRED solve $(CLI_DEMO_DIR)/bundle_mvc.json --solver ilp; \
296+
\
297+
echo ""; \
298+
echo "--- 17. solve: other problem types ---"; \
299+
$$PRED solve $(CLI_DEMO_DIR)/sat.json --solver brute-force; \
300+
$$PRED solve $(CLI_DEMO_DIR)/kcol.json --solver brute-force; \
301+
$$PRED solve $(CLI_DEMO_DIR)/maxcut.json --solver brute-force; \
302+
$$PRED solve $(CLI_DEMO_DIR)/mvc.json; \
303+
\
304+
echo ""; \
305+
echo "--- 18. closed-loop: create → reduce → solve → verify ---"; \
306+
echo "Creating a 6-vertex graph..."; \
307+
$$PRED create MIS --edges 0-1,1-2,2-3,3-4,4-5,0-5,1-4 -o $(CLI_DEMO_DIR)/big.json; \
308+
echo "Solving with ILP..."; \
309+
$$PRED solve $(CLI_DEMO_DIR)/big.json -o $(CLI_DEMO_DIR)/big_sol.json; \
310+
echo "Reducing to QUBO and solving with brute-force..."; \
311+
$$PRED reduce $(CLI_DEMO_DIR)/big.json --to QUBO -o $(CLI_DEMO_DIR)/big_qubo.json; \
312+
$$PRED solve $(CLI_DEMO_DIR)/big_qubo.json --solver brute-force -o $(CLI_DEMO_DIR)/big_qubo_sol.json; \
313+
echo "Verifying both solutions have the same evaluation..."; \
314+
ILP_EVAL=$$(jq -r '.evaluation' $(CLI_DEMO_DIR)/big_sol.json); \
315+
BF_EVAL=$$(jq -r '.evaluation' $(CLI_DEMO_DIR)/big_qubo_sol.json); \
316+
echo " ILP solution evaluation: $$ILP_EVAL"; \
317+
echo " Brute-force (via QUBO) evaluation: $$BF_EVAL"; \
318+
if [ "$$ILP_EVAL" = "$$BF_EVAL" ]; then \
319+
echo " ✅ Solutions agree!"; \
320+
else \
321+
echo " ❌ Solutions disagree!" && exit 1; \
322+
fi; \
323+
\
324+
echo ""; \
325+
echo "--- 19. show with alias and variant slash syntax ---"; \
326+
$$PRED show MIS/UnitDiskGraph; \
327+
\
328+
echo ""; \
329+
echo "--- 20. completions: generate shell completions ---"; \
330+
$$PRED completions bash > /dev/null && echo "bash completions: OK"; \
331+
$$PRED completions zsh > /dev/null && echo "zsh completions: OK"; \
332+
$$PRED completions fish > /dev/null && echo "fish completions: OK"; \
333+
\
334+
echo ""; \
335+
echo "=== Demo complete: $$(ls $(CLI_DEMO_DIR)/*.json | wc -l | tr -d ' ') JSON files in $(CLI_DEMO_DIR) ==="
336+
@echo "=== All 20 steps passed ✅ ==="

README.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,32 @@ Download [PDF manual](https://codingthrust.github.io/problem-reductions/reductio
1515

1616
## Installation
1717

18+
### As a library
19+
1820
Add to your `Cargo.toml`:
1921

2022
```toml
2123
[dependencies]
2224
problemreductions = "0.2"
2325
```
2426

25-
See the [Getting Started](https://codingthrust.github.io/problem-reductions/getting-started.html) guide for usage examples and the reduction workflow.
27+
### CLI tool
28+
29+
Install the `pred` command-line tool for exploring the reduction graph from your terminal:
30+
31+
```bash
32+
cargo install --git https://github.com/CodingThrust/problem-reductions problemreductions-cli
33+
```
34+
35+
Or build from source:
36+
37+
```bash
38+
git clone https://github.com/CodingThrust/problem-reductions
39+
cd problem-reductions
40+
make cli # builds target/release/pred
41+
```
42+
43+
See the [Getting Started](https://codingthrust.github.io/problem-reductions/getting-started.html) guide for usage examples, the reduction workflow, and [CLI usage](https://codingthrust.github.io/problem-reductions/cli.html).
2644

2745
## Contributing
2846

codecov.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ coverage:
1717
threshold: 2%
1818

1919
# Exclude proc-macro crate from coverage since it runs at compile time
20-
# and traditional runtime coverage tools cannot measure it
20+
# and traditional runtime coverage tools cannot measure it.
21+
# Exclude CLI crate from patch coverage: it is a thin dispatch layer
22+
# with many boilerplate type-dispatch match arms that are tested
23+
# end-to-end via integration tests, not amenable to 95% line coverage.
2124
ignore:
2225
- "problemreductions-macros/**/*"
26+
- "problemreductions-cli/**/*"

0 commit comments

Comments
 (0)