use super::BrancherToUse;
use crate::DefaultBrancher;
use crate::Solver;
use crate::basic_types::SolutionReference;
use crate::branching::Brancher;
use crate::branching::SelectionContext;
use crate::branching::brancher::BrancherEvent;
use crate::branching::branchers::alternating::strategies::AlternatingStrategy;
use crate::engine::predicates::predicate::Predicate;
use crate::engine::variables::DomainId;
use crate::statistics::StatisticLogger;
#[derive(Debug)]
pub struct AlternatingBrancher<OtherBrancher, Strategy> {
other_brancher: OtherBrancher,
default_brancher: DefaultBrancher,
strategy: Strategy,
}
impl<Strategy: AlternatingStrategy, OtherBrancher: Brancher>
AlternatingBrancher<OtherBrancher, Strategy>
{
pub fn new(solver: &Solver, other_brancher: OtherBrancher, strategy: Strategy) -> Self {
Self {
other_brancher,
default_brancher: solver.default_brancher(),
strategy,
}
}
#[cfg(test)]
pub(crate) fn is_using_default_brancher(&self) -> bool {
self.strategy.is_using_default_brancher()
}
}
impl<Strategy: AlternatingStrategy, OtherBrancher: Brancher> Brancher
for AlternatingBrancher<OtherBrancher, Strategy>
{
fn next_decision(&mut self, context: &mut SelectionContext) -> Option<Predicate> {
match self.strategy.next_decision(context) {
BrancherToUse::Default => self.default_brancher.next_decision(context),
BrancherToUse::Other => self.other_brancher.next_decision(context),
}
}
fn log_statistics(&self, statistic_logger: StatisticLogger) {
self.default_brancher
.log_statistics(statistic_logger.clone());
self.other_brancher.log_statistics(statistic_logger);
}
fn on_appearance_in_conflict_predicate(&mut self, predicate: Predicate) {
self.default_brancher
.on_appearance_in_conflict_predicate(predicate);
if !self.strategy.will_always_use_default() {
self.other_brancher
.on_appearance_in_conflict_predicate(predicate)
}
}
fn on_conflict(&mut self) {
self.default_brancher.on_conflict();
if !self.strategy.will_always_use_default() {
self.other_brancher.on_conflict();
}
}
fn on_solution(&mut self, solution: SolutionReference) {
self.strategy.on_solution(solution);
self.default_brancher.on_solution(solution);
if !self.strategy.will_always_use_default() {
self.other_brancher.on_solution(solution);
}
}
fn on_unassign_integer(&mut self, variable: DomainId, value: i32) {
self.default_brancher.on_unassign_integer(variable, value);
if !self.strategy.will_always_use_default() {
self.other_brancher.on_unassign_integer(variable, value)
}
}
fn on_restart(&mut self) {
self.strategy.on_restart();
}
fn is_restart_pointless(&mut self) -> bool {
self.strategy
.is_restart_pointless(&mut self.default_brancher, &mut self.other_brancher)
}
fn on_backtrack(&mut self) {
self.default_brancher.on_backtrack();
if !self.strategy.will_always_use_default() {
self.other_brancher.on_backtrack();
}
}
fn synchronise(&mut self, context: &mut SelectionContext) {
self.default_brancher.synchronise(context);
if !self.strategy.will_always_use_default() {
self.other_brancher.synchronise(context);
}
}
fn subscribe_to_events(&self) -> Vec<BrancherEvent> {
let events = self.strategy.subscribe_to_events();
events
.into_iter()
.chain(self.default_brancher.subscribe_to_events())
.chain(self.other_brancher.subscribe_to_events())
.collect()
}
}