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.
|
//! All different implementation.
|
||||||
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use ::{Constraint,PuzzleSearch,Val,VarToken};
|
use ::{Constraint,PuzzleSearch,Val,VarToken};
|
||||||
|
|
||||||
@ -75,6 +76,19 @@ impl Constraint for AllDifferent {
|
|||||||
|
|
||||||
true
|
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)]
|
#[cfg(test)]
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
//! Equality implementation.
|
//! Equality implementation.
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use ::{Constraint,LinExpr,PuzzleSearch,Val,VarToken};
|
use ::{Constraint,LinExpr,PuzzleSearch,Val,VarToken};
|
||||||
use intdiv::IntDiv;
|
use intdiv::IntDiv;
|
||||||
|
|
||||||
@ -140,6 +142,16 @@ impl Constraint for Equality {
|
|||||||
|
|
||||||
true
|
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)]
|
#[cfg(test)]
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
//! Constraint trait, and some common constraints.
|
//! Constraint trait, and some common constraints.
|
||||||
//!
|
//!
|
||||||
//! Note that all puzzle states visited during the solution search
|
//! Note that all puzzle states visited during the solution search
|
||||||
//! share the same set of constraints. This means that you cannot
|
//! share the same set of constraint objects. This means that you
|
||||||
//! store additional information about the state (e.g. caches) in the
|
//! cannot store additional information about the state (e.g. caches)
|
||||||
//! constraint to reuse later.
|
//! in the constraint to reuse later.
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use ::{PuzzleSearch,Val,VarToken};
|
use ::{PuzzleSearch,Val,VarToken};
|
||||||
|
|
||||||
@ -28,6 +30,14 @@ pub trait Constraint {
|
|||||||
fn on_updated(&self, _search: &mut PuzzleSearch) -> bool {
|
fn on_updated(&self, _search: &mut PuzzleSearch) -> bool {
|
||||||
true
|
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;
|
pub use self::alldifferent::AllDifferent;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
extern crate puzzle_solver;
|
extern crate puzzle_solver;
|
||||||
|
|
||||||
|
use std::rc::Rc;
|
||||||
use puzzle_solver::{Constraint,Puzzle,PuzzleSearch,Solution,Val,VarToken};
|
use puzzle_solver::{Constraint,Puzzle,PuzzleSearch,Solution,Val,VarToken};
|
||||||
|
|
||||||
struct NoDiagonal {
|
struct NoDiagonal {
|
||||||
@ -29,6 +30,11 @@ impl Constraint for NoDiagonal {
|
|||||||
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn substitute(&self, _from: VarToken, _to: VarToken)
|
||||||
|
-> Option<Rc<Constraint>> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_queens(n: usize) -> (Puzzle, Vec<VarToken>) {
|
fn make_queens(n: usize) -> (Puzzle, Vec<VarToken>) {
|
||||||
|
Loading…
Reference in New Issue
Block a user