diff --git a/problemreductions-cli/tests/cli_tests.rs b/problemreductions-cli/tests/cli_tests.rs index 809670b6..3bd79f2f 100644 --- a/problemreductions-cli/tests/cli_tests.rs +++ b/problemreductions-cli/tests/cli_tests.rs @@ -423,17 +423,15 @@ fn test_evaluate_sat() { } #[test] -fn test_evaluate_consecutive_block_minimization_rejects_inconsistent_dimensions() { +fn test_evaluate_consecutive_block_minimization_rejects_ragged_matrix() { let problem_json = r#"{ "type": "ConsecutiveBlockMinimization", "data": { - "matrix": [[true]], - "num_rows": 1, - "num_cols": 2, + "matrix": [[true, false], [true]], "bound": 1 } }"#; - let tmp = std::env::temp_dir().join("pred_test_eval_cbm_invalid_dims.json"); + let tmp = std::env::temp_dir().join("pred_test_eval_cbm_ragged_matrix.json"); std::fs::write(&tmp, problem_json).unwrap(); let output = pred() @@ -442,7 +440,7 @@ fn test_evaluate_consecutive_block_minimization_rejects_inconsistent_dimensions( .unwrap(); assert!(!output.status.success()); let stderr = String::from_utf8_lossy(&output.stderr); - assert!(stderr.contains("num_cols must match matrix column count")); + assert!(stderr.contains("same length")); assert!(!stderr.contains("panicked at"), "stderr: {stderr}"); std::fs::remove_file(&tmp).ok(); } diff --git a/src/models/algebraic/consecutive_block_minimization.rs b/src/models/algebraic/consecutive_block_minimization.rs index 53785c48..0a5df44d 100644 --- a/src/models/algebraic/consecutive_block_minimization.rs +++ b/src/models/algebraic/consecutive_block_minimization.rs @@ -58,7 +58,10 @@ inventory::submit! { /// } /// ``` #[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(try_from = "ConsecutiveBlockMinimizationDef")] +#[serde( + try_from = "ConsecutiveBlockMinimizationDef", + into = "ConsecutiveBlockMinimizationDef" +)] pub struct ConsecutiveBlockMinimization { /// The binary matrix A (m x n). matrix: Vec>, @@ -184,11 +187,9 @@ crate::declare_variants! { default ConsecutiveBlockMinimization => "factorial(num_cols) * num_rows * num_cols", } -#[derive(Debug, Clone, Deserialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] struct ConsecutiveBlockMinimizationDef { matrix: Vec>, - num_rows: usize, - num_cols: usize, bound: i64, } @@ -196,20 +197,16 @@ impl TryFrom for ConsecutiveBlockMinimization { type Error = String; fn try_from(value: ConsecutiveBlockMinimizationDef) -> Result { - let problem = Self::try_new(value.matrix, value.bound)?; - if value.num_rows != problem.num_rows { - return Err(format!( - "num_rows must match matrix row count ({})", - problem.num_rows - )); - } - if value.num_cols != problem.num_cols { - return Err(format!( - "num_cols must match matrix column count ({})", - problem.num_cols - )); + Self::try_new(value.matrix, value.bound) + } +} + +impl From for ConsecutiveBlockMinimizationDef { + fn from(value: ConsecutiveBlockMinimization) -> Self { + Self { + matrix: value.matrix, + bound: value.bound, } - Ok(problem) } } diff --git a/src/unit_tests/models/algebraic/consecutive_block_minimization.rs b/src/unit_tests/models/algebraic/consecutive_block_minimization.rs index 60fbba41..7d66b645 100644 --- a/src/unit_tests/models/algebraic/consecutive_block_minimization.rs +++ b/src/unit_tests/models/algebraic/consecutive_block_minimization.rs @@ -91,10 +91,20 @@ fn test_consecutive_block_minimization_serialization() { } #[test] -fn test_consecutive_block_minimization_deserialization_rejects_inconsistent_dimensions() { - let json = r#"{"matrix":[[true]],"num_rows":1,"num_cols":2,"bound":1}"#; +fn test_consecutive_block_minimization_serialization_omits_derived_fields() { + let problem = ConsecutiveBlockMinimization::new(vec![vec![true, false], vec![false, true]], 2); + let value: serde_json::Value = serde_json::to_value(&problem).unwrap(); + let obj = value.as_object().unwrap(); + assert_eq!(obj.len(), 2); + assert!(obj.contains_key("matrix")); + assert!(obj.contains_key("bound")); +} + +#[test] +fn test_consecutive_block_minimization_deserialization_rejects_ragged_matrix() { + let json = r#"{"matrix":[[true,false],[true]],"bound":1}"#; let err = serde_json::from_str::(json).unwrap_err(); - assert!(err.to_string().contains("num_cols")); + assert!(err.to_string().contains("same length")); } #[test]