Skip to content

Commit

Permalink
Merge pull request #8 from conjure-cp/main
Browse files Browse the repository at this point in the history
merge main
  • Loading branch information
gskorokhod authored Nov 30, 2023
2 parents a48d982 + eb82d62 commit cc11bed
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 58 deletions.
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Conjure-Oxide

This repository contains the in progress Conjure Oxide constraints modelling
tool, and it's dependencies.
This repository contains the in-progress Conjure Oxide constraints modelling
tool and its dependencies.

This repository hosts the following projects:

Expand Down
6 changes: 3 additions & 3 deletions solvers/chuffed/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,6 @@ fn bind() {
// The input header we would like to generate
// bindings for.
.header("wrapper.h")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
// Must manually give allow list to stop bindgen accidentally binding something complicated
// in C++ stdlib that will make it crash.
.allowlist_function("createVars")
Expand All @@ -84,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")
Expand Down
10 changes: 8 additions & 2 deletions solvers/chuffed/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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);
}
}
}
48 changes: 3 additions & 45 deletions solvers/chuffed/src/main.rs
Original file line number Diff line number Diff line change
@@ -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() {
Expand All @@ -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);
}
}
14 changes: 14 additions & 0 deletions solvers/chuffed/tests/chuffed_cpp_run.rs
Original file line number Diff line number Diff line change
@@ -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);
}
}
77 changes: 77 additions & 0 deletions solvers/chuffed/wrapper.cpp
Original file line number Diff line number Diff line change
@@ -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<IntVar *> *_searchVars) {
Expand All @@ -23,3 +24,79 @@ void branch_IntVar(vec<IntVar *> *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<IntVar *> x;
vec<IntVar *> y;
vec<IntVar *> 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); }
5 changes: 5 additions & 0 deletions solvers/chuffed/wrapper.h
Original file line number Diff line number Diff line change
@@ -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 {
Expand All @@ -25,3 +27,6 @@ void destroy_vec_intvar(vec<IntVar *> *v);

void branch_IntVar(vec<IntVar *> *x, VarBranch var_branch,
ValBranch val_branch);

void *new_xyz_problem(int n);
void solve_xyz(void *p);
7 changes: 7 additions & 0 deletions solvers/chuffed/xyz.fzn
Original file line number Diff line number Diff line change
@@ -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;
1 change: 1 addition & 0 deletions solvers/kissat/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#[cfg(test)]
#[test]
fn test1() {
use kissat_rs::Assignment;
use kissat_rs::Solver;
Expand Down
9 changes: 3 additions & 6 deletions solvers/minion/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ use std::process::Command;
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();

println!("cargo:rustc-link-search=all={}/build", out_dir);
println!("cargo:rustc-link-lib=static=minion");
println!("cargo:rerun-if-changed=vendor");
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=build.sh");

println!("cargo:rustc-link-search=all={}/build", out_dir);
println!("cargo:rustc-link-lib=static=minion");
build();

// also need to (dynamically) link to c++ stdlib
// https://flames-of-code.netlify.app/blog/rust-and-cmake-cplusplus/
Expand All @@ -31,7 +32,6 @@ fn main() {
unimplemented!();
}

build();
bind();
}

Expand Down Expand Up @@ -63,9 +63,6 @@ fn bind() {
// The input header we would like to generate
// bindings for.
.header("vendor/minion/libwrapper.h")
// Tell cargo to invalidate the built crate whenever any of the
// included header files changed.
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
// Make all templates opaque as reccomended by bindgen
.opaque_type("std::.*")
// Manually allow C++ functions to stop bindgen getting confused.
Expand Down

0 comments on commit cc11bed

Please sign in to comment.