Add constraint trait.

Each constraint is a little sub-program that attempts to reduce the
search space.  They should only be run as required, i.e. when the
candidates of the variables they use were updated, though this has not
yet been implemented.

Constraints are traits so that puzzles may implement their own
specialised contraints as required.  We have split the trait into an
"on_assigned" call and an "on_updated" call for clarity.  The provided
methods simply return true, indicating no contradiction.
This commit is contained in:
David Wang 2017-02-21 08:17:37 +11:00
parent a5c274d9b7
commit 651cc9f6c7
3 changed files with 41 additions and 1 deletions

28
src/constraint/mod.rs Normal file
View File

@ -0,0 +1,28 @@
//! 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.
use ::{PuzzleSearch,Val,VarToken};
/// Constraint trait.
pub trait Constraint {
/// Applied after a variable has been assigned.
///
/// Returns true if the search should continue with these variable
/// assignments, or false if the constraint found a contradiction.
fn on_assigned(&self, _search: &mut PuzzleSearch, _var: VarToken, _val: Val)
-> bool {
true
}
/// Applied after a variable's candidates has been modified.
///
/// Returns true if the search should continue with these variable
/// assignments, or false if the constraint found a contradiction.
fn on_updated(&self, _search: &mut PuzzleSearch) -> bool {
true
}
}

View File

@ -5,6 +5,7 @@ extern crate bit_set;
use std::ops::Index;
pub use constraint::Constraint;
pub use puzzle::Puzzle;
pub use puzzle::PuzzleSearch;
@ -21,6 +22,8 @@ pub struct Solution {
vars: Vec<Val>,
}
pub mod constraint;
mod puzzle;
impl Index<VarToken> for Solution {

View File

@ -4,7 +4,7 @@ use std::collections::BTreeSet;
use std::ops::Index;
use std::rc::Rc;
use ::{Val,VarToken};
use ::{Constraint,Val,VarToken};
/// A collection of candidates.
#[derive(Clone,Debug,Eq,PartialEq)]
@ -29,6 +29,9 @@ pub struct Puzzle {
// The list of candidates for each variable.
candidates: Vec<Candidates>,
// The list of puzzle constraints.
constraints: Vec<Box<Constraint>>,
}
/// Intermediate puzzle search state.
@ -52,6 +55,7 @@ impl Puzzle {
Puzzle {
num_vars: 0,
candidates: Vec::new(),
constraints: Vec::new(),
}
}
@ -244,6 +248,11 @@ impl Puzzle {
},
}
}
/// Add a constraint to the puzzle solution.
pub fn add_constraint(&mut self, constraint: Box<Constraint>) {
self.constraints.push(constraint);
}
}
/*--------------------------------------------------------------*/