Skip to content

Commit b1ace36

Browse files
committed
update
1 parent 05aa8dc commit b1ace36

19 files changed

Lines changed: 809 additions & 656 deletions

Makefile

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ help:
2626
@echo " compare - Generate and compare Rust mapping exports"
2727
@echo " examples - Generate example JSON for paper (from fixtures, fast)"
2828
@echo " regenerate-fixtures - Recompute example DB fixtures (BruteForce/ILP, slow)"
29-
@echo " regenerate-fixtures - Recompute example DB fixtures (BruteForce/ILP, slow)"
3029
@echo " export-schemas - Export problem schemas to JSON"
3130
@echo " qubo-testdata - Regenerate QUBO test data (requires uv)"
3231
@echo " jl-testdata - Regenerate Julia parity test data (requires julia)"
@@ -124,10 +123,6 @@ examples:
124123
regenerate-fixtures:
125124
cargo run --release --features "example-db" --example regenerate_fixtures
126125

127-
# Regenerate example DB fixtures from code (runs BruteForce/ILP — slow)
128-
regenerate-fixtures:
129-
cargo run --release --features "example-db" --example regenerate_fixtures
130-
131126
# Export problem schemas to JSON
132127
export-schemas:
133128
cargo run --example export_schemas

docs/paper/reductions.typ

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616

1717
// === Example JSON helpers ===
1818
// Load canonical example databases generated by `make examples`.
19-
#let rule-db = json("examples/generated/rules.json")
20-
#let model-db = json("examples/generated/models.json")
21-
22-
#let load-example(source, target) = {
23-
let matches = rule-db.rules.filter(r => r.source.problem == source and r.target.problem == target)
19+
#let example-db = json("examples/generated/examples.json")
20+
21+
#let load-example(source, target, source-variant: none, target-variant: none) = {
22+
let matches = example-db.rules.filter(r =>
23+
r.source.problem == source and
24+
r.target.problem == target and
25+
(source-variant == none or r.source.variant == source-variant) and
26+
(target-variant == none or r.target.variant == target-variant)
27+
)
2428
if matches.len() == 1 {
2529
matches.at(0)
2630
} else if matches.len() == 0 {
@@ -30,8 +34,11 @@
3034
}
3135
}
3236

33-
#let load-model-example(name) = {
34-
let matches = model-db.models.filter(m => m.problem == name)
37+
#let load-model-example(name, variant: none) = {
38+
let matches = example-db.models.filter(m =>
39+
m.problem == name and
40+
(variant == none or m.variant == variant)
41+
)
3542
if matches.len() == 1 {
3643
matches.at(0)
3744
} else if matches.len() == 0 {
@@ -275,6 +282,8 @@
275282
#let reduction-rule(
276283
source, target,
277284
example: false,
285+
example-source-variant: none,
286+
example-target-variant: none,
278287
example-caption: none,
279288
extra: none,
280289
theorem-body, proof-body,
@@ -301,7 +310,12 @@
301310
proof[#proof-body]
302311

303312
if example {
304-
let data = load-example(source, target)
313+
let data = load-example(
314+
source,
315+
target,
316+
source-variant: example-source-variant,
317+
target-variant: example-target-variant,
318+
)
305319
pad(left: 1.5em, reduction-example(data, caption: example-caption)[#extra])
306320
}
307321
}
@@ -376,8 +390,8 @@ The gray schema table shows the JSON field names used in the library's data stru
376390
In all graph problems below, $G = (V, E)$ denotes an undirected graph with $|V| = n$ vertices and $|E|$ edges.
377391

378392
#{
379-
// MIS has two entries in models.json; select the unit-weight variant
380-
let x = model-db.models.filter(m => m.problem == "MaximumIndependentSet" and m.variant.at("weight", default: "") == "One").at(0)
393+
// MIS has two entries in examples.json; select the unit-weight variant
394+
let x = load-model-example("MaximumIndependentSet", variant: (graph: "SimpleGraph", weight: "One"))
381395
let nv = graph-num-vertices(x.instance)
382396
let ne = graph-num-edges(x.instance)
383397
// Pick optimal[2] = {v1, v3, v5, v9} to match figure
@@ -2772,17 +2786,26 @@ The following table shows concrete variable overhead for example instances, gene
27722786
#let example-files = (
27732787
(source: "MaximumIndependentSet", target: "MinimumVertexCover"),
27742788
(source: "MinimumVertexCover", target: "MaximumIndependentSet"),
2775-
(source: "MaximumIndependentSet", target: "MaximumSetPacking"),
2789+
(
2790+
source: "MaximumIndependentSet",
2791+
target: "MaximumSetPacking",
2792+
source-variant: (graph: "SimpleGraph", weight: "One"),
2793+
target-variant: (weight: "One"),
2794+
),
27762795
(source: "MaximumMatching", target: "MaximumSetPacking"),
27772796
(source: "MinimumVertexCover", target: "MinimumSetCovering"),
27782797
(source: "MaxCut", target: "SpinGlass"),
27792798
(source: "SpinGlass", target: "MaxCut"),
27802799
(source: "SpinGlass", target: "QUBO"),
27812800
(source: "QUBO", target: "SpinGlass"),
2782-
(source: "MaximumIndependentSet", target: "QUBO"),
27832801
(source: "KColoring", target: "QUBO"),
27842802
(source: "MaximumSetPacking", target: "QUBO"),
2785-
(source: "KSatisfiability", target: "QUBO"),
2803+
(
2804+
source: "KSatisfiability",
2805+
target: "QUBO",
2806+
source-variant: (k: "K3"),
2807+
target-variant: (weight: "f64"),
2808+
),
27862809
(source: "ILP", target: "QUBO"),
27872810
(source: "Satisfiability", target: "MaximumIndependentSet"),
27882811
(source: "Satisfiability", target: "KColoring"),
@@ -2801,7 +2824,12 @@ The following table shows concrete variable overhead for example instances, gene
28012824
)
28022825

28032826
#let examples = example-files.map(entry => {
2804-
let d = load-example(entry.source, entry.target)
2827+
let d = load-example(
2828+
entry.source,
2829+
entry.target,
2830+
source-variant: entry.at("source-variant", default: none),
2831+
target-variant: entry.at("target-variant", default: none),
2832+
)
28052833
(name: example-name(entry.source, entry.target), data: d)
28062834
})
28072835

examples/export_examples.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
use problemreductions::example_db::{build_model_db, build_rule_db, default_generated_dir};
2-
use problemreductions::export::{write_model_db_to, write_rule_db_to};
1+
use problemreductions::example_db::{build_example_db, default_generated_dir};
2+
use problemreductions::export::write_example_db_to;
33
use std::fs;
44

55
fn main() {
@@ -9,15 +9,13 @@ fn main() {
99
}
1010
fs::create_dir_all(&output_dir).expect("Failed to create generated examples directory");
1111

12-
let rule_db = build_rule_db().expect("Failed to build canonical rule database");
13-
let model_db = build_model_db().expect("Failed to build canonical model database");
12+
let example_db = build_example_db().expect("Failed to build canonical example database");
1413

15-
write_rule_db_to(&output_dir, &rule_db);
16-
write_model_db_to(&output_dir, &model_db);
14+
write_example_db_to(&output_dir, &example_db);
1715

1816
println!(
1917
"Exported {} rule examples and {} model examples",
20-
rule_db.rules.len(),
21-
model_db.models.len()
18+
example_db.rules.len(),
19+
example_db.models.len()
2220
);
2321
}

examples/regenerate_fixtures.rs

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,31 @@
11
/// Regenerate example database fixture files from builder code.
22
///
33
/// This binary recomputes all model and rule examples using BruteForce/ILP
4-
/// and writes them to `src/example_db/fixtures/` as JSON Lines, one example per
5-
/// line. Run this in release mode after changing any model or rule to update
6-
/// the stored expected results:
4+
/// and writes them to `src/example_db/fixtures/` as wrapped JSON objects. Run
5+
/// this in release mode after changing any model or rule to update the stored
6+
/// expected results:
77
///
88
/// ```
99
/// cargo run --release --example regenerate_fixtures --features example-db
1010
/// ```
11-
use problemreductions::example_db::{compute_model_db, compute_rule_db};
12-
use problemreductions::export::{write_model_db_to, write_rule_db_to};
11+
use problemreductions::example_db::compute_example_db;
12+
use problemreductions::export::write_example_db_to;
1313
use std::fs;
1414
use std::path::Path;
1515

1616
fn main() {
1717
let fixtures_dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("src/example_db/fixtures");
1818
fs::create_dir_all(&fixtures_dir).expect("Failed to create fixtures directory");
1919

20-
let rule_db = compute_rule_db().expect("Failed to compute canonical rule database");
21-
let model_db = compute_model_db().expect("Failed to compute canonical model database");
20+
let example_db = compute_example_db().expect("Failed to compute canonical example database");
21+
let examples_path = fixtures_dir.join("examples.json");
2222

23-
let models_path = fixtures_dir.join("models.json");
24-
let rules_path = fixtures_dir.join("rules.json");
25-
26-
write_model_db_to(&fixtures_dir, &model_db);
27-
write_rule_db_to(&fixtures_dir, &rule_db);
23+
write_example_db_to(&fixtures_dir, &example_db);
2824

2925
println!(
3026
"Regenerated fixtures: {} rule examples, {} model examples",
31-
rule_db.rules.len(),
32-
model_db.models.len()
27+
example_db.rules.len(),
28+
example_db.models.len()
3329
);
34-
println!(" Models: {}", models_path.display());
35-
println!(" Rules: {}", rules_path.display());
30+
println!(" Examples: {}", examples_path.display());
3631
}

0 commit comments

Comments
 (0)