diff --git a/lib/src/adf.rs b/lib/src/adf.rs index dec54b0..e51c274 100644 --- a/lib/src/adf.rs +++ b/lib/src/adf.rs @@ -1066,6 +1066,19 @@ mod test { stable.collect::>(), vec![vec![Term(1), Term(0)], vec![Term(0), Term(1)]] ); + + let stable = adf.stable_nogood(Heuristic::Custom(&|_adf, interpr| { + for (idx, term) in interpr.iter().enumerate() { + if !term.is_truth_value() { + return Some((Var(idx), Term::BOT)); + } + } + None + })); + assert_eq!( + stable.collect::>(), + vec![vec![Term(0), Term(1)], vec![Term(1), Term(0)]] + ); } #[test] diff --git a/lib/src/adf/heuristics.rs b/lib/src/adf/heuristics.rs index 301dc3d..ccfc642 100644 --- a/lib/src/adf/heuristics.rs +++ b/lib/src/adf/heuristics.rs @@ -14,21 +14,35 @@ pub(crate) fn heu_simple(_adf: &Adf, interpr: &[Term]) -> Option<(Var, Term)> { None } -type RetVal = Option<(Var, Term)>; +/// Return value for heuristics. +pub type RetVal = Option<(Var, Term)>; +/// Signature for heuristics functions. +pub type HeuristicFn = dyn Fn(&Adf, &[Term]) -> RetVal; /// Enumeration of all currently implemented heuristics. /// It represents a public view on the crate-view implementations of heuristics. -#[derive(Debug, Clone, Copy)] -pub enum Heuristic { +pub enum Heuristic<'a> { /// Implementation of a simple heuristic. /// This will just take the first not decided variable and maps it value to (`true`)[Term::TOP]. Simple, + /// Allow passing in an externally-defined custom heuristic. + Custom(&'a HeuristicFn), } -impl Heuristic { - pub(crate) fn get_heuristic(&self) -> Box RetVal> { +impl std::fmt::Debug for Heuristic<'_> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Heuristic::Simple => Box::new(heu_simple), + Self::Simple => write!(f, "Simple"), + Self::Custom(_) => f.debug_tuple("Custom function").finish(), + } + } +} + +impl Heuristic<'_> { + pub(crate) fn get_heuristic(&self) -> &(dyn Fn(&Adf, &[Term]) -> RetVal + '_) { + match self { + Heuristic::Simple => &heu_simple, + Self::Custom(f) => f, } } }