From 886c17efcc954a52a22cb6828f43403dc8e46b31 Mon Sep 17 00:00:00 2001 From: Kieranoski Date: Sun, 5 Nov 2023 18:44:44 +0000 Subject: [PATCH] Turn example main program into rust test --- solvers/chuffed/build.rs | 1 + solvers/chuffed/src/lib.rs | 17 +++++- solvers/chuffed/src/main.rs | 19 +++++- solvers/chuffed/tests/chuffed_basic_run.rs | 67 ++++++++++++++++++++++ solvers/chuffed/wrapper.cpp | 14 +++-- solvers/chuffed/wrapper.h | 7 ++- 6 files changed, 111 insertions(+), 14 deletions(-) create mode 100644 solvers/chuffed/tests/chuffed_basic_run.rs diff --git a/solvers/chuffed/build.rs b/solvers/chuffed/build.rs index 280dbd7d90..a20e120d83 100644 --- a/solvers/chuffed/build.rs +++ b/solvers/chuffed/build.rs @@ -76,6 +76,7 @@ fn bind() { .allowlist_function("destroy_vec_intvar") .allowlist_function("p_addVars") .allowlist_function("p_setcallback") + .allowlist_function("p_print") .allowlist_function("branch_IntVar") .clang_arg("-Ivendor/build") // generated from configure.py .clang_arg("-Ivendor") diff --git a/solvers/chuffed/src/lib.rs b/solvers/chuffed/src/lib.rs index f935887260..4e8fc22659 100644 --- a/solvers/chuffed/src/lib.rs +++ b/solvers/chuffed/src/lib.rs @@ -7,8 +7,8 @@ pub mod bindings { pub mod wrappers { use crate::bindings::{ - all_different, branch_IntVar, createVar, createVars, make_vec_intvar, vec, ConLevel, - IntVar, ValBranch, VarBranch, + all_different, branch_IntVar, createVar, createVars, make_vec_intvar, output_vars1, + var_sym_break, vec, ConLevel, IntVar, ValBranch, VarBranch, }; use core::ptr; @@ -50,4 +50,17 @@ pub mod wrappers { branch_IntVar(x, var_branch, val_branch); } } + + pub unsafe fn output_vars_wrapper(x: *mut vec<*mut IntVar>) { + unsafe { + // output_vars1 takes in an vec instead of branching + output_vars1(x); + } + } + + pub unsafe fn var_sym_break_wrapper(x: *mut vec<*mut IntVar>) { + unsafe { + var_sym_break(x); + } + } } diff --git a/solvers/chuffed/src/main.rs b/solvers/chuffed/src/main.rs index c97ff07353..a22f3de3b6 100644 --- a/solvers/chuffed/src/main.rs +++ b/solvers/chuffed/src/main.rs @@ -1,8 +1,10 @@ use chuffed_rs::bindings::{ - get_idx, new_dummy_problem, p_addVars, p_setcallback, vec, ConLevel_CL_DEF, IntVar, + get_idx, new_dummy_problem, p_addVars, p_print, p_setcallback, vec, ConLevel_CL_DEF, IntVar, VarBranch_VAR_INORDER, VarBranch_VAR_MIN_MIN, }; -use chuffed_rs::wrappers::{all_different_wrapper, branch_wrapper, create_vars}; +use chuffed_rs::wrappers::{ + all_different_wrapper, branch_wrapper, create_vars, output_vars_wrapper, var_sym_break_wrapper, +}; unsafe fn post_constraints(_n: i32) -> *mut vec<*mut IntVar> { // Create constant @@ -16,15 +18,23 @@ unsafe fn post_constraints(_n: i32) -> *mut vec<*mut IntVar> { // Post some branchings branch_wrapper(x as _, VarBranch_VAR_INORDER, VarBranch_VAR_MIN_MIN); + // Declare output variables (optional) + output_vars_wrapper(x); + + // Declare symmetries (optional) + var_sym_break_wrapper(x); + + // Return the variable x } // Custom printing function for this problem #[no_mangle] pub unsafe extern "C" fn callback(x: *mut vec<*mut IntVar>) { - print!("First output is: {:?}", get_idx(x, 0)); + print!("First output is: {}", get_idx(x, 0)); } +// Entry point for running this problem fn main() { let args: Vec = std::env::args().collect(); @@ -43,5 +53,8 @@ fn main() { p_addVars(p, x); // Call problem.setcallback() p_setcallback(p, Some(callback)); + // Commented out currently as trying to print causes the assertion of + // isFixed() in IntVar::getVal() to fail. + // p_print(p); } } diff --git a/solvers/chuffed/tests/chuffed_basic_run.rs b/solvers/chuffed/tests/chuffed_basic_run.rs new file mode 100644 index 0000000000..535b6dc12d --- /dev/null +++ b/solvers/chuffed/tests/chuffed_basic_run.rs @@ -0,0 +1,67 @@ +use chuffed_rs::bindings::{ + get_idx, new_dummy_problem, p_addVars, p_print, p_setcallback, vec, ConLevel_CL_DEF, IntVar, + VarBranch_VAR_INORDER, VarBranch_VAR_MIN_MIN, +}; +use chuffed_rs::wrappers::{ + all_different_wrapper, branch_wrapper, create_vars, output_vars_wrapper, var_sym_break_wrapper, +}; + +/// Creates the variable for the test problem and posts some constraints and +/// branchings on it. +unsafe fn post_constraints(_n: i32) -> *mut vec<*mut IntVar> { + // Create constant + let n: i32 = _n; + // Create some variables + let x: *mut vec<*mut IntVar> = create_vars(n, 0, n, false); + + // Post some constraints + all_different_wrapper(x, ConLevel_CL_DEF); + + // Post some branchings + branch_wrapper(x as _, VarBranch_VAR_INORDER, VarBranch_VAR_MIN_MIN); + + // Declare output variables (optional) + output_vars_wrapper(x); + + // Declare symmetries (optional) + var_sym_break_wrapper(x); + + // Return the variable + x +} + +/// Custom printing function for this test problem +#[no_mangle] +pub unsafe extern "C" fn callback(x: *mut vec<*mut IntVar>) { + print!("First output is: {}", get_idx(x, 0)); +} + +/// Basic test to make sure that running the ffi bindings and wrappers does not +/// crash +#[test] +fn run_basic_problem() { + let args: Vec = std::env::args().collect(); + + if args.len() != 2 { + println!("Invalid number of arguments"); + return; + } + + let n: i32 = args[1].parse().expect("Invalid input"); + + unsafe { + let x = post_constraints(n); + // make new dummy problem + let p = new_dummy_problem(); + // Call problem.addvars() + p_addVars(p, x); + // Call problem.setcallback() + p_setcallback(p, Some(callback)); + // Commented out currently as trying to print causes the assertion of + // isFixed() in IntVar::getVal() to fail. + // p_print(p); + + // Pass test if no crash occurs + assert!(true); + } +} diff --git a/solvers/chuffed/wrapper.cpp b/solvers/chuffed/wrapper.cpp index 94d90aed20..84a89b42a9 100644 --- a/solvers/chuffed/wrapper.cpp +++ b/solvers/chuffed/wrapper.cpp @@ -7,15 +7,17 @@ void p_addVars(DummyProblem *p, vec *_searchVars) { void p_setcallback(DummyProblem *p, void (*_callback)(vec *)) { p->setcallback(_callback); } -IntVar* get_idx(vec *x, int i) { return *x[i]; } +void p_print(DummyProblem *p) { p->print(); } -vec* make_vec_intvar() { - return new vec(); +int get_idx(vec *x, int i) { + IntVar *var = *x[i]; + int t = var->getVal(); + return t; } -void destroy_vec_intvar(vec* v) { - delete v; -} +vec *make_vec_intvar() { return new vec(); } + +void destroy_vec_intvar(vec *v) { delete v; } void branch_IntVar(vec *x, VarBranch var_branch, ValBranch val_branch) { diff --git a/solvers/chuffed/wrapper.h b/solvers/chuffed/wrapper.h index 6a0773539a..d8a10c4fd6 100644 --- a/solvers/chuffed/wrapper.h +++ b/solvers/chuffed/wrapper.h @@ -17,10 +17,11 @@ class DummyProblem { DummyProblem *new_dummy_problem(); void p_addVars(DummyProblem *p, vec *_searchVars); void p_setcallback(DummyProblem *p, void (*_callback)(vec *)); -IntVar* get_idx(vec *x, int i); +void p_print(DummyProblem *p); +int get_idx(vec *x, int i); -vec* make_vec_intvar(); -void destroy_vec_intvar(vec* v); +vec *make_vec_intvar(); +void destroy_vec_intvar(vec *v); void branch_IntVar(vec *x, VarBranch var_branch, ValBranch val_branch);