Skip to content

Commit 2228c61

Browse files
GiggleLiuclaudeisPANN
authored
Fix #420: Add ConsecutiveBlockMinimization model (#668)
* Add plan for #420: ConsecutiveBlockMinimization model * Implement #420: Add ConsecutiveBlockMinimization model Add the Consecutive Block Minimization satisfaction problem (Garey & Johnson SR17) to the algebraic/ category. Given an m×n binary matrix and bound K, decide whether a column permutation exists yielding at most K maximal blocks of consecutive 1's across all rows. - Model with SatisfactionProblem trait, dims=[n;n] permutation space - CLI create with --matrix (JSON) and --bound-k flags - Unit tests: creation, evaluation, count_blocks, brute_force, serialization, invalid permutation, empty matrix - Paper entry with citations (Kou 1977, Booth 1975, Haddadi 2008) - Example DB fixture with 2×3 matrix instance Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * chore: remove plan file after implementation * fix: validate empty CBM permutations * fix: harden CBM CLI and deserialization * docs: surface CBM CLI usage * Fix canonical_model_example_specs for new ModelExampleSpec API The ModelExampleSpec struct changed on main (build closure -> instance/optimal_config/optimal_value fields). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Run cargo fmt after merge with main Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Use issue #420 Instance 2 (P_6 adjacency matrix) as canonical example Update canonical_model_example_specs to use the 6x6 path graph adjacency matrix with K=6 from the issue. Fix paper to use new optimal_config field format. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Fix SchedulingWithIndividualDeadlines paper section for new example format Update from old x.samples.at(0).config to x.optimal_config to match the current ModelExampleSpec format. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Rename --bound-k CLI flag to --bound for ConsecutiveBlockMinimization Reuse the existing --bound flag instead of adding a separate --bound-k. Other models with bound_k fields (RectilinearPictureCompression, MinimumCardinalityKey, ConsecutiveOnesSubmatrix) already map to --k. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Use i64 for bound_k to match CLI --bound type directly Avoids type conversion between CLI i64 and model usize. Negative bounds correctly mean no permutation can satisfy. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Remove contradictory --bound assertion in CLI test After renaming --bound-k to --bound, the negative assertion became contradictory with the positive one. Remove since --bound-k no longer exists. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * Rename bound_k to bound (i64) across all models Unify the field name and type for CBM, MinimumCardinalityKey, ConsecutiveOnesSubmatrix, and RectilinearPictureCompression. All now use `bound: i64` matching the CLI --bound flag directly. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: Xiwei Pan <xiwei.pan@connect.hkust-gz.edu.cn>
1 parent aa5e687 commit 2228c61

20 files changed

Lines changed: 619 additions & 95 deletions

README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,17 @@ make cli # builds target/release/pred
4242

4343
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).
4444

45+
Try a model directly from the CLI:
46+
47+
```bash
48+
# Show the Consecutive Block Minimization model (alias: CBM)
49+
pred show CBM
50+
51+
# Create and solve a small CBM instance (currently with brute-force)
52+
pred create CBM --matrix '[[true,false,true],[false,true,true]]' --bound 2 \
53+
| pred solve - --solver brute-force
54+
```
55+
4556
## MCP Server (AI Integration)
4657

4758
The `pred` CLI includes a built-in [MCP](https://modelcontextprotocol.io/) server for AI assistant integration (Claude Code, Cursor, Windsurf, OpenCode, etc.).

docs/paper/reductions.typ

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,13 @@
136136
"SchedulingWithIndividualDeadlines": [Scheduling With Individual Deadlines],
137137
"StaffScheduling": [Staff Scheduling],
138138
"MinimumTardinessSequencing": [Minimum Tardiness Sequencing],
139+
"ConsecutiveBlockMinimization": [Consecutive Block Minimization],
139140
"ConsecutiveOnesSubmatrix": [Consecutive Ones Submatrix],
140141
"SequencingToMinimizeMaximumCumulativeCost": [Sequencing to Minimize Maximum Cumulative Cost],
141142
"SequencingToMinimizeWeightedTardiness": [Sequencing to Minimize Weighted Tardiness],
143+
"SequencingWithinIntervals": [Sequencing Within Intervals],
142144
"SumOfSquaresPartition": [Sum of Squares Partition],
143145
"TwoDimensionalConsecutiveSets": [2-Dimensional Consecutive Sets],
144-
"SequencingWithinIntervals": [Sequencing Within Intervals],
145146
"DirectedTwoCommodityIntegralFlow": [Directed Two-Commodity Integral Flow],
146147
"ConjunctiveBooleanQuery": [Conjunctive Boolean Query],
147148
"RectilinearPictureCompression": [Rectilinear Picture Compression],
@@ -1891,7 +1892,7 @@ A classical NP-complete problem from Garey and Johnson @garey1979[Ch.~3, p.~76],
18911892
let n = x.instance.num_attributes
18921893
let deps = x.instance.dependencies
18931894
let m = deps.len()
1894-
let bound = x.instance.bound_k
1895+
let bound = x.instance.bound
18951896
let key-attrs = range(n).filter(i => x.optimal_config.at(i) == 1)
18961897
let fmt-set(s) = "${" + s.map(e => str(e)).join(", ") + "}$"
18971898
let fmt-fd(d) = fmt-set(d.at(0)) + " $arrow.r$ " + fmt-set(d.at(1))
@@ -2484,6 +2485,39 @@ A classical NP-complete problem from Garey and Johnson @garey1979[Ch.~3, p.~76],
24842485
]
24852486
}
24862487

2488+
#{
2489+
let x = load-model-example("ConsecutiveBlockMinimization")
2490+
let mat = x.instance.matrix
2491+
let K = x.instance.bound
2492+
let n-rows = mat.len()
2493+
let n-cols = if n-rows > 0 { mat.at(0).len() } else { 0 }
2494+
let perm = x.optimal_config
2495+
// Count blocks under the satisfying permutation
2496+
let total-blocks = 0
2497+
for row in mat {
2498+
let in-block = false
2499+
for p in perm {
2500+
if row.at(p) {
2501+
if not in-block {
2502+
total-blocks += 1
2503+
in-block = true
2504+
}
2505+
} else {
2506+
in-block = false
2507+
}
2508+
}
2509+
}
2510+
[
2511+
#problem-def("ConsecutiveBlockMinimization")[
2512+
Given an $m times n$ binary matrix $A$ and a positive integer $K$, determine whether there exists a permutation of the columns of $A$ such that the resulting matrix has at most $K$ maximal blocks of consecutive 1-entries (summed over all rows). A _block_ is a maximal contiguous run of 1-entries within a single row.
2513+
][
2514+
Consecutive Block Minimization (SR17 in Garey & Johnson) arises in consecutive file organization for information retrieval systems, where records stored on a linear medium must be arranged so that each query's relevant records form a contiguous segment. Applications also include scheduling, production planning, the glass cutting industry, and data compression. NP-complete by reduction from Hamiltonian Path @kou1977. When $K$ equals the number of non-all-zero rows, the problem reduces to testing the _consecutive ones property_, solvable in polynomial time via PQ-trees @booth1975. A 1.5-approximation is known @haddadi2008. The best known exact algorithm runs in $O^*(n!)$ by brute-force enumeration of all column permutations.
2515+
2516+
*Example.* Let $A$ be the #n-rows$times$#n-cols matrix with rows #mat.enumerate().map(((i, row)) => [$r_#i = (#row.map(v => if v {$1$} else {$0$}).join($,$))$]).join(", ") and $K = #K$. The column permutation $pi = (#perm.map(p => str(p)).join(", "))$ yields #total-blocks total blocks, so #total-blocks $<= #K$ and the answer is YES.
2517+
]
2518+
]
2519+
}
2520+
24872521
#{
24882522
let x = load-model-example("PaintShop")
24892523
let n-cars = x.instance.num_cars
@@ -2765,7 +2799,7 @@ A classical NP-complete problem from Garey and Johnson @garey1979[Ch.~3, p.~76],
27652799
let mat = x.instance.matrix
27662800
let m = mat.len()
27672801
let n = mat.at(0).len()
2768-
let K = x.instance.bound_k
2802+
let K = x.instance.bound
27692803
// Convert bool matrix to int for display
27702804
let M = mat.map(row => row.map(v => if v { 1 } else { 0 }))
27712805
[
@@ -3462,8 +3496,7 @@ A classical NP-complete problem from Garey and Johnson @garey1979[Ch.~3, p.~76],
34623496
let nproc = x.instance.num_processors
34633497
let deadlines = x.instance.deadlines
34643498
let precs = x.instance.precedences
3465-
let sample = x.samples.at(0)
3466-
let start = sample.config
3499+
let start = x.optimal_config
34673500
let horizon = deadlines.fold(0, (acc, d) => if d > acc { d } else { acc })
34683501
let slot-groups = range(horizon).map(slot => range(ntasks).filter(t => start.at(t) == slot))
34693502
let tight-tasks = range(ntasks).filter(t => start.at(t) + 1 == deadlines.at(t))
@@ -3973,7 +4006,7 @@ A classical NP-complete problem from Garey and Johnson @garey1979[Ch.~3, p.~76],
39734006
let A = x.instance.matrix
39744007
let m = A.len()
39754008
let n = A.at(0).len()
3976-
let K = x.instance.bound_k
4009+
let K = x.instance.bound
39774010
// Convert bool matrix to int for display
39784011
let A-int = A.map(row => row.map(v => if v { 1 } else { 0 }))
39794012
// Use the canonical witness {0, 1, 3}

docs/paper/references.bib

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1034,6 +1034,17 @@ @article{kou1977
10341034
doi = {10.1137/0206005}
10351035
}
10361036

1037+
@article{haddadi2008,
1038+
author = {Salim Haddadi and Zohra Layouni},
1039+
title = {Consecutive block minimization is 1.5-approximable},
1040+
journal = {Information Processing Letters},
1041+
volume = {108},
1042+
number = {3},
1043+
pages = {161--163},
1044+
year = {2008},
1045+
doi = {10.1016/j.ipl.2008.05.003}
1046+
}
1047+
10371048
@article{lawler1972,
10381049
author = {Eugene L. Lawler},
10391050
title = {A Procedure for Computing the $K$ Best Solutions to Discrete Optimization Problems and Its Application to the Shortest Path Problem},

docs/src/cli.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@ pred create SteinerTree --graph 0-1,0-3,1-2,1-3,2-3,2-4,3-4 --edge-weights 2,5,2
5858
# Create a Length-Bounded Disjoint Paths instance
5959
pred create LengthBoundedDisjointPaths --graph 0-1,1-6,0-2,2-3,3-6,0-4,4-5,5-6 --source 0 --sink 6 --num-paths-required 2 --bound 3 -o lbdp.json
6060

61+
# Create a Consecutive Block Minimization instance (alias: CBM)
62+
pred create CBM --matrix '[[true,false,true],[false,true,true]]' --bound 2 -o cbm.json
63+
64+
# CBM currently needs the brute-force solver
65+
pred solve cbm.json --solver brute-force
66+
6167
# Or start from a canonical model example
6268
pred create --example MIS/SimpleGraph/i32 -o example.json
6369

@@ -342,6 +348,7 @@ pred create MIS --graph 0-1,1-2,2-3 -o problem.json
342348
pred create MIS --graph 0-1,1-2,2-3 --weights 2,1,3,1 -o problem.json
343349
pred create SAT --num-vars 3 --clauses "1,2;-1,3" -o sat.json
344350
pred create QUBO --matrix "1,0.5;0.5,2" -o qubo.json
351+
pred create CBM --matrix '[[true,false,true],[false,true,true]]' --bound 2 -o cbm.json
345352
pred create KColoring --k 3 --graph 0-1,1-2,2-0 -o kcol.json
346353
pred create KthBestSpanningTree --graph 0-1,0-2,1-2 --edge-weights 2,3,1 --k 1 --bound 3 -o kth.json
347354
pred create SpinGlass --graph 0-1,1-2 -o sg.json
@@ -366,6 +373,10 @@ pred create StrongConnectivityAugmentation --arcs "0>1,1>2,2>0,3>4,4>3,2>3,4>5,5
366373
For `LengthBoundedDisjointPaths`, the CLI flag `--bound` maps to the JSON field
367374
`max_length`.
368375
376+
For `ConsecutiveBlockMinimization`, the `--matrix` flag expects a JSON 2D bool array such as
377+
`'[[true,false,true],[false,true,true]]'`. The example above shows the accepted shape, and solving
378+
CBM instances currently requires `--solver brute-force`.
379+
369380
For problem-specific create help, run `pred create <PROBLEM>` with no additional flags.
370381
The generic `pred create --help` output lists all flags across all problem types.
371382

problemreductions-cli/src/cli.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ Flags by problem type:
250250
BalancedCompleteBipartiteSubgraph --left, --right, --biedges, --k
251251
BiconnectivityAugmentation --graph, --potential-edges, --budget [--num-vertices]
252252
BMF --matrix (0/1), --rank
253+
ConsecutiveBlockMinimization --matrix (JSON 2D bool), --bound-k
253254
ConsecutiveOnesSubmatrix --matrix (0/1), --k
254255
SteinerTree --graph, --edge-weights, --terminals
255256
MultipleCopyFileAllocation --graph, --usage, --storage, --bound
@@ -357,7 +358,8 @@ pub struct CreateArgs {
357358
/// Number of variables (for SAT/KSAT)
358359
#[arg(long)]
359360
pub num_vars: Option<usize>,
360-
/// Matrix input (semicolon-separated rows; use `pred create <PROBLEM>` for problem-specific formats)
361+
/// Matrix input. QUBO uses semicolon-separated numeric rows ("1,0.5;0.5,2");
362+
/// ConsecutiveBlockMinimization uses a JSON 2D bool array ('[[true,false],[false,true]]')
361363
#[arg(long)]
362364
pub matrix: Option<String>,
363365
/// Shared integer parameter (use `pred create <PROBLEM>` for the problem-specific meaning)
@@ -552,6 +554,7 @@ pub struct CreateArgs {
552554
/// Alphabet size for LCS, SCS, StringToStringCorrection, or TwoDimensionalConsecutiveSets (optional; inferred from the input strings if omitted)
553555
#[arg(long)]
554556
pub alphabet_size: Option<usize>,
557+
555558
/// Number of attributes for AdditionalKey or MinimumCardinalityKey
556559
#[arg(long)]
557560
pub num_attributes: Option<usize>,

problemreductions-cli/src/commands/create.rs

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,9 @@ use crate::problem_name::{
77
use crate::util;
88
use anyhow::{bail, Context, Result};
99
use problemreductions::export::{ModelExample, ProblemRef, ProblemSide, RuleExample};
10-
use problemreductions::models::algebraic::{ClosestVectorProblem, ConsecutiveOnesSubmatrix, BMF};
10+
use problemreductions::models::algebraic::{
11+
ClosestVectorProblem, ConsecutiveBlockMinimization, ConsecutiveOnesSubmatrix, BMF,
12+
};
1113
use problemreductions::models::graph::{
1214
GeneralizedHex, GraphPartitioning, HamiltonianCircuit, HamiltonianPath,
1315
LengthBoundedDisjointPaths, MinimumCutIntoBoundedSets, MinimumMultiwayCut,
@@ -342,7 +344,7 @@ fn type_format_hint(type_name: &str, graph_type: Option<&str>) -> &'static str {
342344
}
343345
"Vec<Vec<usize>>" => "semicolon-separated sets: \"0,1;1,2;0,2\"",
344346
"Vec<CNFClause>" => "semicolon-separated clauses: \"1,2;-1,3\"",
345-
"Vec<Vec<bool>>" => "semicolon-separated binary rows: \"1,1,0;0,1,1\"",
347+
"Vec<Vec<bool>>" => "JSON 2D bool array: '[[true,false],[false,true]]'",
346348
"Vec<Vec<W>>" => "semicolon-separated rows: \"1,0.5;0.5,2\"",
347349
"usize" | "W::Sum" => "integer",
348350
"u64" => "integer",
@@ -431,7 +433,7 @@ fn example_for(canonical: &str, graph_type: Option<&str>) -> &'static str {
431433
"AdditionalKey" => "--num-attributes 6 --dependencies \"0,1:2,3;2,3:4,5;4,5:0,1\" --relation-attrs 0,1,2,3,4,5 --known-keys \"0,1;2,3;4,5\"",
432434
"SubgraphIsomorphism" => "--graph 0-1,1-2,2-0 --pattern 0-1",
433435
"RectilinearPictureCompression" => {
434-
"--matrix \"1,1,0,0;1,1,0,0;0,0,1,1;0,0,1,1\" --k 2"
436+
"--matrix \"1,1,0,0;1,1,0,0;0,0,1,1;0,0,1,1\" --bound 2"
435437
}
436438
"SequencingToMinimizeWeightedTardiness" => {
437439
"--sizes 3,4,2,5,3 --weights 2,3,1,4,2 --deadlines 5,8,4,15,10 --bound 13"
@@ -449,7 +451,7 @@ fn example_for(canonical: &str, graph_type: Option<&str>) -> &'static str {
449451
"--strings \"010110;100101;001011\" --bound 3 --alphabet-size 2"
450452
}
451453
"MinimumCardinalityKey" => {
452-
"--num-attributes 6 --dependencies \"0,1>2;0,2>3;1,3>4;2,4>5\" --k 2"
454+
"--num-attributes 6 --dependencies \"0,1>2;0,2>3;1,3>4;2,4>5\" --bound 2"
453455
}
454456
"PrimeAttributeName" => {
455457
"--universe 6 --deps \"0,1>2,3,4,5;2,3>0,1,4,5\" --query 3"
@@ -458,13 +460,16 @@ fn example_for(canonical: &str, graph_type: Option<&str>) -> &'static str {
458460
"--alphabet-size 6 --sets \"0,1,2;3,4,5;1,3;2,4;0,5\""
459461
}
460462
"ShortestCommonSupersequence" => "--strings \"0,1,2;1,2,0\" --bound 4",
461-
"SequencingToMinimizeMaximumCumulativeCost" => {
462-
"--costs 2,-1,3,-2,1,-3 --precedence-pairs \"0>2,1>2,1>3,2>4,3>5,4>5\" --bound 4"
463+
"ConsecutiveBlockMinimization" => {
464+
"--matrix '[[true,false,true],[false,true,true]]' --bound 2"
463465
}
464-
"ConjunctiveQueryFoldability" => "(use --example ConjunctiveQueryFoldability)",
465466
"ConjunctiveBooleanQuery" => {
466467
"--domain-size 6 --relations \"2:0,3|1,3|2,4;3:0,1,5|1,2,5\" --conjuncts-spec \"0:v0,c3;0:v1,c3;1:v0,v1,c5\""
467468
}
469+
"ConjunctiveQueryFoldability" => "(use --example ConjunctiveQueryFoldability)",
470+
"SequencingToMinimizeMaximumCumulativeCost" => {
471+
"--costs 2,-1,3,-2,1,-3 --precedence-pairs \"0>2,1>2,1>3,2>4,3>5,4>5\" --bound 4"
472+
}
468473
"StringToStringCorrection" => {
469474
"--source-string \"0,1,2,3,1,0\" --target-string \"0,1,3,2,1\" --bound 2"
470475
}
@@ -489,12 +494,11 @@ fn help_flag_name(canonical: &str, field_name: &str) -> String {
489494
return "num-processors/--m".to_string();
490495
}
491496
("LengthBoundedDisjointPaths", "max_length") => return "bound".to_string(),
492-
("RectilinearPictureCompression", "bound_k") => return "k".to_string(),
497+
("RectilinearPictureCompression", "bound") => return "bound".to_string(),
493498
("PrimeAttributeName", "num_attributes") => return "universe".to_string(),
494499
("PrimeAttributeName", "dependencies") => return "deps".to_string(),
495500
("PrimeAttributeName", "query_attribute") => return "query".to_string(),
496-
("MinimumCardinalityKey", "bound_k") => return "k".to_string(),
497-
("ConsecutiveOnesSubmatrix", "bound_k") => return "k".to_string(),
501+
("ConsecutiveOnesSubmatrix", "bound") => return "bound".to_string(),
498502
("StaffScheduling", "shifts_per_schedule") => return "k".to_string(),
499503
_ => {}
500504
}
@@ -1774,12 +1778,12 @@ pub fn create(args: &CreateArgs, out: &OutputConfig) -> Result<()> {
17741778
"MinimumCardinalityKey" => {
17751779
let num_attributes = args.num_attributes.ok_or_else(|| {
17761780
anyhow::anyhow!(
1777-
"MinimumCardinalityKey requires --num-attributes, --dependencies, and --k\n\n\
1778-
Usage: pred create MinimumCardinalityKey --num-attributes 6 --dependencies \"0,1>2;0,2>3;1,3>4;2,4>5\" --k 2"
1781+
"MinimumCardinalityKey requires --num-attributes, --dependencies, and --bound\n\n\
1782+
Usage: pred create MinimumCardinalityKey --num-attributes 6 --dependencies \"0,1>2;0,2>3;1,3>4;2,4>5\" --bound 2"
17791783
)
17801784
})?;
1781-
let k = args.k.ok_or_else(|| {
1782-
anyhow::anyhow!("MinimumCardinalityKey requires --k (bound on key cardinality)")
1785+
let k = args.bound.ok_or_else(|| {
1786+
anyhow::anyhow!("MinimumCardinalityKey requires --bound (bound on key cardinality)")
17831787
})?;
17841788
let deps_str = args.dependencies.as_deref().ok_or_else(|| {
17851789
anyhow::anyhow!(
@@ -1853,32 +1857,55 @@ pub fn create(args: &CreateArgs, out: &OutputConfig) -> Result<()> {
18531857
(ser(BMF::new(matrix, rank))?, resolved_variant.clone())
18541858
}
18551859

1860+
// ConsecutiveBlockMinimization
1861+
"ConsecutiveBlockMinimization" => {
1862+
let usage = "Usage: pred create ConsecutiveBlockMinimization --matrix '[[true,false,true],[false,true,true]]' --bound 2";
1863+
let matrix_str = args.matrix.as_deref().ok_or_else(|| {
1864+
anyhow::anyhow!(
1865+
"ConsecutiveBlockMinimization requires --matrix as a JSON 2D bool array and --bound\n\n{usage}"
1866+
)
1867+
})?;
1868+
let bound = args.bound.ok_or_else(|| {
1869+
anyhow::anyhow!("ConsecutiveBlockMinimization requires --bound\n\n{usage}")
1870+
})?;
1871+
let matrix: Vec<Vec<bool>> = serde_json::from_str(matrix_str).map_err(|err| {
1872+
anyhow::anyhow!(
1873+
"ConsecutiveBlockMinimization requires --matrix as a JSON 2D bool array (e.g., '[[true,false,true],[false,true,true]]')\n\n{usage}\n\nFailed to parse --matrix: {err}"
1874+
)
1875+
})?;
1876+
(
1877+
ser(ConsecutiveBlockMinimization::try_new(matrix, bound)
1878+
.map_err(|err| anyhow::anyhow!("{err}\n\n{usage}"))?)?,
1879+
resolved_variant.clone(),
1880+
)
1881+
}
1882+
18561883
// RectilinearPictureCompression
18571884
"RectilinearPictureCompression" => {
18581885
let matrix = parse_bool_matrix(args)?;
1859-
let k = args.k.ok_or_else(|| {
1886+
let bound = args.bound.ok_or_else(|| {
18601887
anyhow::anyhow!(
1861-
"RectilinearPictureCompression requires --matrix and --k\n\n\
1862-
Usage: pred create RectilinearPictureCompression --matrix \"1,1,0,0;1,1,0,0;0,0,1,1;0,0,1,1\" --k 2"
1888+
"RectilinearPictureCompression requires --matrix and --bound\n\n\
1889+
Usage: pred create RectilinearPictureCompression --matrix \"1,1,0,0;1,1,0,0;0,0,1,1;0,0,1,1\" --bound 2"
18631890
)
18641891
})?;
18651892
(
1866-
ser(RectilinearPictureCompression::new(matrix, k))?,
1893+
ser(RectilinearPictureCompression::new(matrix, bound))?,
18671894
resolved_variant.clone(),
18681895
)
18691896
}
18701897

18711898
// ConsecutiveOnesSubmatrix
18721899
"ConsecutiveOnesSubmatrix" => {
18731900
let matrix = parse_bool_matrix(args)?;
1874-
let k = args.k.ok_or_else(|| {
1901+
let bound = args.bound.ok_or_else(|| {
18751902
anyhow::anyhow!(
1876-
"ConsecutiveOnesSubmatrix requires --matrix and --k\n\n\
1877-
Usage: pred create ConsecutiveOnesSubmatrix --matrix \"1,1,0,1;1,0,1,1;0,1,1,0\" --k 3"
1903+
"ConsecutiveOnesSubmatrix requires --matrix and --bound\n\n\
1904+
Usage: pred create ConsecutiveOnesSubmatrix --matrix \"1,1,0,1;1,0,1,1;0,1,1,0\" --bound 3"
18781905
)
18791906
})?;
18801907
(
1881-
ser(ConsecutiveOnesSubmatrix::new(matrix, k))?,
1908+
ser(ConsecutiveOnesSubmatrix::new(matrix, bound))?,
18821909
resolved_variant.clone(),
18831910
)
18841911
}

0 commit comments

Comments
 (0)