use crate::hydrostructure::incremental_hydrostructure::IncrementalSafetyTracker;
use traitgraph::implementation::subgraphs::bit_vector_subgraph::BitVectorSubgraph;
use traitgraph::implementation::subgraphs::incremental_subgraph::IncrementalSubgraph;
use traitgraph::interface::subgraph::{MutableSubgraph, SubgraphBase};
use traitgraph::interface::ImmutableGraphContainer;
use traitgraph::interface::{GraphBase, StaticGraph};
pub struct RiverIsNonEmptyTracker<'a, Graph> {
river: BitVectorSubgraph<'a, Graph>,
river_size: usize,
}
impl<'a, Graph: StaticGraph + SubgraphBase> IncrementalSafetyTracker<'a, Graph>
for RiverIsNonEmptyTracker<'a, Graph>
where
<Graph as SubgraphBase>::RootGraph: ImmutableGraphContainer,
{
fn new_with_empty_subgraph(graph: &'a Graph) -> Self {
Self {
river: BitVectorSubgraph::new_empty(graph),
river_size: 0,
}
}
fn clear(&mut self) {
if self.river.node_count() == 0 && self.river.edge_count() == 0 {
return;
}
self.river.clear();
self.river_size = 0;
}
fn reset(&mut self, r_plus: &IncrementalSubgraph<Graph>, r_minus: &IncrementalSubgraph<Graph>) {
self.clear();
for node in r_plus.root().node_indices() {
if !r_plus.contains_node_index(node) && !r_minus.contains_node_index(node) {
self.add_node(node);
}
}
for edge in r_plus.root().edge_indices() {
if !r_plus.contains_edge_index(edge) && !r_minus.contains_edge_index(edge) {
self.add_edge(edge);
}
}
}
fn add_incremental_subgraph_step(
&mut self,
r_plus: &IncrementalSubgraph<Graph>,
_r_minus: &IncrementalSubgraph<Graph>,
) {
for edge in r_plus.new_edges() {
if self.contains_edge(*edge) {
self.remove_edge(*edge);
}
}
for node in r_plus.new_nodes() {
if self.contains_node(*node) {
self.remove_node(*node);
}
}
}
fn remove_incremental_subgraph_step(
&mut self,
r_plus: &IncrementalSubgraph<Graph>,
r_minus: &IncrementalSubgraph<Graph>,
) {
for node in r_minus.new_nodes() {
if !r_plus.contains_node_index(*node) {
self.add_node(*node);
}
}
for edge in r_minus.new_edges() {
if !r_plus.contains_edge_index(*edge) {
self.add_edge(*edge);
}
}
}
fn is_safe(&self, is_forward_univocal: bool, is_backward_univocal: bool) -> bool {
is_forward_univocal || is_backward_univocal || self.river_size > 0
}
fn does_safety_equal_bridge_like() -> bool {
false
}
}
impl<'a, Graph: StaticGraph + SubgraphBase> RiverIsNonEmptyTracker<'a, Graph> {
pub fn contains_node(&self, node: <Graph as GraphBase>::NodeIndex) -> bool {
self.river.contains_node_index(node)
}
pub fn contains_edge(&self, edge: <Graph as GraphBase>::EdgeIndex) -> bool {
self.river.contains_edge_index(edge)
}
pub fn add_node(&mut self, node: <Graph as GraphBase>::NodeIndex) {
debug_assert!(!self.river.contains_node_index(node));
self.river.enable_node(node);
self.river_size += 1;
}
pub fn add_edge(&mut self, edge: <Graph as GraphBase>::EdgeIndex) {
debug_assert!(
!self.river.contains_edge_index(edge),
"Subgraph already contains edge {:?}",
edge
);
self.river.enable_edge(edge);
self.river_size += 1;
}
pub fn remove_node(&mut self, node: <Graph as GraphBase>::NodeIndex) {
debug_assert!(self.river.contains_node_index(node));
self.river.disable_node(node);
self.river_size -= 1;
}
pub fn remove_edge(&mut self, edge: <Graph as GraphBase>::EdgeIndex) {
debug_assert!(self.river.contains_edge_index(edge));
self.river.disable_edge(edge);
self.river_size -= 1;
}
}
impl<'a, Graph: ImmutableGraphContainer + SubgraphBase> std::fmt::Debug
for RiverIsNonEmptyTracker<'a, Graph>
where
Graph::NodeIndex: std::fmt::Debug,
Graph::EdgeIndex: std::fmt::Debug,
<Graph as SubgraphBase>::RootGraph: ImmutableGraphContainer,
{
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(f, "RiverIsNonEmptyTracker[nodes: [")?;
let mut once = true;
for node in self.river.root().node_indices() {
if self.river.contains_node_index(node) {
if once {
once = false;
} else {
write!(f, ", ")?;
}
write!(f, "{:?}", node)?;
}
}
write!(f, "], edges: [")?;
let mut once = true;
for edge in self.river.root().edge_indices() {
if self.river.contains_edge_index(edge) {
if once {
once = false;
} else {
write!(f, ", ")?;
}
write!(f, "{:?}", edge)?;
}
}
write!(f, "]]")
}
}