Skip to content

Commit

Permalink
Merge pull request #183 from scipopt/remove-hasscipptr-trait
Browse files Browse the repository at this point in the history
Remove HasSCIPPtr trait
  • Loading branch information
mmghannam authored Jan 9, 2025
2 parents 01b9d2a + dad5962 commit 810814e
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 85 deletions.
129 changes: 47 additions & 82 deletions src/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,7 @@ impl Model<ProblemCreated> {
delay: bool,
pricer: Box<dyn Pricer>,
) -> Self {
self.scip()
self.scip
.include_pricer(name, desc, priority, delay, pricer)
.expect("Failed to include pricer at state ProblemCreated");
self
Expand Down Expand Up @@ -391,12 +391,12 @@ impl Model<Solving> {
var_type: VarType,
) -> Rc<Variable> {
let var = self
.scip()
.scip
.create_var_solving(lb, ub, obj, name, var_type)
.expect("Failed to create variable in state ProblemCreated");
let var = Variable {
raw: var,
scip: self.scip().clone(),
scip: self.scip.clone(),
};

Rc::new(var)
Expand All @@ -408,7 +408,7 @@ impl Model<Solving> {
///
/// This method panics if not called in the `Solving` state, it should only be used from plugins implementations.
pub fn focus_node(&self) -> Node {
self.scip().focus_node()
self.scip.focus_node()
}

/// Creates a new child node of the current node and returns it.
Expand All @@ -417,7 +417,7 @@ impl Model<Solving> {
///
/// This method panics if not called from plugins implementations.
pub fn create_child(&mut self) -> Node {
self.scip()
self.scip
.create_child()
.expect("Failed to create child node in state ProblemCreated")
}
Expand All @@ -444,12 +444,12 @@ impl Model<Solving> {
var_type: VarType,
) -> Rc<Variable> {
let var = self
.scip()
.scip
.create_priced_var(lb, ub, obj, name, var_type)
.expect("Failed to create variable in state ProblemCreated");
let var = Variable {
raw: var,
scip: self.scip().clone(),
scip: self.scip.clone(),
};

Rc::new(var)
Expand All @@ -464,9 +464,9 @@ impl Model<Solving> {
/// A reference-counted pointer to the variable.
pub fn var_in_prob(&self, var_prob_id: usize) -> Option<Variable> {
unsafe {
ScipPtr::var_from_id(self.scip().raw, var_prob_id).map(|v| Variable {
ScipPtr::var_from_id(self.scip.raw, var_prob_id).map(|v| Variable {
raw: v,
scip: self.scip().clone(),
scip: self.scip.clone(),
})
}
}
Expand All @@ -480,7 +480,7 @@ impl Model<Solving> {
/// # Returns
/// A boolean indicating whether the row is infeasible from the local bounds.
pub fn add_cut(&mut self, cut: Row, force_cut: bool) -> bool {
self.scip()
self.scip
.add_row(cut, force_cut)
.expect("Failed to add row in state ProblemCreated")
}
Expand Down Expand Up @@ -547,25 +547,25 @@ macro_rules! impl_ModelWithProblem {

/// Returns a vector of all variables in the optimization model.
fn vars(&self) -> Vec<Rc<Variable>> {
let scip_vars = self.scip().vars(false);
let scip_vars = self.scip.vars(false);
scip_vars
.into_iter()
.map(|(_i,v)| Variable {
raw: v,
scip: self.scip().clone(),
scip: self.scip.clone(),
})
.map(Rc::new)
.collect()
}

/// Returns the variable with the given ID, if it exists.
fn var(&self, var_id: VarId) -> Option<Rc<Variable>> {
let vars = self.scip().vars(false);
let vars = self.scip.vars(false);
for (i, v) in vars {
if i == var_id {
return Some(Rc::new(Variable {
raw: v,
scip: self.scip().clone(),
scip: self.scip.clone(),
}));
}
}
Expand All @@ -575,30 +575,30 @@ macro_rules! impl_ModelWithProblem {

/// Returns the number of variables in the optimization model.
fn n_vars(&self) -> usize {
self.scip().n_vars()
self.scip.n_vars()
}

/// Returns the number of constraints in the optimization model.
fn n_conss(&self) -> usize {
self.scip().n_conss()
self.scip.n_conss()
}

/// Returns a vector of all constraints in the optimization model.
fn conss(&self) -> Vec<Rc<Constraint>> {
let scip_conss = self.scip().conss(false);
let scip_conss = self.scip.conss(false);
scip_conss
.into_iter()
.map(|c| Constraint {
raw: c,
scip: self.scip().clone(),
scip: self.scip.clone(),
})
.map(Rc::new)
.collect()
}

/// Writes the optimization model to a file with the given path and extension.
fn write(&self, path: &str, ext: &str) -> Result<(), Retcode> {
self.scip().write(path, ext)?;
self.scip.write(path, ext)?;
Ok(())
}

Expand Down Expand Up @@ -800,11 +800,11 @@ macro_rules! impl_ProblemOrSolving {

/// Creates a new solution initialized to zero.
fn create_sol(&self) -> Solution {
let sol_ptr = self.scip()
let sol_ptr = self.scip
.create_sol()
.expect("Failed to create solution in state ProblemCreated");
Solution {
scip_ptr: self.scip().clone(),
scip_ptr: self.scip.clone(),
raw: sol_ptr,
}
}
Expand All @@ -814,7 +814,7 @@ macro_rules! impl_ProblemOrSolving {
/// # Returns
/// A `Result` indicating whether the solution was added successfully.
fn add_sol(&self, sol: Solution) -> Result<(), SolError> {
let succesfully_stored = self.scip().add_sol(sol).expect("Failed to add solution");
let succesfully_stored = self.scip.add_sol(sol).expect("Failed to add solution");
if succesfully_stored {
Ok(())
} else {
Expand All @@ -834,7 +834,7 @@ macro_rules! impl_ProblemOrSolving {
/// This method panics if the variable cannot be added in the current state, or if the variable is not binary.
fn add_cons_coef_setppc(&mut self, cons: Rc<Constraint>, var: Rc<Variable>) {
assert_eq!(var.var_type(), VarType::Binary);
self.scip()
self.scip
.add_cons_coef_setppc(cons, var)
.expect("Failed to add constraint coefficient in state ProblemCreated");
}
Expand All @@ -852,7 +852,7 @@ macro_rules! impl_ProblemOrSolving {
///
/// This method panics if the coefficient cannot be added in the current state.
fn add_cons_coef(&mut self, cons: Rc<Constraint>, var: Rc<Variable>, coef: f64) {
self.scip()
self.scip
.add_cons_coef(cons, var, coef)
.expect("Failed to add constraint coefficient in state ProblemCreated");
}
Expand Down Expand Up @@ -892,7 +892,7 @@ macro_rules! impl_ProblemOrSolving {
assert_eq!(quad_vars_1.len(), quad_vars_2.len());
assert_eq!(quad_vars_1.len(), quad_coefs.len());
let cons = self
.scip()
.scip
.create_cons_quadratic(
lin_vars,
lin_coefs,
Expand All @@ -907,7 +907,7 @@ macro_rules! impl_ProblemOrSolving {
let cons = Rc::new(
Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
}
);
cons
Expand Down Expand Up @@ -942,12 +942,12 @@ macro_rules! impl_ProblemOrSolving {
) -> Rc<Constraint> {
assert_eq!(vars.len(), coefs.len());
let cons = self
.scip()
.scip
.create_cons(vars, coefs, lhs, rhs, name)
.expect("Failed to create constraint in state ProblemCreated");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand All @@ -969,12 +969,12 @@ macro_rules! impl_ProblemOrSolving {
fn add_cons_set_part(&mut self, vars: Vec<Rc<Variable>>, name: &str) -> Rc<Constraint> {
assert!(vars.iter().all(|v| v.var_type() == VarType::Binary));
let cons = self
.scip()
.scip
.create_cons_set_part(vars, name)
.expect("Failed to add constraint set partition in state ProblemCreated");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand All @@ -996,12 +996,12 @@ macro_rules! impl_ProblemOrSolving {
fn add_cons_set_cover(&mut self, vars: Vec<Rc<Variable>>, name: &str) -> Rc<Constraint> {
assert!(vars.iter().all(|v| v.var_type() == VarType::Binary));
let cons = self
.scip()
.scip
.create_cons_set_cover(vars, name)
.expect("Failed to add constraint set cover in state ProblemCreated");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand All @@ -1023,12 +1023,12 @@ macro_rules! impl_ProblemOrSolving {
fn add_cons_set_pack(&mut self, vars: Vec<Rc<Variable>>, name: &str) -> Rc<Constraint> {
assert!(vars.iter().all(|v| v.var_type() == VarType::Binary));
let cons = self
.scip()
.scip
.create_cons_set_pack(vars, name)
.expect("Failed to add constraint set packing in state ProblemCreated");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand All @@ -1050,12 +1050,12 @@ macro_rules! impl_ProblemOrSolving {
/// This method panics if the constraint cannot be created in the current state.
fn add_cons_cardinality(&mut self, vars: Vec<Rc<Variable>>, cardinality: usize, name: &str) -> Rc<Constraint> {
let cons = self
.scip()
.scip
.create_cons_cardinality(vars, cardinality, name)
.expect("Failed to add cardinality constraint");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand Down Expand Up @@ -1088,12 +1088,12 @@ macro_rules! impl_ProblemOrSolving {
assert_eq!(vars.len(), coefs.len());
assert_eq!(bin_var.var_type(), VarType::Binary);
let cons = self
.scip()
.scip
.create_cons_indicator(bin_var, vars, coefs, rhs, name)
.expect("Failed to create constraint in state ProblemCreated");
let cons = Rc::new( Constraint {
raw: cons,
scip: self.scip().clone(),
scip: self.scip.clone(),
});
cons
}
Expand All @@ -1120,8 +1120,8 @@ macro_rules! impl_WithSolutions {
fn best_sol(&self) -> Option<Solution> {
if self.n_sols() > 0 {
let sol = Solution {
scip_ptr: self.scip().clone(),
raw: self.scip().best_sol().unwrap(),
scip_ptr: self.scip.clone(),
raw: self.scip.best_sol().unwrap(),
};
Some(sol)
} else {
Expand All @@ -1131,7 +1131,7 @@ macro_rules! impl_WithSolutions {

/// Returns the number of solutions found by the optimization model.
fn n_sols(&self) -> usize {
self.scip().n_sols()
self.scip.n_sols()
}

})*
Expand Down Expand Up @@ -1164,27 +1164,27 @@ macro_rules! impl_WithSolvingStats {

/// Returns the objective value of the best solution found by the optimization model.
fn obj_val(&self) -> f64 {
self.scip().obj_val()
self.scip.obj_val()
}

/// Returns the best bound (dualbound) proven so far.
fn best_bound(&self) -> f64 {
self.scip().best_bound()
self.scip.best_bound()
}

/// Returns the number of nodes explored by the optimization model.
fn n_nodes(&self) -> usize {
self.scip().n_nodes()
self.scip.n_nodes()
}

/// Returns the total solving time of the optimization model.
fn solving_time(&self) -> f64 {
self.scip().solving_time()
self.scip.solving_time()
}

/// Returns the number of LP iterations performed by the optimization model.
fn n_lp_iterations(&self) -> usize {
self.scip().n_lp_iterations()
self.scip.n_lp_iterations()
}

})*
Expand All @@ -1193,41 +1193,6 @@ macro_rules! impl_WithSolvingStats {

impl_WithSolvingStats!(for Model<Solved>, Model<Solving>, Model<ProblemCreated>);

/// A trait for optimization models with any state that hold a pointer to the underlying SCIP instance.
pub trait HasScipPtr {
/// Returns a reference-counted pointer to the underlying SCIP instance.
fn scip(&self) -> Rc<ScipPtr>;

/// Returns a pointer to the underlying SCIP instance.
///
/// # Safety
///
/// This method is unsafe because it returns a raw pointer to the underlying SCIP instance.
/// The caller must ensure that the pointer is used safely and correctly.
#[cfg(feature = "raw")]
unsafe fn scip_ptr(&self) -> *mut ffi::SCIP {
self.scip().raw
}
}

impl HasScipPtr for Model<ProblemCreated> {
fn scip(&self) -> Rc<ScipPtr> {
self.scip.clone()
}
}

impl HasScipPtr for Model<Solved> {
fn scip(&self) -> Rc<ScipPtr> {
self.scip.clone()
}
}

impl HasScipPtr for Model<Solving> {
fn scip(&self) -> Rc<ScipPtr> {
self.scip.clone()
}
}

/// Creates a minimal `Model` instance and sets off a lot of SCIP plugins, useful for writing tests.
pub fn minimal_model() -> Model<ProblemCreated> {
Model::default()
Expand Down Expand Up @@ -1634,7 +1599,7 @@ mod tests {
"c2",
);

let scip_ptr = unsafe { model.scip_ptr() };
let scip_ptr = model.scip.raw;
assert!(!scip_ptr.is_null());
}

Expand Down
Loading

0 comments on commit 810814e

Please sign in to comment.