Skip to content

Commit e89f539

Browse files
GiggleLiuclaude
andcommitted
Fix CBM example in README; align CBM wire format with schema
The README's `pred create CBM ... | pred solve` example was broken on two fronts: the bound flag is `--bound-k` (not `--bound`), and the schema-driven factory rejected the generated JSON because `ConsecutiveBlockMinimization`'s deserialization required `num_rows`/`num_cols` fields that aren't part of its declared schema (only `matrix` and `bound` are). Drop the derived dimensions from the wire format entirely via `serde(into = ConsecutiveBlockMinimizationDef)` so serialize and deserialize both use the minimal `{matrix, bound}` form that matches `ProblemSchemaEntry`. Replace the now-irrelevant inconsistent-dimensions test with one that pins the minimal wire format and one that exercises ragged-matrix rejection. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent cbfad84 commit e89f539

3 files changed

Lines changed: 28 additions & 21 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ Try it out:
3636
pred show CBM
3737

3838
# Create and solve a small CBM instance
39-
pred create CBM --matrix '[[true,false,true],[false,true,true]]' --bound 2 \
39+
pred create CBM --matrix '[[true,false,true],[false,true,true]]' --bound-k 2 \
4040
| pred solve - --solver brute-force
4141
```
4242

src/models/algebraic/consecutive_block_minimization.rs

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,10 @@ inventory::submit! {
5858
/// }
5959
/// ```
6060
#[derive(Debug, Clone, Serialize, Deserialize)]
61-
#[serde(try_from = "ConsecutiveBlockMinimizationDef")]
61+
#[serde(
62+
try_from = "ConsecutiveBlockMinimizationDef",
63+
into = "ConsecutiveBlockMinimizationDef"
64+
)]
6265
pub struct ConsecutiveBlockMinimization {
6366
/// The binary matrix A (m x n).
6467
matrix: Vec<Vec<bool>>,
@@ -184,32 +187,26 @@ crate::declare_variants! {
184187
default ConsecutiveBlockMinimization => "factorial(num_cols) * num_rows * num_cols",
185188
}
186189

187-
#[derive(Debug, Clone, Deserialize)]
190+
#[derive(Debug, Clone, Serialize, Deserialize)]
188191
struct ConsecutiveBlockMinimizationDef {
189192
matrix: Vec<Vec<bool>>,
190-
num_rows: usize,
191-
num_cols: usize,
192193
bound: i64,
193194
}
194195

195196
impl TryFrom<ConsecutiveBlockMinimizationDef> for ConsecutiveBlockMinimization {
196197
type Error = String;
197198

198199
fn try_from(value: ConsecutiveBlockMinimizationDef) -> Result<Self, Self::Error> {
199-
let problem = Self::try_new(value.matrix, value.bound)?;
200-
if value.num_rows != problem.num_rows {
201-
return Err(format!(
202-
"num_rows must match matrix row count ({})",
203-
problem.num_rows
204-
));
205-
}
206-
if value.num_cols != problem.num_cols {
207-
return Err(format!(
208-
"num_cols must match matrix column count ({})",
209-
problem.num_cols
210-
));
200+
Self::try_new(value.matrix, value.bound)
201+
}
202+
}
203+
204+
impl From<ConsecutiveBlockMinimization> for ConsecutiveBlockMinimizationDef {
205+
fn from(value: ConsecutiveBlockMinimization) -> Self {
206+
Self {
207+
matrix: value.matrix,
208+
bound: value.bound,
211209
}
212-
Ok(problem)
213210
}
214211
}
215212

src/unit_tests/models/algebraic/consecutive_block_minimization.rs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,20 @@ fn test_consecutive_block_minimization_serialization() {
9191
}
9292

9393
#[test]
94-
fn test_consecutive_block_minimization_deserialization_rejects_inconsistent_dimensions() {
95-
let json = r#"{"matrix":[[true]],"num_rows":1,"num_cols":2,"bound":1}"#;
94+
fn test_consecutive_block_minimization_serialization_omits_derived_fields() {
95+
let problem = ConsecutiveBlockMinimization::new(vec![vec![true, false], vec![false, true]], 2);
96+
let value: serde_json::Value = serde_json::to_value(&problem).unwrap();
97+
let obj = value.as_object().unwrap();
98+
assert_eq!(obj.len(), 2);
99+
assert!(obj.contains_key("matrix"));
100+
assert!(obj.contains_key("bound"));
101+
}
102+
103+
#[test]
104+
fn test_consecutive_block_minimization_deserialization_rejects_ragged_matrix() {
105+
let json = r#"{"matrix":[[true,false],[true]],"bound":1}"#;
96106
let err = serde_json::from_str::<ConsecutiveBlockMinimization>(json).unwrap_err();
97-
assert!(err.to_string().contains("num_cols"));
107+
assert!(err.to_string().contains("same length"));
98108
}
99109

100110
#[test]

0 commit comments

Comments
 (0)