mod clique_graph;
mod disjoint_set_union;
mod nomerge;
mod parent_child;
use crate::solver::chordal::*;
pub(crate) use clique_graph::*;
pub(crate) use disjoint_set_union::*;
pub(crate) use nomerge::*;
pub(crate) use parent_child::*;
pub(crate) trait MergeStrategy {
fn merge_cliques(&mut self, t: &mut SuperNodeTree) {
self.initialise(t);
while !self.is_done() {
let Some(cand) = self.traverse(t) else {
break; };
let do_merge = self.evaluate(t, cand);
if do_merge {
self.merge_two_cliques(t, cand);
}
self.update_strategy(t, cand, do_merge);
if t.n_cliques == 1 {
break;
}
}
self.post_process_merge(t);
}
fn initialise(&mut self, t: &mut SuperNodeTree);
fn is_done(&self) -> bool;
fn traverse(&mut self, t: &SuperNodeTree) -> Option<(usize, usize)>;
fn evaluate(&mut self, t: &SuperNodeTree, cand: (usize, usize)) -> bool;
fn merge_two_cliques(&self, t: &mut SuperNodeTree, cand: (usize, usize));
fn update_strategy(&mut self, t: &SuperNodeTree, cand: (usize, usize), do_merge: bool);
fn post_process_merge(&mut self, t: &mut SuperNodeTree);
}
#[derive(Clone, Copy, Debug)]
pub(crate) enum EdgeWeightMethod {
Cubic = 1,
}
fn set_union_into_indexed(sets: &mut [VertexSet], c1: usize, c2: usize) {
if c1 == c2 {
return;
}
let (target, source);
if c1 < c2 {
let (head, tail) = sets.split_at_mut(c1 + 1);
target = &mut head[c1];
source = &tail[c2 - c1 - 1];
} else {
let (head, tail) = sets.split_at_mut(c2 + 1);
source = &head[c2];
target = &mut tail[c1 - c2 - 1];
}
for &el in source {
target.insert(el);
}
}