Add simple variable substitution for constraints.
Constraints must now implement the substitution of "from" with "to". The implementations can be sanity checked when we come to build the list of constraints that each variable wakes up. In the future, we would like to make the more general substitution: from -> scale * to + constant.
This commit is contained in:
parent
bae1138501
commit
5bb52b03f2
@ -1,6 +1,7 @@
|
||||
//! All different implementation.
|
||||
|
||||
use std::collections::HashMap;
|
||||
use std::rc::Rc;
|
||||
|
||||
use ::{Constraint,PuzzleSearch,Val,VarToken};
|
||||
|
||||
@ -75,6 +76,19 @@ impl Constraint for AllDifferent {
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn substitute(&self, from: VarToken, to: VarToken)
|
||||
-> Option<Rc<Constraint>> {
|
||||
if let Some(idx) = self.vars.iter().position(|&var| var == from) {
|
||||
if !self.vars.contains(&to) {
|
||||
let mut new_vars = self.vars.clone();
|
||||
new_vars[idx] = to;
|
||||
return Some(Rc::new(AllDifferent{ vars: new_vars }));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! Equality implementation.
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use ::{Constraint,LinExpr,PuzzleSearch,Val,VarToken};
|
||||
use intdiv::IntDiv;
|
||||
|
||||
@ -140,6 +142,16 @@ impl Constraint for Equality {
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn substitute(&self, from: VarToken, to: VarToken)
|
||||
-> Option<Rc<Constraint>> {
|
||||
let mut eqn = self.eqn.clone();
|
||||
if let Some(coef) = eqn.coef.remove(&from) {
|
||||
eqn = eqn + coef * to;
|
||||
}
|
||||
|
||||
Some(Rc::new(Equality{ eqn: eqn }))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,9 +1,11 @@
|
||||
//! Constraint trait, and some common constraints.
|
||||
//!
|
||||
//! Note that all puzzle states visited during the solution search
|
||||
//! share the same set of constraints. This means that you cannot
|
||||
//! store additional information about the state (e.g. caches) in the
|
||||
//! constraint to reuse later.
|
||||
//! share the same set of constraint objects. This means that you
|
||||
//! cannot store additional information about the state (e.g. caches)
|
||||
//! in the constraint to reuse later.
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use ::{PuzzleSearch,Val,VarToken};
|
||||
|
||||
@ -28,6 +30,14 @@ pub trait Constraint {
|
||||
fn on_updated(&self, _search: &mut PuzzleSearch) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
/// Substitute the "from" variable with the "to" variable.
|
||||
///
|
||||
/// Returns a new constraint with all instances of "from" replaced
|
||||
/// with "to", or None if a contradiction was found in the
|
||||
/// process.
|
||||
fn substitute(&self, from: VarToken, to: VarToken)
|
||||
-> Option<Rc<Constraint>>;
|
||||
}
|
||||
|
||||
pub use self::alldifferent::AllDifferent;
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
extern crate puzzle_solver;
|
||||
|
||||
use std::rc::Rc;
|
||||
use puzzle_solver::{Constraint,Puzzle,PuzzleSearch,Solution,Val,VarToken};
|
||||
|
||||
struct NoDiagonal {
|
||||
@ -29,6 +30,11 @@ impl Constraint for NoDiagonal {
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
fn substitute(&self, _from: VarToken, _to: VarToken)
|
||||
-> Option<Rc<Constraint>> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
fn make_queens(n: usize) -> (Puzzle, Vec<VarToken>) {
|
||||
|
Loading…
Reference in New Issue
Block a user