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:
David Wang 2017-03-09 07:42:09 +11:00
parent bae1138501
commit 5bb52b03f2
4 changed files with 45 additions and 3 deletions

View File

@ -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)]

View File

@ -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)]

View File

@ -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;

View File

@ -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>) {