diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/flat.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/flat.svg
new file mode 100644
index 0000000000..bf23e67c31
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/flat.svg
@@ -0,0 +1,23 @@
+
+ coverage: 0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+ coverage
+ coverage
+ 0%
+ 0%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/flat_square.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/flat_square.svg
new file mode 100644
index 0000000000..dd62fd7016
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/flat_square.svg
@@ -0,0 +1,13 @@
+
+ coverage: 0%
+
+
+
+
+
+ coverage
+ 0%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/for_the_badge.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/for_the_badge.svg
new file mode 100644
index 0000000000..0b8854cd6b
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/for_the_badge.svg
@@ -0,0 +1,13 @@
+
+ COVERAGE: 0%
+
+
+
+
+
+ COVERAGE
+ 0%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/plastic.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/plastic.svg
new file mode 100644
index 0000000000..56ddfa74e6
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/plastic.svg
@@ -0,0 +1,25 @@
+
+ coverage: 0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ coverage
+ coverage
+ 0%
+ 0%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/social.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/social.svg
new file mode 100644
index 0000000000..4675a1a427
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/badges/social.svg
@@ -0,0 +1,27 @@
+
+ Coverage: 0%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Coverage
+ Coverage
+ 0%
+ 0%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/coverage.json b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/coverage.json
new file mode 100644
index 0000000000..13bbdcbd82
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/coverage.json
@@ -0,0 +1 @@
+{"schemaVersion":1,"label":"coverage","message":"0.00%","color":"red"}
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/index.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/index.html
new file mode 100644
index 0000000000..7bc0b775cf
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/index.html
@@ -0,0 +1,88 @@
+
+
+
+
+ Grcov report - top_level
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory
+ Line Coverage
+ Functions
+
+ Branches
+
+
+
+
+
+ src
+
+
+
+ 0%
+
+
+
+ 0%
+
+
+ 0 / 41
+
+
+ 0%
+ 0 / 20
+
+
+ 100%
+ 0 / 0
+
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/src/index.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/src/index.html
new file mode 100644
index 0000000000..7fa1abd285
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/src/index.html
@@ -0,0 +1,88 @@
+
+
+
+
+ Grcov report - src
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ File
+ Line Coverage
+ Functions
+
+ Branches
+
+
+
+
+
+ lib.rs
+
+
+
+ 0%
+
+
+
+ 0%
+
+
+ 0 / 41
+
+
+ 0%
+ 0 / 20
+
+
+ 100%
+ 0 / 0
+
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/src/lib.rs.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/src/lib.rs.html
new file mode 100644
index 0000000000..049bfb15cc
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/chuffed/src/lib.rs.html
@@ -0,0 +1,1106 @@
+
+
+
+
+ Grcov report - lib.rs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
#![allow(non_upper_case_globals)]
+
+
+
+
+
+
+
+
#![allow(non_camel_case_types)]
+
+
+
+
+
+
+
+
#![allow(non_snake_case)]
+
+
+
+
+
+
+
+
include!(concat!(env!("OUT_DIR"), "/chuffed_bindings.rs"));
+
+
+
+
+
+
+
+
use crate::bindings::{
+
+
+
+
+
+
+
+
all_different, branch_IntVar, createVar, createVars, make_vec_intvar, output_vars1,
+
+
+
+
+
+
+
+
var_sym_break, vec, ConLevel, IntVar, ValBranch, VarBranch,
+
+
+
+
+
+
+
+
// The signature of createVar is below for reference.
+
+
+
+
+
+
+
+
// createVar(x: *mut *mut IntVar, min: ::std::os::raw::c_int, max: ::std::os::raw::c_int, el: bool)
+
+
+
+
+
+
+
+
pub fn create_var(min: i32, max: i32, el: bool) -> *mut IntVar {
+
+
+
+
+
+
+
+
let mut ptr: *mut IntVar = ptr::null_mut();
+
+
+
+
+
+
+
+
createVar(&mut ptr, min, max, el);
+
+
+
+
+
+
+
+
// createVars void createVars(vec<IntVar*>& x, int n, int min, int max, bool el)
+
+
+
+
+
+
+
+
pub fn create_vars(n: i32, min: i32, max: i32, el: bool) -> *mut vec<*mut IntVar> {
+
+
+
+
+
+
+
+
let ptr: *mut vec<*mut IntVar> = unsafe { make_vec_intvar() };
+
+
+
+
+
+
+
+
createVars(ptr, n, min, max, el);
+
+
+
+
+
+
+
+
// void all_different(vec<IntVar*>& x, ConLevel cl)
+
+
+
+
+
+
+
+
pub unsafe fn all_different_wrapper(x: *mut vec<*mut IntVar>, cl: ConLevel) {
+
+
+
+
+
+
+
+
all_different(x, cl);
+
+
+
+
+
+
+
+
// void branch(vec<Branching*> x, VarBranch var_branch, ValBranch val_branch);
+
+
+
+
+
+
+
+
pub unsafe fn branch_wrapper(
+
+
+
+
+
+
+
+
x: *mut vec<*mut IntVar>,
+
+
+
+
+
+
+
+
var_branch: VarBranch,
+
+
+
+
+
+
+
+
val_branch: ValBranch,
+
+
+
+
+
+
+
+
branch_IntVar(x, var_branch, val_branch);
+
+
+
+
+
+
+
+
pub unsafe fn output_vars_wrapper(x: *mut vec<*mut IntVar>) {
+
+
+
+
+
+
+
+
// output_vars1 takes in an vec<IntVar*> instead of branching
+
+
+
+
+
+
+
+
pub unsafe fn var_sym_break_wrapper(x: *mut vec<*mut IntVar>) {
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/flat.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/flat.svg
new file mode 100644
index 0000000000..617990c047
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/flat.svg
@@ -0,0 +1,23 @@
+
+ coverage: 81%
+
+
+
+
+
+
+
+
+
+
+
+
+
+ coverage
+ coverage
+ 81%
+ 81%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/flat_square.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/flat_square.svg
new file mode 100644
index 0000000000..61ac9234cd
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/flat_square.svg
@@ -0,0 +1,13 @@
+
+ coverage: 81%
+
+
+
+
+
+ coverage
+ 81%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/for_the_badge.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/for_the_badge.svg
new file mode 100644
index 0000000000..47e896f018
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/for_the_badge.svg
@@ -0,0 +1,13 @@
+
+ COVERAGE: 81%
+
+
+
+
+
+ COVERAGE
+ 81%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/plastic.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/plastic.svg
new file mode 100644
index 0000000000..b3880efbcb
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/plastic.svg
@@ -0,0 +1,25 @@
+
+ coverage: 81%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ coverage
+ coverage
+ 81%
+ 81%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/social.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/social.svg
new file mode 100644
index 0000000000..de42d48917
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/badges/social.svg
@@ -0,0 +1,27 @@
+
+ Coverage: 81%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Coverage
+ Coverage
+ 81%
+ 81%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/coverage.json b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/coverage.json
new file mode 100644
index 0000000000..101bc105c2
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/coverage.json
@@ -0,0 +1 @@
+{"schemaVersion":1,"label":"coverage","message":"81.82%","color":"yellow"}
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/index.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/index.html
new file mode 100644
index 0000000000..64b0c579b2
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/index.html
@@ -0,0 +1,88 @@
+
+
+
+
+ Grcov report - top_level
+
+
+
+
+
+
+
+
+
+
+
+
Functions
+
+ 15.58 %
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory
+ Line Coverage
+ Functions
+
+ Branches
+
+
+
+
+
+ src/common/ast
+
+
+
+ 81.82%
+
+
+
+ 81.82%
+
+
+ 9 / 11
+
+
+ 15.58%
+ 12 / 77
+
+
+ 100%
+ 0 / 0
+
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/src/common/ast/ast.rs.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/src/common/ast/ast.rs.html
new file mode 100644
index 0000000000..2dab885f62
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/src/common/ast/ast.rs.html
@@ -0,0 +1,818 @@
+
+
+
+
+ Grcov report - ast.rs
+
+
+
+
+
+
+
+
+
+
+
+
Functions
+
+ 15.58 %
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
use std::collections::HashMap;
+
+
+
+
+
+
+
+
pub variables: HashMap<Name, DecisionVariable>,
+
+
+
+
+
+
+
+
pub constraints: Vec<Expression>,
+
+
+
+
+
+
+
+
// Function to update a DecisionVariable based on its Name
+
+
+
+
+ 2
+
+
+
pub fn update_domain(&mut self, name: &Name, new_domain: Domain) {
+
+
+
+
+ 2
+
+
+
if let Some(decision_var) = self.variables.get_mut(name) {
+
+
+
+
+ 2
+
+
+
decision_var.domain = new_domain;
+
+
+
+
+ 8
+
+
+
#[derive(Clone, Debug, Eq, PartialEq, Hash)]
+
+
+
+
+
+
+
+
#[derive(Debug, PartialEq)]
+
+
+
+
+
+
+
+
pub struct DecisionVariable {
+
+
+
+
+ 2
+
+
+
#[derive(Clone, Debug, PartialEq)]
+
+
+
+
+
+
+
+
IntDomain(Vec<Range<i32>>),
+
+
+
+
+ 2
+
+
+
#[derive(Clone, Debug, PartialEq)]
+
+
+
+
+ 17
+
+
+
#[derive(Clone, Debug, PartialEq)]
+
+
+
+
+
+
+
+
pub enum Expression {
+
+
+
+
+
+
+
+
Sum(Vec<Expression>),
+
+
+
+
+
+
+
+
Eq(Box<Expression>, Box<Expression>),
+
+
+
+
+
+
+
+
Geq(Box<Expression>, Box<Expression>),
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/src/common/ast/index.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/src/common/ast/index.html
new file mode 100644
index 0000000000..6a6f3ada8e
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/conjure-oxide/src/common/ast/index.html
@@ -0,0 +1,88 @@
+
+
+
+
+ Grcov report - src/common/ast
+
+
+
+
+
+
+
+
+
+
+
+
Functions
+
+ 15.58 %
+
+
+
+
+
+
+
+
+
+
+
+
+ File
+ Line Coverage
+ Functions
+
+ Branches
+
+
+
+
+
+ ast.rs
+
+
+
+ 81.82%
+
+
+
+ 81.82%
+
+
+ 9 / 11
+
+
+ 15.58%
+ 12 / 77
+
+
+ 100%
+ 0 / 0
+
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/flat.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/flat.svg
new file mode 100644
index 0000000000..606ea84823
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/flat.svg
@@ -0,0 +1,23 @@
+
+ coverage: 76%
+
+
+
+
+
+
+
+
+
+
+
+
+
+ coverage
+ coverage
+ 76%
+ 76%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/flat_square.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/flat_square.svg
new file mode 100644
index 0000000000..fc84cccdf0
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/flat_square.svg
@@ -0,0 +1,13 @@
+
+ coverage: 76%
+
+
+
+
+
+ coverage
+ 76%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/for_the_badge.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/for_the_badge.svg
new file mode 100644
index 0000000000..11a6e0ee88
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/for_the_badge.svg
@@ -0,0 +1,13 @@
+
+ COVERAGE: 76%
+
+
+
+
+
+ COVERAGE
+ 76%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/plastic.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/plastic.svg
new file mode 100644
index 0000000000..ee25c04aed
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/plastic.svg
@@ -0,0 +1,25 @@
+
+ coverage: 76%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ coverage
+ coverage
+ 76%
+ 76%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/social.svg b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/social.svg
new file mode 100644
index 0000000000..aa95beecb2
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/badges/social.svg
@@ -0,0 +1,27 @@
+
+ Coverage: 76%
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Coverage
+ Coverage
+ 76%
+ 76%
+
+
+
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/coverage.json b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/coverage.json
new file mode 100644
index 0000000000..d09fc6bd77
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/coverage.json
@@ -0,0 +1 @@
+{"schemaVersion":1,"label":"coverage","message":"76.35%","color":"yellow"}
\ No newline at end of file
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/index.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/index.html
new file mode 100644
index 0000000000..5caf4975d3
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/index.html
@@ -0,0 +1,88 @@
+
+
+
+
+ Grcov report - top_level
+
+
+
+
+
+
+
+
+
+
+
+
Functions
+
+ 45.88 %
+
+
+
+
+
+
+
+
+
+
+
+
+ Directory
+ Line Coverage
+ Functions
+
+ Branches
+
+
+
+
+
+ src
+
+
+
+ 76.35%
+
+
+
+ 76.35%
+
+
+ 297 / 389
+
+
+ 45.88%
+ 39 / 85
+
+
+ 100%
+ 0 / 0
+
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/ast.rs.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/ast.rs.html
new file mode 100644
index 0000000000..21275be442
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/ast.rs.html
@@ -0,0 +1,1634 @@
+
+
+
+
+ Grcov report - ast.rs
+
+
+
+
+
+
+
+
+
+
+
+
Functions
+
+ 35.71 %
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
* This Source Code Form is subject to the terms of the Mozilla Public
+
+
+
+
+
+
+
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
+
+
+
+
+
+
+
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+
+
+
+
+
+
+
//! The Model Syntax tree for the Minion bindings.
+
+
+
+
+
+
+
+
use std::collections::HashMap;
+
+
+
+
+
+
+
+
pub type VarName = String;
+
+
+
+
+
+
+
+
/// A lookup table of all named variables.
+
+
+
+
+
+
+
+
pub named_variables: SymbolTable,
+
+
+
+
+
+
+
+
pub constraints: Vec<Constraint>,
+
+
+
+
+ 1
+
+
+
pub fn new() -> Model {
+
+
+
+
+ 1
+
+
+
named_variables: SymbolTable::new(),
+
+
+
+
+ 1
+
+
+
constraints: Vec::new(),
+
+
+
+
+
+
+
+
pub enum Constraint {
+
+
+
+
+
+
+
+
SumLeq(Vec<Var>, Var),
+
+
+
+
+
+
+
+
SumGeq(Vec<Var>, Var),
+
+
+
+
+
+
+
+
Ineq(Var, Var, Constant),
+
+
+
+
+
+
+
+
/// A variable can either be a named variable, or an anomynous "constant as a variable".
+
+
+
+
+
+
+
+
/// The latter is not stored in the symbol table, or counted in Minions internal list of all
+
+
+
+
+
+
+
+
/// variables, but is used to allow the use of a constant in the place of a variable in a
+
+
+
+
+
+
+
+
#[derive(Copy, Clone)]
+
+
+
+
+
+
+
+
SparseBound(i32, i32),
+
+
+
+
+
+
+
+
pub struct SymbolTable {
+
+
+
+
+
+
+
+
table: HashMap<VarName, VarDomain>,
+
+
+
+
+
+
+
+
// for now doubles both as Minion's SearchOrder and print order
+
+
+
+
+
+
+
+
var_order: Vec<VarName>,
+
+
+
+
+ 1
+
+
+
fn new() -> SymbolTable {
+
+
+
+
+ 1
+
+
+
table: HashMap::new(),
+
+
+
+
+ 1
+
+
+
var_order: Vec::new(),
+
+
+
+
+
+
+
+
/// Creates a new variable and adds it to the symbol table.
+
+
+
+
+
+
+
+
/// If a variable already exists with the given name, an error is thrown.
+
+
+
+
+ 3
+
+
+
pub fn add_var(&mut self, name: VarName, vartype: VarDomain) -> Option<()> {
+
+
+
+
+ 3
+
+
+
if self.table.contains_key(&name) {
+
+
+
+
+ 3
+
+
+
self.table.insert(name.clone(), vartype);
+
+
+
+
+ 3
+
+
+
self.var_order.push(name);
+
+
+
+
+ 3
+
+
+
pub fn get_vartype(&self, name: VarName) -> Option<VarDomain> {
+
+
+
+
+ 3
+
+
+
match self.table.get(&name) {
+
+
+
+
+ 1
+
+
+
pub fn get_variable_order(&self) -> Vec<VarName> {
+
+
+
+
+ 1
+
+
+
self.var_order.clone()
+
+
+
+
+
+
+
+
pub fn contains(&self, name: VarName) -> bool {
+
+
+
+
+
+
+
+
self.table.contains_key(&name)
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/error.rs.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/error.rs.html
new file mode 100644
index 0000000000..d8805bb24b
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/error.rs.html
@@ -0,0 +1,578 @@
+
+
+
+
+ Grcov report - error.rs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
* This Source Code Form is subject to the terms of the Mozilla Public
+
+
+
+
+
+
+
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
+
+
+
+
+
+
+
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+
+
+
+
+
+
+
//! Error types for Minion bindings.
+
+
+
+
+
+
+
+
use crate::raw_bindings::*;
+
+
+
+
+
+
+
+
use thiserror::Error;
+
+
+
+
+
+
+
+
/// RuntimeErrors are thrown by Minion during execution.
+
+
+
+
+
+
+
+
#[derive(Debug, Error)]
+
+
+
+
+
+
+
+
pub enum RuntimeError {
+
+
+
+
+
+
+
+
// These closely follow the ReturnCodes found in Minion's libwrapper.cpp.
+
+
+
+
+
+
+
+
#[error("the given instance is invalid")]
+
+
+
+
+
+
+
+
#[error("an unknown error has occurred while running minion")]
+
+
+
+
+
+
+
+
// Minion's ReturnCodes are passed over FFI as ints.
+
+
+
+
+
+
+
+
// Convert them to their appropriate error.
+
+
+
+
+
+
+
+
impl From<u32> for RuntimeError {
+
+
+
+
+
+
+
+
fn from(return_code: u32) -> Self {
+
+
+
+
+
+
+
+
#[allow(non_upper_case_globals)]
+
+
+
+
+
+
+
+
ReturnCodes_INVALID_INSTANCE => RuntimeError::InvalidInstance,
+
+
+
+
+
+
+
+
_ => RuntimeError::UnknownError,
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/index.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/index.html
new file mode 100644
index 0000000000..2a5f341cc6
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/index.html
@@ -0,0 +1,196 @@
+
+
+
+
+ Grcov report - src
+
+
+
+
+
+
+
+
+
+
+
+
Functions
+
+ 45.88 %
+
+
+
+
+
+
+
+
+
+
+
+
+ File
+ Line Coverage
+ Functions
+
+ Branches
+
+
+
+
+
+ ast.rs
+
+
+
+ 53.85%
+
+
+
+ 53.85%
+
+
+ 28 / 52
+
+
+ 35.71%
+ 5 / 14
+
+
+ 100%
+ 0 / 0
+
+
+
+
+ error.rs
+
+
+
+ 0%
+
+
+
+ 0%
+
+
+ 0 / 7
+
+
+ 0%
+ 0 / 3
+
+
+ 100%
+ 0 / 0
+
+
+
+
+ raw_bindings.rs
+
+
+
+ 97.7%
+
+
+
+ 97.7%
+
+
+ 85 / 87
+
+
+ 60%
+ 3 / 5
+
+
+ 100%
+ 0 / 0
+
+
+
+
+ run.rs
+
+
+
+ 76.86%
+
+
+
+ 76.86%
+
+
+ 176 / 229
+
+
+ 48.72%
+ 19 / 39
+
+
+ 100%
+ 0 / 0
+
+
+
+
+ scoped_ptr.rs
+
+
+
+ 57.14%
+
+
+
+ 57.14%
+
+
+ 8 / 14
+
+
+ 50%
+ 12 / 24
+
+
+ 100%
+ 0 / 0
+
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/raw_bindings.rs.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/raw_bindings.rs.html
new file mode 100644
index 0000000000..e692d8f009
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/raw_bindings.rs.html
@@ -0,0 +1,1826 @@
+
+
+
+
+ Grcov report - raw_bindings.rs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
* This Source Code Form is subject to the terms of the Mozilla Public
+
+
+
+
+
+
+
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
+
+
+
+
+
+
+
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+
+
+
+
+
+
+
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
+
+
+
+
+
+
+
+
use std::ffi::CString;
+
+
+
+
+
+
+
+
static mut X_VAL: i32 = 0;
+
+
+
+
+
+
+
+
static mut Y_VAL: i32 = 0;
+
+
+
+
+
+
+
+
static mut Z_VAL: i32 = 0;
+
+
+
+
+ 1
+
+
+
pub extern "C" fn hello_from_rust() -> bool {
+
+
+
+
+ 1
+
+
+
X_VAL = printMatrix_getValue(0) as _;
+
+
+
+
+ 1
+
+
+
Y_VAL = printMatrix_getValue(1) as _;
+
+
+
+
+ 1
+
+
+
Z_VAL = printMatrix_getValue(2) as _;
+
+
+
+
+ 1
+
+
+
// A simple constraints model, manually written using FFI functions.
+
+
+
+
+ 1
+
+
+
// Testing to see if it does not segfault.
+
+
+
+
+ 1
+
+
+
// Results can be manually inspected in the outputted minion logs.
+
+
+
+
+ 1
+
+
+
// See https://rust-lang.github.io/rust-bindgen/cpp.html
+
+
+
+
+ 1
+
+
+
let options = newSearchOptions();
+
+
+
+
+ 1
+
+
+
let args = newSearchMethod();
+
+
+
+
+ 1
+
+
+
let instance = newInstance();
+
+
+
+
+ 1
+
+
+
let x_str = CString::new("x").expect("bad x");
+
+
+
+
+ 1
+
+
+
let y_str = CString::new("y").expect("bad y");
+
+
+
+
+ 1
+
+
+
let z_str = CString::new("z").expect("bad z");
+
+
+
+
+ 1
+
+
+
newVar_ffi(instance, x_str.as_ptr() as _, VariableType_VAR_BOUND, 1, 3);
+
+
+
+
+ 1
+
+
+
newVar_ffi(instance, y_str.as_ptr() as _, VariableType_VAR_BOUND, 2, 4);
+
+
+
+
+ 1
+
+
+
newVar_ffi(instance, z_str.as_ptr() as _, VariableType_VAR_BOUND, 1, 5);
+
+
+
+
+ 1
+
+
+
let x = getVarByName(instance, x_str.as_ptr() as _);
+
+
+
+
+ 1
+
+
+
let y = getVarByName(instance, y_str.as_ptr() as _);
+
+
+
+
+ 1
+
+
+
let z = getVarByName(instance, z_str.as_ptr() as _);
+
+
+
+
+ 1
+
+
+
printMatrix_addVar(instance, x);
+
+
+
+
+ 1
+
+
+
printMatrix_addVar(instance, y);
+
+
+
+
+ 1
+
+
+
printMatrix_addVar(instance, z);
+
+
+
+
+ 1
+
+
+
let search_vars = vec_var_new();
+
+
+
+
+ 1
+
+
+
vec_var_push_back(search_vars as _, x);
+
+
+
+
+ 1
+
+
+
vec_var_push_back(search_vars as _, y);
+
+
+
+
+ 1
+
+
+
vec_var_push_back(search_vars as _, z);
+
+
+
+
+ 1
+
+
+
let search_order = newSearchOrder(search_vars as _, VarOrderEnum_ORDER_STATIC, false);
+
+
+
+
+ 1
+
+
+
instance_addSearchOrder(instance, search_order);
+
+
+
+
+ 1
+
+
+
let leq = newConstraintBlob(ConstraintType_CT_LEQSUM);
+
+
+
+
+ 1
+
+
+
let geq = newConstraintBlob(ConstraintType_CT_GEQSUM);
+
+
+
+
+ 1
+
+
+
let ineq = newConstraintBlob(ConstraintType_CT_INEQ);
+
+
+
+
+ 1
+
+
+
let rhs_vars = vec_var_new();
+
+
+
+
+ 1
+
+
+
vec_var_push_back(rhs_vars, constantAsVar(4));
+
+
+
+
+ 1
+
+
+
// leq / geq : [var] [var]
+
+
+
+
+ 1
+
+
+
constraint_addVarList(leq, search_vars as _);
+
+
+
+
+ 1
+
+
+
constraint_addVarList(leq, rhs_vars as _);
+
+
+
+
+ 1
+
+
+
constraint_addVarList(geq, search_vars as _);
+
+
+
+
+ 1
+
+
+
constraint_addVarList(geq, rhs_vars as _);
+
+
+
+
+ 1
+
+
+
// ineq: [var] [var] [const]
+
+
+
+
+ 1
+
+
+
let x_vec = vec_var_new();
+
+
+
+
+ 1
+
+
+
vec_var_push_back(x_vec, x);
+
+
+
+
+ 1
+
+
+
let y_vec = vec_var_new();
+
+
+
+
+ 1
+
+
+
vec_var_push_back(y_vec, y);
+
+
+
+
+ 1
+
+
+
let const_vec = vec_int_new();
+
+
+
+
+ 1
+
+
+
vec_int_push_back(const_vec, -1);
+
+
+
+
+ 1
+
+
+
constraint_addVarList(ineq, x_vec as _);
+
+
+
+
+ 1
+
+
+
constraint_addVarList(ineq, y_vec as _);
+
+
+
+
+ 1
+
+
+
constraint_addConstantList(ineq, const_vec as _);
+
+
+
+
+ 1
+
+
+
instance_addConstraint(instance, leq);
+
+
+
+
+ 1
+
+
+
instance_addConstraint(instance, geq);
+
+
+
+
+ 1
+
+
+
instance_addConstraint(instance, ineq);
+
+
+
+
+ 1
+
+
+
let res = runMinion(options, args, instance, Some(hello_from_rust));
+
+
+
+
+ 1
+
+
+
// does it get this far?
+
+
+
+
+
+
+
+
// test if solutions are correct
+
+
+
+
+ 1
+
+
+
assert_eq!(X_VAL, 1);
+
+
+
+
+ 1
+
+
+
assert_eq!(Y_VAL, 2);
+
+
+
+
+ 1
+
+
+
assert_eq!(Z_VAL, 1);
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/run.rs.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/run.rs.html
new file mode 100644
index 0000000000..177bc93615
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/run.rs.html
@@ -0,0 +1,4130 @@
+
+
+
+
+ Grcov report - run.rs
+
+
+
+
+
+
+
+
+
+
+
+
Functions
+
+ 48.72 %
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
* This Source Code Form is subject to the terms of the Mozilla Public
+
+
+
+
+
+
+
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
+
+
+
+
+
+
+
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+
+
+
+
+
+
+
use std::ffi::CString;
+
+
+
+
+
+
+
+
use crate::{ast::*, error::*, raw_bindings::*, scoped_ptr::Scoped};
+
+
+
+
+
+
+
+
// TODO: allow passing of options.
+
+
+
+
+
+
+
+
/// Callback function used to capture results from minion as they are generated.
+
+
+
+
+
+
+
+
/// Should return `true` if search is to continue, `false` otherwise.
+
+
+
+
+
+
+
+
pub type Callback = fn(Vec<(VarName, Constant)>) -> bool;
+
+
+
+
+ 1
+
+
+
extern "C" fn hello_from_rust2() -> bool {
+
+
+
+
+ 1
+
+
+
pub fn run_minion(model: Model, callback: Callback) -> Result<(), RuntimeError> {
+
+
+
+
+ 1
+
+
+
let options = Scoped::new(newSearchOptions(), |x| searchOptions_free(x as _));
+
+
+
+
+ 1
+
+
+
let args = Scoped::new(newSearchMethod(), |x| searchMethod_free(x as _));
+
+
+
+
+ 1
+
+
+
let instance = Scoped::new(convert_model_to_raw(&model), |x| instance_free(x as _));
+
+
+
+
+ 1
+
+
+
let res = runMinion(options.ptr, args.ptr, instance.ptr, Some(hello_from_rust2));
+
+
+
+
+
+
+
+
x => Err(RuntimeError::from(x)),
+
+
+
+
+
+
+
+
/// Callee owns the returned instance
+
+
+
+
+ 1
+
+
+
unsafe fn convert_model_to_raw(model: &Model) -> *mut ProbSpec_CSPInstance {
+
+
+
+
+ 1
+
+
+
// This is managed in scope by the callee
+
+
+
+
+ 1
+
+
+
let instance = newInstance();
+
+
+
+
+ 1
+
+
+
/*******************************/
+
+
+
+
+ 1
+
+
+
/*******************************/
+
+
+
+
+ 1
+
+
+
* These are all done in the order saved in the SymbolTable.
+
+
+
+
+ 1
+
+
+
let search_vars = Scoped::new(vec_var_new(), |x| vec_var_free(x as _));
+
+
+
+
+ 3
+
+
+
for var_name in model.named_variables.get_variable_order() {
+
+
+
+
+
+
+
+
//TODO: make this return Result
+
+
+
+
+ 3
+
+
+
let c_str = CString::new(var_name.clone()).expect("");
+
+
+
+
+ 3
+
+
+
.get_vartype(var_name.clone())
+
+
+
+
+ 3
+
+
+
let (vartype_raw, domain_low, domain_high) = match vartype {
+
+
+
+
+ 3
+
+
+
VarDomain::Bound(a, b) => (VariableType_VAR_BOUND, a, b),
+
+
+
+
+
+
+
+
_ => panic!("NOT IMPLEMENTED"),
+
+
+
+
+ 3
+
+
+
let var = getVarByName(instance, c_str.as_ptr() as _);
+
+
+
+
+ 3
+
+
+
printMatrix_addVar(instance, var);
+
+
+
+
+ 3
+
+
+
vec_var_push_back(search_vars.ptr, var);
+
+
+
+
+ 1
+
+
+
let search_order = Scoped::new(
+
+
+
+
+ 1
+
+
+
newSearchOrder(search_vars.ptr, VarOrderEnum_ORDER_STATIC, false),
+
+
+
+
+ 1
+
+
+
|x| searchOrder_free(x as _),
+
+
+
+
+ 1
+
+
+
// this and other instance_ functions does not move so my use of ptrs are ok
+
+
+
+
+ 1
+
+
+
// TODO (nd60): document this
+
+
+
+
+ 1
+
+
+
instance_addSearchOrder(instance, search_order.ptr);
+
+
+
+
+
+
+
+
/*********************************/
+
+
+
+
+
+
+
+
/* Add constraints */
+
+
+
+
+
+
+
+
/*********************************/
+
+
+
+
+ 4
+
+
+
for constraint in &model.constraints {
+
+
+
+
+ 3
+
+
+
// 1. get constraint type and create C++ constraint object
+
+
+
+
+ 3
+
+
+
// 2. run through arguments and add them to the constraint
+
+
+
+
+ 3
+
+
+
// 3. add constraint to instance
+
+
+
+
+ 3
+
+
+
let constraint_type = get_constraint_type(constraint);
+
+
+
+
+ 3
+
+
+
let raw_constraint = Scoped::new(newConstraintBlob(constraint_type), |x| {
+
+
+
+
+ 3
+
+
+
constraint_free(x as _)
+
+
+
+
+ 3
+
+
+
constraint_add_args(instance, raw_constraint.ptr, constraint);
+
+
+
+
+ 3
+
+
+
instance_addConstraint(instance, raw_constraint.ptr);
+
+
+
+
+ 3
+
+
+
unsafe fn get_constraint_type(constraint: &Constraint) -> u32 {
+
+
+
+
+ 1
+
+
+
Constraint::SumGeq(_, _) => ConstraintType_CT_GEQSUM,
+
+
+
+
+ 1
+
+
+
Constraint::SumLeq(_, _) => ConstraintType_CT_LEQSUM,
+
+
+
+
+ 1
+
+
+
Constraint::Ineq(_, _, _) => ConstraintType_CT_INEQ,
+
+
+
+
+
+
+
+
#[allow(unreachable_patterns)]
+
+
+
+
+
+
+
+
_ => panic!("NOT IMPLEMENTED"),
+
+
+
+
+ 3
+
+
+
unsafe fn constraint_add_args(
+
+
+
+
+ 3
+
+
+
i: *mut ProbSpec_CSPInstance,
+
+
+
+
+ 3
+
+
+
r_constr: *mut ProbSpec_ConstraintBlob,
+
+
+
+
+ 1
+
+
+
Constraint::SumGeq(lhs_vars, rhs_var) => {
+
+
+
+
+ 1
+
+
+
read_vars(i, r_constr, &lhs_vars);
+
+
+
+
+ 1
+
+
+
read_var(i, r_constr, rhs_var)
+
+
+
+
+ 1
+
+
+
Constraint::SumLeq(lhs_vars, rhs_var) => {
+
+
+
+
+ 1
+
+
+
read_vars(i, r_constr, &lhs_vars);
+
+
+
+
+ 1
+
+
+
read_var(i, r_constr, rhs_var)
+
+
+
+
+ 1
+
+
+
Constraint::Ineq(var1, var2, c) => {
+
+
+
+
+ 1
+
+
+
read_var(i, r_constr, &var1);
+
+
+
+
+ 1
+
+
+
read_var(i, r_constr, &var2);
+
+
+
+
+ 1
+
+
+
read_const(r_constr, c)
+
+
+
+
+
+
+
+
#[allow(unreachable_patterns)]
+
+
+
+
+
+
+
+
_ => panic!("NOT IMPLEMENTED"),
+
+
+
+
+
+
+
+
// DO NOT call manually - this assumes that all needed vars are already in the symbol table.
+
+
+
+
+
+
+
+
// TODO not happy with this just assuming the name is in the symbol table
+
+
+
+
+ 2
+
+
+
instance: *mut ProbSpec_CSPInstance,
+
+
+
+
+ 2
+
+
+
raw_constraint: *mut ProbSpec_ConstraintBlob,
+
+
+
+
+ 2
+
+
+
let raw_vars = Scoped::new(vec_var_new(), |x| vec_var_free(x as _));
+
+
+
+
+ 6
+
+
+
// TODO: could easily break and segfault and die and so on
+
+
+
+
+ 6
+
+
+
let raw_var = match var {
+
+
+
+
+ 6
+
+
+
Var::NameRef(name) => {
+
+
+
+
+ 6
+
+
+
let c_str = CString::new(name.clone()).expect("");
+
+
+
+
+ 6
+
+
+
getVarByName(instance, c_str.as_ptr() as _)
+
+
+
+
+
+
+
+
Var::ConstantAsVar(n) => constantAsVar(*n),
+
+
+
+
+ 6
+
+
+
vec_var_push_back(raw_vars.ptr, raw_var);
+
+
+
+
+ 2
+
+
+
constraint_addVarList(raw_constraint, raw_vars.ptr);
+
+
+
+
+ 4
+
+
+
instance: *mut ProbSpec_CSPInstance,
+
+
+
+
+ 4
+
+
+
raw_constraint: *mut ProbSpec_ConstraintBlob,
+
+
+
+
+ 4
+
+
+
let raw_vars = Scoped::new(vec_var_new(), |x| vec_var_free(x as _));
+
+
+
+
+ 4
+
+
+
let raw_var = match var {
+
+
+
+
+ 2
+
+
+
Var::NameRef(name) => {
+
+
+
+
+ 2
+
+
+
let c_str = CString::new(name.clone()).expect("");
+
+
+
+
+ 2
+
+
+
getVarByName(instance, c_str.as_ptr() as _)
+
+
+
+
+ 2
+
+
+
Var::ConstantAsVar(n) => constantAsVar(*n),
+
+
+
+
+ 4
+
+
+
vec_var_push_back(raw_vars.ptr, raw_var);
+
+
+
+
+ 4
+
+
+
constraint_addVarList(raw_constraint, raw_vars.ptr);
+
+
+
+
+ 1
+
+
+
unsafe fn read_const(raw_constraint: *mut ProbSpec_ConstraintBlob, constant: &Constant) {
+
+
+
+
+ 1
+
+
+
let raw_consts = Scoped::new(vec_int_new(), |x| vec_var_free(x as _));
+
+
+
+
+ 1
+
+
+
let val = match constant {
+
+
+
+
+ 1
+
+
+
Constant::Integer(n) => n,
+
+
+
+
+
+
+
+
_ => panic!("NOT IMPLEMENTED"),
+
+
+
+
+ 1
+
+
+
vec_int_push_back(raw_consts.ptr, *val);
+
+
+
+
+ 1
+
+
+
constraint_addConstantList(raw_constraint, raw_consts.ptr);
+
+
+
+
+
+
+
+
use std::error::Error;
+
+
+
+
+
+
+
+
fn callback(_: Vec<(VarName, Constant)>) -> bool {
+
+
+
+
+ 1
+
+
+
fn basic_ast_test() -> Result<(), RuntimeError> {
+
+
+
+
+ 1
+
+
+
let mut model = Model::new();
+
+
+
+
+ 1
+
+
+
.add_var("x".to_owned(), VarDomain::Bound(1, 3));
+
+
+
+
+ 1
+
+
+
.add_var("y".to_owned(), VarDomain::Bound(2, 4));
+
+
+
+
+ 1
+
+
+
.add_var("z".to_owned(), VarDomain::Bound(1, 5));
+
+
+
+
+ 1
+
+
+
let leq = Constraint::SumLeq(
+
+
+
+
+ 1
+
+
+
Var::NameRef("x".to_owned()),
+
+
+
+
+ 1
+
+
+
Var::NameRef("y".to_owned()),
+
+
+
+
+ 1
+
+
+
Var::NameRef("z".to_owned()),
+
+
+
+
+ 1
+
+
+
Var::ConstantAsVar(4),
+
+
+
+
+ 1
+
+
+
let geq = Constraint::SumGeq(
+
+
+
+
+ 1
+
+
+
Var::NameRef("x".to_owned()),
+
+
+
+
+ 1
+
+
+
Var::NameRef("y".to_owned()),
+
+
+
+
+ 1
+
+
+
Var::NameRef("z".to_owned()),
+
+
+
+
+ 1
+
+
+
Var::ConstantAsVar(4),
+
+
+
+
+ 1
+
+
+
let ineq = Constraint::Ineq(
+
+
+
+
+ 1
+
+
+
Var::NameRef("x".to_owned()),
+
+
+
+
+ 1
+
+
+
Var::NameRef("y".to_owned()),
+
+
+
+
+ 1
+
+
+
Constant::Integer(-1),
+
+
+
+
+ 1
+
+
+
model.constraints.push(leq);
+
+
+
+
+ 1
+
+
+
model.constraints.push(geq);
+
+
+
+
+ 1
+
+
+
model.constraints.push(ineq);
+
+
+
+
+ 1
+
+
+
run_minion(model, callback)
+
+
+
+
+
+
diff --git a/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/scoped_ptr.rs.html b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/scoped_ptr.rs.html
new file mode 100644
index 0000000000..0c7d6917d6
--- /dev/null
+++ b/coverage/edfa8dab93de094f8c1de4e5c57af8203b30c10f/minion/src/scoped_ptr.rs.html
@@ -0,0 +1,594 @@
+
+
+
+
+ Grcov report - scoped_ptr.rs
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
* This Source Code Form is subject to the terms of the Mozilla Public
+
+
+
+
+
+
+
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
+
+
+
+
+
+
+
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
+
+
+
+
+
+
+
+
/// A light scoped wrapper over a raw *mut pointer.
+
+
+
+
+
+
+
+
/// Implements destruction of the pointer when it goes out of scope, but provides no other
+
+
+
+
+
+
+
+
pub struct Scoped<T> {
+
+
+
+
+
+
+
+
destructor: fn(*mut T),
+
+
+
+
+
+
+
+
// https://doc.rust-lang.org/std/alloc/trait.Allocator.html with box (in nightly only)
+
+
+
+
+
+
+
+
// https://docs.rs/scopeguard/latest/scopeguard/
+
+
+
+
+ 15
+
+
+
pub unsafe fn new(ptr: *mut T, destructor: fn(*mut T)) -> Scoped<T> {
+
+
+
+
+ 15
+
+
+
return Scoped { ptr, destructor };
+
+
+
+
+
+
+
+
// https://doc.rust-lang.org/nomicon/destructors.html
+
+
+
+
+
+
+
+
impl<T> Drop for Scoped<T> {
+
+
+
+
+ 15
+
+
+
(self.destructor)(self.ptr);
+
+
+
+
+
+