diff --git a/solvers/chuffed/build.rs b/solvers/chuffed/build.rs index 8802202695..6439f775a2 100644 --- a/solvers/chuffed/build.rs +++ b/solvers/chuffed/build.rs @@ -81,6 +81,9 @@ fn bind() { .allowlist_function("p_setcallback") .allowlist_function("p_print") .allowlist_function("branch_IntVar") + .allowlist_function("new_xyz_problem") + .allowlist_function("solve_xyz") + .allowlist_function("int_plus") .clang_arg(format!("-I{}/build", out_dir)) .clang_arg("-Ivendor") .clang_arg(r"--std=gnu++11") diff --git a/solvers/chuffed/src/lib.rs b/solvers/chuffed/src/lib.rs index 45b17a4a34..ec46d7f3cf 100644 --- a/solvers/chuffed/src/lib.rs +++ b/solvers/chuffed/src/lib.rs @@ -5,8 +5,8 @@ pub mod bindings { pub mod wrappers { use crate::bindings::{ - all_different, branch_IntVar, createVar, createVars, make_vec_intvar, output_vars1, - var_sym_break, vec, ConLevel, IntVar, ValBranch, VarBranch, + all_different, branch_IntVar, createVar, createVars, int_plus, make_vec_intvar, + output_vars1, var_sym_break, vec, ConLevel, IntVar, ValBranch, VarBranch, }; use core::ptr; @@ -61,4 +61,10 @@ pub mod wrappers { var_sym_break(x); } } + + pub unsafe fn int_plus_wrapper(x: *mut IntVar, y: *mut IntVar, z: *mut IntVar) { + unsafe { + int_plus(x, y, z); + } + } } diff --git a/solvers/chuffed/src/main.rs b/solvers/chuffed/src/main.rs index a22f3de3b6..d00676f22f 100644 --- a/solvers/chuffed/src/main.rs +++ b/solvers/chuffed/src/main.rs @@ -1,38 +1,4 @@ -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, -}; - -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 problem -#[no_mangle] -pub unsafe extern "C" fn callback(x: *mut vec<*mut IntVar>) { - print!("First output is: {}", get_idx(x, 0)); -} +use chuffed_rs::bindings::{new_xyz_problem, solve_xyz}; // Entry point for running this problem fn main() { @@ -46,15 +12,7 @@ fn main() { 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); + let p = new_xyz_problem(n); + solve_xyz(p); } } diff --git a/solvers/chuffed/tests/chuffed_cpp_run.rs b/solvers/chuffed/tests/chuffed_cpp_run.rs new file mode 100644 index 0000000000..3798a4a5fe --- /dev/null +++ b/solvers/chuffed/tests/chuffed_cpp_run.rs @@ -0,0 +1,14 @@ +use chuffed_rs::bindings::{new_xyz_problem, solve_xyz}; + +#[test] +fn run_cpp_problem() { + let n: i32 = 1; + + unsafe { + let p = new_xyz_problem(n); + solve_xyz(p); + + // Pass test if no crash occurs + assert!(true); + } +} diff --git a/solvers/chuffed/wrapper.cpp b/solvers/chuffed/wrapper.cpp index 84a89b42a9..3e6529209b 100644 --- a/solvers/chuffed/wrapper.cpp +++ b/solvers/chuffed/wrapper.cpp @@ -1,4 +1,5 @@ #include "./wrapper.h" +#include "chuffed/flatzinc/flatzinc.h" DummyProblem *new_dummy_problem() { return new DummyProblem(); } void p_addVars(DummyProblem *p, vec *_searchVars) { @@ -23,3 +24,79 @@ void branch_IntVar(vec *x, VarBranch var_branch, ValBranch val_branch) { branch(*x, var_branch, val_branch); } + +// Construct problem with given number of variables +FlatZinc::FlatZincSpace *new_flat_zinc_space(int intVars, int boolVars, + int setVars) { + return new FlatZinc::FlatZincSpace(intVars, boolVars, setVars); +} + +// add new int var +void addIntVar(FlatZinc::FlatZincSpace flat_zinc_space, + FlatZinc::IntVarSpec *vs, const std::string &name) { + flat_zinc_space.newIntVar(vs, name); +} + +class XYZProblem : public Problem { + +public: + // Constants + int n; // number of variables + + // Variables + vec x; + vec y; + vec z; + + XYZProblem(int _n) : n(_n) { + // Create vars + createVars(x, n, 1, 3); + createVars(y, n, 1, 3); + createVars(z, n, 1, 3); + + // Post constraints + // find x, y, z : int(1..3) + // such that x + y = z + + all_different(x); + + for (int i = 0; i < n; i++) { + int_plus(x[i], y[i], z[i]); + } + + // Branching + branch(x, VAR_INORDER, VAL_MIN); + branch(y, VAR_INORDER, VAL_MIN); + branch(z, VAR_INORDER, VAL_MIN); + + // Declare output variables + output_vars(x); + output_vars(y); + output_vars(z); + } + + // Function to print out solution + void print(std::ostream &out) override { + out << "x = "; + for (int i = 0; i < n; i++) { + out << x[i]->getVal() << " "; + } + out << std::endl; + out << "y = "; + for (int i = 0; i < n; i++) { + out << y[i]->getVal() << " "; + } + out << std::endl; + out << "z = "; + for (int i = 0; i < n; i++) { + out << z[i]->getVal() << " "; + } + out << std::endl; + } +}; + +// Create new xyz problem +void *new_xyz_problem(int n) { return new XYZProblem(n); } + +// Solve xyz problem +void solve_xyz(void *p) { engine.solve((XYZProblem *)p); } diff --git a/solvers/chuffed/wrapper.h b/solvers/chuffed/wrapper.h index d8a10c4fd6..30c7108f33 100644 --- a/solvers/chuffed/wrapper.h +++ b/solvers/chuffed/wrapper.h @@ -1,6 +1,8 @@ #include "chuffed/branching/branching.h" #include "chuffed/core/engine.h" #include "chuffed/core/propagator.h" +#include "chuffed/flatzinc/flatzinc.h" +#include "chuffed/primitives/primitives.h" #include "chuffed/vars/modelling.h" class DummyProblem { @@ -25,3 +27,6 @@ void destroy_vec_intvar(vec *v); void branch_IntVar(vec *x, VarBranch var_branch, ValBranch val_branch); + +void *new_xyz_problem(int n); +void solve_xyz(void *p); diff --git a/solvers/chuffed/xyz.fzn b/solvers/chuffed/xyz.fzn new file mode 100644 index 0000000000..934105800b --- /dev/null +++ b/solvers/chuffed/xyz.fzn @@ -0,0 +1,7 @@ +predicate all_different_int(array [int] of var int: xs); +var 1..3: x:: output_var ; +var 1..3: y:: output_var ; +var 1..3: z:: output_var ; +constraint int_lin_eq([1,1,-1],[x,y,z],0); +solve :: int_search([x, y, z], input_order, indomain_min, complete) + satisfy;