From 9b0a3b853eec313994c85b712b1b3ca118d2b689 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Heim?= Date: Mon, 22 Jun 2026 15:15:31 -0300 Subject: [PATCH 1/2] Add VAR_TYPE_* constants --- src/lib.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index ee94ce2..d45af89 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,3 +40,12 @@ pub const MATRIX_FORMAT_ROW_WISE: HighsInt = 2; pub const OBJECTIVE_SENSE_MINIMIZE: HighsInt = 1; pub const OBJECTIVE_SENSE_MAXIMIZE: HighsInt = -1; + +// Variable types, as used in the `integrality` array passed to `Highs_passMip` +// and in `Highs_changeColIntegrality`. These mirror the `kHighsVarType*` +// constants in HiGHS' C API. +pub const VAR_TYPE_CONTINUOUS: HighsInt = 0; +pub const VAR_TYPE_INTEGER: HighsInt = 1; +pub const VAR_TYPE_SEMI_CONTINUOUS: HighsInt = 2; +pub const VAR_TYPE_SEMI_INTEGER: HighsInt = 3; +pub const VAR_TYPE_IMPLICIT_INTEGER: HighsInt = 4; From bc48190f17acf37c3af28155f6895fd0f67b4ee8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Germ=C3=A1n=20Heim?= Date: Mon, 22 Jun 2026 16:02:20 -0300 Subject: [PATCH 2/2] Add semicont/semiint tests --- tests/test_highs_functions.rs | 99 +++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/tests/test_highs_functions.rs b/tests/test_highs_functions.rs index a324fa2..ecceb90 100644 --- a/tests/test_highs_functions.rs +++ b/tests/test_highs_functions.rs @@ -122,6 +122,105 @@ fn highs_functions() { } } +#[test] +fn semi_continuous_variable() { + // min x s.t. x >= 3, x semicontinuous in {0} U [5, 10]. + unsafe { + let highs = Highs_create(); + let opt = CString::new("output_flag").unwrap(); + Highs_setBoolOptionValue(highs, opt.as_ptr(), 0); + let inf = Highs_getInfinity(highs); + + assert_eq!( + STATUS_OK, + Highs_addCol(highs, 1.0, 5.0, 10.0, 0, std::ptr::null(), std::ptr::null()), + "addCol" + ); + // x >= 3 + let idx: &mut [HighsInt] = &mut [0]; + let val: &mut [f64] = &mut [1.0]; + assert_eq!( + STATUS_OK, + Highs_addRow(highs, 3.0, inf, 1, ptr(idx), ptr(val)), + "addRow" + ); + // x semicont + assert_eq!( + STATUS_OK, + Highs_changeColIntegrality(highs, 0, VAR_TYPE_SEMI_CONTINUOUS), + "changeColIntegrality" + ); + assert_eq!(Highs_run(highs), STATUS_OK, "run"); + assert_eq!(Highs_getModelStatus(highs), MODEL_STATUS_OPTIMAL, "status"); + + let colvalue: &mut [f64] = &mut [0.; 1]; + let coldual: &mut [f64] = &mut [0.; 1]; + let rowvalue: &mut [f64] = &mut [0.; 1]; + let rowdual: &mut [f64] = &mut [0.; 1]; + Highs_getSolution( + highs, + ptr(colvalue), + ptr(coldual), + ptr(rowvalue), + ptr(rowdual), + ); + assert!((colvalue[0] - 5.0).abs() < 1e-6, "x = {}", colvalue[0]); + + Highs_destroy(highs); + } +} + +#[test] +fn semi_integer_variable() { + // max x s.t. x <= 7.5, x semi-integer in {0} U {5, 6, ..., 10}. + unsafe { + let highs = Highs_create(); + let opt = CString::new("output_flag").unwrap(); + Highs_setBoolOptionValue(highs, opt.as_ptr(), 0); + let inf = Highs_getInfinity(highs); + + assert_eq!( + STATUS_OK, + Highs_addCol(highs, 1.0, 5.0, 10.0, 0, std::ptr::null(), std::ptr::null()), + "addCol" + ); + // x <= 7.5. + let idx: &mut [HighsInt] = &mut [0]; + let val: &mut [f64] = &mut [1.0]; + assert_eq!( + STATUS_OK, + Highs_addRow(highs, -inf, 7.5, 1, ptr(idx), ptr(val)), + "addRow" + ); + assert_eq!( + STATUS_OK, + Highs_changeColIntegrality(highs, 0, VAR_TYPE_SEMI_INTEGER), + "changeColIntegrality" + ); + assert_eq!( + Highs_changeObjectiveSense(highs, OBJECTIVE_SENSE_MAXIMIZE), + STATUS_OK + ); + assert_eq!(Highs_run(highs), STATUS_OK, "run"); + assert_eq!(Highs_getModelStatus(highs), MODEL_STATUS_OPTIMAL, "status"); + + let colvalue: &mut [f64] = &mut [0.; 1]; + let coldual: &mut [f64] = &mut [0.; 1]; + let rowvalue: &mut [f64] = &mut [0.; 1]; + let rowdual: &mut [f64] = &mut [0.; 1]; + Highs_getSolution( + highs, + ptr(colvalue), + ptr(coldual), + ptr(rowvalue), + ptr(rowdual), + ); + assert!((colvalue[0] - 7.0).abs() < 1e-6, "x = {}", colvalue[0]); + + Highs_destroy(highs); + } +} + #[cfg(not(target_os = "windows"))] // broken on windows #[test] fn highs_functions_multithread() {