1use core::panic;
85use std::cmp::Ordering;
86use std::fmt::Display;
87use std::hash::Hash;
88use std::num::TryFromIntError;
89use std::ops::{Index, IndexMut};
90
91use ahash::{AHashMap, AHashSet};
92
93use bitvec::prelude::*;
94use bitvec::{slice::IterOnes, vec::BitVec};
95use builder::{HedgeData, HedgeGraphBuilder};
96use hedgevec::{Accessors, SmartEdgeVec};
97use indexmap::IndexSet;
98use involution::{
99 EdgeData, EdgeIndex, EdgeVec, Flow, Hedge, HedgePair, HedgeVec, Involution, InvolutionError,
100 InvolutiveMapping, Orientation,
101};
102
103use itertools::Itertools;
104use nodestore::{NodeStorage, NodeStorageOps, NodeStorageVec};
105use rand::{rngs::SmallRng, Rng, SeedableRng};
106use swap::Swap;
107
108define_indexed_vec!(
109 pub struct NodeIndex; pub struct NodeVec;
118);
119
120impl NodeIndex {
121 pub fn add_data<H>(self, data: H) -> HedgeData<H> {
122 HedgeData {
123 data,
124 node: self,
125 is_in_subgraph: false,
126 }
127 }
128}
129
130impl std::fmt::Display for NodeIndex {
131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132 write!(f, "{}", self.0)
133 }
134}
135
136pub struct PowersetIterator {
146 size: usize,
148 current: usize,
151}
152
153impl PowersetIterator {
154 pub fn new(n_elements: u8) -> Self {
155 PowersetIterator {
156 size: 1 << n_elements,
157 current: 0,
158 }
159 }
160}
161
162impl Iterator for PowersetIterator {
163 type Item = BitVec;
164
165 fn next(&mut self) -> Option<Self::Item> {
166 if self.current < self.size {
167 let out = BitVec::<_, Lsb0>::from_element(self.current);
168 self.current += 1;
169 Some(out)
170 } else {
171 None
172 }
173 }
174}
175pub mod involution;
176
177#[derive(Clone, Debug, Default)]
178#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
179#[cfg_attr(feature = "bincode", derive(bincode::Encode, bincode::Decode))]
180pub struct GVEdgeAttrs {
185 pub label: Option<String>,
187 pub color: Option<String>,
190 pub other: Option<String>,
193}
194
195impl std::fmt::Display for GVEdgeAttrs {
196 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
197 let out = [
198 ("label=", self.label.as_ref()),
199 (
200 "color=",
201 self.color.as_ref().map(|str| format!("\"{str}\"")).as_ref(),
202 ),
203 ("", self.other.as_ref()),
204 ]
205 .iter()
206 .filter_map(|(prefix, x)| x.map(|s| format!("{prefix}{s}")))
207 .join(" ")
208 .to_string();
209 if out.is_empty() {
210 write!(f, "")
211 } else {
212 write!(f, " {out}")
213 }
214 }
215}
216pub mod builder;
217pub mod nodestore;
218pub mod subgraph;
219pub mod swap;
220
221#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
222#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
223#[cfg_attr(
224 feature = "bincode",
225 derive(bincode_trait_derive::Encode, bincode_trait_derive::Decode)
226)]
227pub struct HedgeGraph<E, V, H = NoData, S: NodeStorage<NodeData = V> = NodeStorageVec<V>> {
246 hedge_data: HedgeVec<H>,
247 edge_store: SmartEdgeVec<E>,
251 pub node_store: S,
255}
256
257#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Default)]
258#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
259#[cfg_attr(
260 feature = "bincode",
261 derive(bincode_trait_derive::Encode, bincode_trait_derive::Decode)
262)]
263pub struct NoData {}
264impl Display for NoData {
265 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
266 write!(f, "")
267 }
268}
269
270impl<E, V, H, S: NodeStorage<NodeData = V>> AsRef<Involution> for HedgeGraph<E, V, H, S> {
271 fn as_ref(&self) -> &Involution {
272 self.edge_store.as_ref()
273 }
274}
275
276impl<E, V: Default, H: Default, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
277 pub fn random(nodes: usize, edges: usize, seed: u64) -> HedgeGraph<(), V, H, N>
301 where
302 N::Neighbors: BaseSubgraph + SubGraphOps,
303 {
304 let inv: Involution<()> = Involution::<()>::random(edges, seed);
305
306 let mut rng = SmallRng::seed_from_u64(seed);
307
308 let mut externals = Vec::new();
309 let mut sources = Vec::new();
310 let mut sinks = Vec::new();
311
312 for (i, e) in inv.iter() {
313 let n_h: Hedge = inv.len();
314 let mut nodeid = N::Neighbors::empty(n_h.0);
315 nodeid.add(i);
316 match e {
317 InvolutiveMapping::Identity { .. } => externals.push(nodeid),
318 InvolutiveMapping::Source { .. } => sources.push(nodeid),
319 InvolutiveMapping::Sink { .. } => sinks.push(nodeid),
320 }
321 }
322
323 assert_eq!(sources.len(), sinks.len());
324
325 while !externals.is_empty() {
326 if rng.gen_bool(0.5) {
327 let source_i = rng.gen_range(0..sources.len());
328
329 sources[source_i].union_with(&externals.pop().unwrap());
330 } else {
331 let sink_i = rng.gen_range(0..sinks.len());
332
333 sinks[sink_i].union_with(&externals.pop().unwrap());
334 }
335 }
336
337 let mut lengthone = false;
338
339 while sources.len() + sinks.len() > nodes {
340 if rng.gen_bool(0.5) {
341 if sources.len() <= 1 {
342 if lengthone {
343 break;
344 }
345 lengthone = true;
346 continue;
347 }
348
349 let idx1 = rng.gen_range(0..sources.len());
350 let idx2 = rng.gen_range(0..sources.len() - 1);
351
352 let n_i = sources.swap_remove(idx1);
353 sources[idx2].union_with(&n_i);
354 } else {
355 if sinks.len() <= 1 {
356 if lengthone {
357 break;
358 }
359 lengthone = true;
360 continue;
361 }
362 let idx1 = rng.gen_range(0..sinks.len());
363 let idx2 = rng.gen_range(0..sinks.len() - 1);
364 let n_i = sinks.swap_remove(idx1);
365 sinks[idx2].union_with(&n_i);
366 }
367 }
368
369 let mut hedge_data = HedgeVec::new();
370 let n_h: Hedge = inv.len();
371 for _ in 0..n_h.0 {
372 hedge_data.push(H::default());
373 }
374
375 HedgeGraph {
376 hedge_data,
377 node_store: N::random(&sources, &sinks),
378 edge_store: SmartEdgeVec::new(inv),
379 }
380 }
381}
382
383impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
384 pub fn check(&self) -> Result<(), HedgeGraphError> {
385 for (h, _) in self.iter_hedges() {
387 if h != self.inv(self.inv(h)) {
388 Err(InvolutionError::NonInvolutive(h))?;
389 }
390 }
391
392 self.edge_store.check_hedge_pairs()?;
394 Ok(())
395 }
396
397 pub fn delete_hedges<S: SubGraph<Base = N::Base>>(&mut self, subgraph: &S) {
406 let mut left = Hedge(0);
407 let mut extracted: Hedge = self.len();
408 while left < extracted {
409 if !subgraph.includes(&left) {
410 left.0 += 1;
412 } else {
413 extracted.0 -= 1;
415 if !subgraph.includes(&extracted) {
416 self.hedge_data.swap(left, extracted);
419 left.0 += 1;
420 }
421 }
422 }
423 let _ = self.hedge_data.split_off(left);
424
425 self.edge_store.delete(subgraph);
426 self.node_store.delete(subgraph);
427 }
428
429 pub fn concretize<'a, S: SubGraph>(
445 &'a self,
446 subgraph: &'a S,
447 ) -> HedgeGraph<&'a E, &'a V, &'a H, N::OpStorage<&'a V>> {
448 let mut builder = HedgeGraphBuilder::new();
449
450 let mut node_map = AHashMap::new();
451
452 for (n, _, d) in self.iter_nodes_of(subgraph) {
453 node_map.insert(n, builder.add_node(d));
454 }
455
456 for (pair, _, d) in self.iter_edges_of(subgraph) {
457 match pair {
458 HedgePair::Paired { source, sink } => {
459 let src = node_map[&self.node_id(source)].add_data(&self[source]);
460 let dst = node_map[&self.node_id(sink)].add_data(&self[sink]);
461
462 builder.add_edge(src, dst, d.data, d.orientation);
463 }
464 HedgePair::Unpaired { hedge, flow } => {
465 let src = node_map[&self.node_id(hedge)].add_data(&self[hedge]);
466
467 builder.add_external_edge(src, d.data, d.orientation, flow);
468 }
469 HedgePair::Split {
470 source,
471 sink,
472 split,
473 } => match split {
474 Flow::Sink => {
475 let src = node_map[&self.node_id(sink)].add_data(&self[sink]);
476 builder.add_external_edge(src, d.data, d.orientation, split);
477 }
478 Flow::Source => {
479 let src = node_map[&self.node_id(source)].add_data(&self[source]);
480 builder.add_external_edge(src, d.data, d.orientation, split);
481 }
482 },
483 }
484 }
485
486 builder.build()
487 }
488
489 pub fn extract<O, V2, S: SubGraph<Base = N::Base>>(
514 &mut self,
515 subgraph: &S,
516 split_edge_fn: impl FnMut(EdgeData<&E>) -> EdgeData<O>,
517 internal_data: impl FnMut(EdgeData<E>) -> EdgeData<O>,
518 split_node: impl FnMut(&V) -> V2,
519 owned_node: impl FnMut(V) -> V2,
520 ) -> HedgeGraph<O, V2, H, N::OpStorage<V2>> {
521 let new_edge_store = self
522 .edge_store
523 .extract(subgraph, split_edge_fn, internal_data);
524
525 let mut left = Hedge(0);
526 let mut extracted: Hedge = self.len();
527 while left < extracted {
528 if !subgraph.includes(&left) {
529 left.0 += 1;
531 } else {
532 extracted.0 -= 1;
534 if !subgraph.includes(&extracted) {
535 self.hedge_data.swap(left, extracted);
538 left.0 += 1;
539 }
540 }
541 }
542 let new_hedge_data = self.hedge_data.split_off(left);
543
544 let new_node_store = self.node_store.extract(subgraph, split_node, owned_node);
545 HedgeGraph {
546 hedge_data: new_hedge_data,
547 node_store: new_node_store,
548 edge_store: new_edge_store,
549 }
550 }
551
552 pub fn extract_nodes<O>(
553 &mut self,
554 nodes: impl IntoIterator<Item = NodeIndex>,
555 split_edge_fn: impl FnMut(EdgeData<&E>) -> EdgeData<O>,
556 internal_data: impl FnMut(EdgeData<E>) -> EdgeData<O>,
557 ) -> HedgeGraph<O, V, H, N>
558 where
559 N: NodeStorageOps<Base = BitVec>,
560 {
561 let (extracted, nodes) = self.node_store.extract_nodes(nodes);
562
563 let left = self.hedge_data.partition(|h| !extracted.includes(h));
564
565 let ne_hedge = self.hedge_data.split_off(left);
566
567 let new_edge_store = self
568 .edge_store
569 .extract(&extracted, split_edge_fn, internal_data);
570 HedgeGraph {
571 hedge_data: ne_hedge,
572 node_store: nodes,
573 edge_store: new_edge_store,
574 }
575 }
576 pub fn inv(&self, hedge: Hedge) -> Hedge {
588 self.edge_store.inv(hedge)
589 }
590
591 pub fn split_edge(&mut self, hedge: Hedge, data: EdgeData<E>) -> Result<(), HedgeGraphError> {
608 Ok(self.edge_store.split_edge(hedge, data)?)
609 }
610
611 pub fn join(
634 mut self,
635 other: Self,
636 matching_fn: impl Fn(Flow, EdgeData<&E>, Flow, EdgeData<&E>) -> bool,
637 merge_fn: impl Fn(Flow, EdgeData<E>, Flow, EdgeData<E>) -> (Flow, EdgeData<E>),
638 ) -> Result<Self, HedgeGraphError> {
639 self.hedge_data.extend(other.hedge_data);
640 let mut g = HedgeGraph {
641 hedge_data: self.hedge_data,
642 node_store: self.node_store.extend(other.node_store),
643 edge_store: self
644 .edge_store
645 .join(other.edge_store, matching_fn, merge_fn)?,
646 };
647 g.node_store.check_and_set_nodes()?;
648
649 Ok(g)
650 }
651
652 pub fn join_mut(
667 &mut self,
668 other: Self,
669 matching_fn: impl Fn(Flow, EdgeData<&E>, Flow, EdgeData<&E>) -> bool,
670 merge_fn: impl Fn(Flow, EdgeData<E>, Flow, EdgeData<E>) -> (Flow, EdgeData<E>),
671 ) -> Result<(), HedgeGraphError> {
672 self.node_store.extend_mut(other.node_store);
676 self.edge_store
677 .join_mut(other.edge_store, matching_fn, merge_fn)?;
678
679 self.hedge_data.extend(other.hedge_data);
680
681 self.node_store.check_and_set_nodes()?;
682 Ok(())
683 }
684
685 pub fn sew(
704 &mut self,
705 matching_fn: impl Fn(Flow, EdgeData<&E>, Flow, EdgeData<&E>) -> bool,
706 merge_fn: impl Fn(Flow, EdgeData<E>, Flow, EdgeData<E>) -> (Flow, EdgeData<E>),
707 ) -> Result<(), HedgeGraphError> {
708 self.edge_store.sew(matching_fn, merge_fn)
709 }
710
711 pub fn add_dangling_edge(
727 mut self,
728 source: impl Into<HedgeData<H>>,
729 data: E,
730 flow: Flow,
731 orientation: impl Into<Orientation>,
732 ) -> Result<(Hedge, Self), HedgeGraphError> {
733 let source = source.into();
734
735 self.hedge_data.push(source.data);
736 let (edge_store, hedge) = self.edge_store.add_dangling_edge(data, flow, orientation);
737 let mut g = HedgeGraph {
738 hedge_data: self.hedge_data,
739 edge_store,
740 node_store: self.node_store.add_dangling_edge(source.node)?,
741 };
742
743 g.node_store.check_and_set_nodes()?;
744
745 Ok((hedge, g))
746 }
747
748 pub fn add_pair(
766 mut self,
767 source: impl Into<HedgeData<H>>,
768 sink: impl Into<HedgeData<H>>,
769 data: E,
770 orientation: impl Into<Orientation>,
771 ) -> Result<(Hedge, Hedge, Self), HedgeGraphError> {
772 let source = source.into();
773 let sink = sink.into();
774 self.hedge_data.push(source.data);
775 self.hedge_data.push(sink.data);
776 let (edge_store, sourceh, sinkh) = self.edge_store.add_paired(data, orientation);
777 let mut g = HedgeGraph {
778 hedge_data: self.hedge_data,
779 edge_store,
780 node_store: self
781 .node_store
782 .add_dangling_edge(source.node)?
783 .add_dangling_edge(sink.node)?,
784 };
785
786 g.node_store.check_and_set_nodes()?;
787
788 Ok((sourceh, sinkh, g))
789 }
790
791 pub fn is_connected<S: SubGraph>(&self, subgraph: &S) -> bool {
807 let n_edges = subgraph.nedges(self);
808 if let Some(start) = subgraph.included_iter().next() {
809 SimpleTraversalTree::depth_first_traverse(self, subgraph, &self.node_id(start), None)
810 .unwrap()
811 .covers(subgraph)
812 .nedges(self)
813 == n_edges
814 } else {
815 true
816 }
817 }
818
819 pub fn cut_branches(&self, subgraph: &mut HedgeNode) {
833 let nodes = AHashSet::<NodeIndex>::from_iter(
834 subgraph
835 .internal_graph
836 .included_iter()
837 .map(|i| self.node_id(i)),
838 );
839 self.remove_externals(subgraph);
840
841 let mut has_branch = true;
842 while has_branch {
843 has_branch = false;
844
845 for n in &nodes {
846 let int = self.sub_iter_crown(*n, subgraph).collect::<Vec<_>>();
847 let first = int.first();
848 let next = int.get(1);
849
850 if let Some(first) = first {
851 if next.is_none() {
852 subgraph.internal_graph.filter.set(first.0, false);
853 subgraph
854 .internal_graph
855 .filter
856 .set(self.inv(*first).0, false);
857 has_branch = true;
858 }
859 }
860 }
861 }
862
863 self.nesting_node_fix(subgraph);
864 }
865
866 }
870
871impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
873 pub fn internal_crown<S: SubGraph>(&self, subgraph: &S) -> S::Base
887 where
888 S::Base: ModifySubgraph<HedgePair>,
889 {
890 let mut crown = S::Base::empty(self.n_hedges());
891
892 for (p, _, _) in self.iter_edges_of(subgraph) {
893 if !p.is_paired() {
894 crown.add(p)
895 }
896 }
897
898 crown
899 }
900
901 pub fn full_crown<S: SubGraph>(&self, subgraph: &S) -> S::Base
918 where
919 S::Base: ModifySubgraph<Hedge>,
920 {
921 let mut crown = S::Base::empty(self.n_hedges());
922
923 for (_, n, _) in self.iter_nodes_of(subgraph) {
924 for h in n {
925 let invh = self.inv(h);
926 if h == invh || !subgraph.includes(&invh) {
927 crown.add(h);
928 }
929 }
930 }
931
932 crown
933 }
934
935 pub fn paired_filter_from_pos(&self, pos: &[Hedge]) -> BitVec {
936 let mut filter = bitvec![usize, Lsb0; 0; self.n_hedges()];
937
938 for &i in pos {
939 filter.set(i.0, true);
940 filter.set(self.inv(i).0, true);
941 }
942
943 filter
944 }
945
946 pub fn external_filter(&self) -> BitVec {
952 let mut filter = bitvec![usize, Lsb0; 0; self.n_hedges()];
953
954 for (i, _, _) in self.iter_edges() {
955 if i.is_unpaired() {
956 filter.set(i.any_hedge().0, true);
957 }
958 }
959
960 filter
961 }
962
963 pub fn full_filter(&self) -> BitVec {
968 bitvec![usize, Lsb0; 1; self.n_hedges()]
969 }
970
971 pub fn full(&self) -> FullOrEmpty {
973 FullOrEmpty::full(self.n_hedges())
974 }
975
976 pub fn empty(&self) -> FullOrEmpty {
978 FullOrEmpty::empty(self.n_hedges())
979 }
980
981 pub fn clean_subgraph(&self, filter: BitVec) -> InternalSubGraph {
992 InternalSubGraph::cleaned_filter_pessimist(filter, self)
993 }
994
995 pub fn full_node(&self) -> HedgeNode {
999 self.nesting_node_from_subgraph(self.full_graph())
1000 }
1001
1002 pub fn full_graph(&self) -> InternalSubGraph {
1005 InternalSubGraph::cleaned_filter_optimist(self.full_filter(), self)
1006 }
1007
1008 pub fn empty_subgraph<S: SubGraph>(&self) -> S {
1016 S::empty(self.n_hedges())
1017 }
1018
1019 pub fn from_filter<S: BaseSubgraph>(&self, filter: impl FnMut(&E) -> bool) -> S {
1031 S::from_filter(self, filter)
1032 }
1033
1034 pub fn nesting_node_from_subgraph(&self, internal_graph: InternalSubGraph) -> HedgeNode {
1047 let mut hairs = bitvec![usize, Lsb0; 0; self.n_hedges()];
1048
1049 if !internal_graph.valid::<E, V, H, N>(self) {
1050 panic!("Invalid subgraph")
1051 }
1052
1053 for i in internal_graph.included_iter() {
1054 hairs.union_with_iter(self.neighbors(i));
1055 }
1056
1057 HedgeNode {
1058 hairs: !(!hairs | &internal_graph.filter),
1059 internal_graph,
1060 }
1061 }
1062
1063 pub fn remove_internal_hedges(&self, subgraph: &BitVec) -> BitVec {
1064 let mut hairs = subgraph.clone();
1065 for i in subgraph.included_iter() {
1066 if subgraph.includes(&self.inv(i)) {
1067 hairs.set(i.0, false);
1068 hairs.set(self.inv(i).0, false);
1069 }
1070 }
1071 hairs
1072 }
1073
1074 pub(crate) fn split_hairs_and_internal_hedges(
1075 &self,
1076 mut subgraph: BitVec,
1077 ) -> (BitVec, InternalSubGraph) {
1078 let mut internal: InternalSubGraph = self.empty_subgraph();
1079 for i in subgraph.included_iter() {
1080 let invh = self.inv(i);
1081 if subgraph.includes(&invh) {
1082 internal.filter.set(i.0, true);
1083 internal.filter.set(invh.0, true);
1084 }
1085 }
1086 for i in internal.filter.included_iter() {
1087 subgraph.set(i.0, false);
1088 }
1089 (subgraph, internal)
1090 }
1091
1092 fn nesting_node_fix(&self, node: &mut HedgeNode) {
1101 let mut externalhedges = bitvec![usize, Lsb0; 0; self.n_hedges()];
1102
1103 for i in node.internal_graph.filter.included_iter() {
1104 externalhedges.union_with_iter(self.neighbors(i));
1105 }
1106
1107 node.hairs = !(!externalhedges | &node.internal_graph.filter);
1108 }
1109
1110 fn remove_externals(&self, subgraph: &mut HedgeNode) {
1111 let externals = self.external_filter();
1112
1113 subgraph.internal_graph.filter &= !externals;
1114 }
1115}
1116
1117impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
1119 pub fn count_internal_edges<S: SubGraph>(&self, subgraph: &S) -> usize {
1130 let mut internal_edge_count = 0;
1131 for hedge_index in subgraph.included_iter() {
1133 let inv_hedge_index = self.inv(hedge_index);
1134
1135 if subgraph.includes(&inv_hedge_index) {
1137 if hedge_index < inv_hedge_index {
1139 internal_edge_count += 1;
1140 }
1141 }
1142 }
1143 internal_edge_count
1144 }
1145
1146 pub fn n_hedges(&self) -> usize {
1148 let n_h: Hedge = self.len();
1149 n_h.0
1150 }
1151
1152 pub fn n_edges(&self) -> usize {
1153 let n_e: EdgeIndex = self.len();
1154 n_e.0
1155 }
1156
1157 pub fn n_nodes(&self) -> usize {
1159 let n_n: NodeIndex = self.len();
1160 n_n.0
1161 }
1162
1163 pub fn n_externals(&self) -> usize {
1165 self.edge_store.n_dangling()
1166 }
1167
1168 pub fn n_internals(&self) -> usize {
1171 self.edge_store.n_paired()
1172 }
1173
1174 pub fn number_of_nodes_in_subgraph<S: SubGraph>(&self, subgraph: &S) -> usize {
1187 self.iter_nodes_of(subgraph).count()
1188 }
1189
1190 pub fn node_degrees_in_subgraph(
1202 &self,
1203 subgraph: &InternalSubGraph,
1204 ) -> AHashMap<NodeIndex, usize> {
1205 let mut degrees = AHashMap::new();
1206
1207 for (_, node, _) in self.iter_nodes_of(subgraph) {
1208 let node_pos = self.id_from_crown(node).unwrap();
1209
1210 let incident_edges =
1212 BitVec::from_hedge_iter(self.sub_iter_crown(node_pos, subgraph), subgraph.size());
1213 let degree = incident_edges.count_ones();
1214
1215 degrees.insert(node_pos, degree);
1216 }
1217
1218 degrees
1219 }
1220}
1221
1222pub trait EdgeAccessors<Index> {
1223 fn orientation(&self, index: Index) -> Orientation;
1224
1225 fn set_orientation(&mut self, index: Index, orientation: Orientation);
1226}
1227
1228impl<E, V, H, N: NodeStorageOps<NodeData = V>> EdgeAccessors<Hedge> for HedgeGraph<E, V, H, N> {
1229 fn orientation(&self, index: Hedge) -> Orientation {
1230 self.edge_store.orientation(index)
1231 }
1232
1233 fn set_orientation(&mut self, index: Hedge, orientation: Orientation) {
1234 self.edge_store.set_orientation(index, orientation);
1235 }
1236}
1237
1238impl<E, V, H, N: NodeStorageOps<NodeData = V>> EdgeAccessors<HedgePair> for HedgeGraph<E, V, H, N> {
1239 fn orientation(&self, index: HedgePair) -> Orientation {
1240 self.edge_store.orientation(index)
1241 }
1242
1243 fn set_orientation(&mut self, index: HedgePair, orientation: Orientation) {
1244 self.edge_store.set_orientation(index, orientation);
1245 }
1246}
1247
1248impl<E, V, H, N: NodeStorageOps<NodeData = V>> EdgeAccessors<EdgeIndex> for HedgeGraph<E, V, H, N> {
1249 fn orientation(&self, index: EdgeIndex) -> Orientation {
1250 self.edge_store.orientation(index)
1251 }
1252
1253 fn set_orientation(&mut self, index: EdgeIndex, orientation: Orientation) {
1254 self.edge_store.set_orientation(index, orientation);
1255 }
1256}
1257
1258impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
1260 pub fn owned_neighbors<S: SubGraph>(&self, subgraph: &S, pos: Hedge) -> BitVec {
1262 subgraph.hairs(self.neighbors(pos))
1263 }
1264
1265 pub fn connected_neighbors<S: SubGraph>(&self, subgraph: &S, pos: Hedge) -> Option<BitVec> {
1266 Some(subgraph.hairs(self.involved_node_crown(pos)?))
1267 }
1268 pub fn get_edge_data(&self, edge: Hedge) -> &E {
1269 &self[self[&edge]]
1270 }
1271
1272 pub fn hedge_pair(&self, hedge: Hedge) -> HedgePair {
1273 self.edge_store[&self.edge_store[&hedge]].1
1274 }
1275
1276 pub fn get_edge_data_full(&self, hedge: Hedge) -> EdgeData<&E> {
1277 let orientation = self.edge_store.orientation(hedge);
1278 EdgeData::new(&self[self[&hedge]], orientation)
1279 }
1280
1281 pub fn flow(&self, hedge: Hedge) -> Flow {
1283 self.edge_store.flow(hedge)
1284 }
1285
1286 pub fn superficial_hedge_orientation(&self, hedge: Hedge) -> Option<Flow> {
1287 self.edge_store.superficial_hedge_orientation(hedge)
1288 }
1289
1290 pub fn underlying_hedge_orientation(&self, hedge: Hedge) -> Flow {
1291 self.edge_store.underlying_hedge_orientation(hedge)
1292 }
1293
1294 pub fn neighbors(&self, hedge: Hedge) -> N::NeighborsIter<'_> {
1295 self.iter_crown(self.node_id(hedge))
1296 }
1297
1298 pub fn iter_crown(&self, id: NodeIndex) -> N::NeighborsIter<'_> {
1299 self.node_store.get_neighbor_iterator(id)
1300 }
1301
1302 pub fn sub_iter_crown<'a, S: SubGraph>(
1303 &'a self,
1304 id: NodeIndex,
1305 subgraph: &'a S,
1306 ) -> impl Iterator<Item = Hedge> + 'a {
1307 self.iter_crown(id).filter(|i| subgraph.includes(i))
1308 }
1309
1310 pub fn id_from_crown<'a>(&'a self, mut neighbors: N::NeighborsIter<'a>) -> Option<NodeIndex> {
1311 let e = neighbors.next()?;
1312 Some(self.node_id(e))
1313 }
1314
1315 pub fn involved_node_crown(&self, hedge: Hedge) -> Option<N::NeighborsIter<'_>> {
1316 self.involved_node_id(hedge).map(|id| self.iter_crown(id))
1317 }
1318
1319 pub fn involved_node_id(&self, hedge: Hedge) -> Option<NodeIndex> {
1320 let invh = self.inv(hedge);
1321 if invh == hedge {
1322 return None;
1323 }
1324 Some(self.node_id(invh))
1325 }
1326
1327 pub fn node_id(&self, hedge: Hedge) -> NodeIndex {
1328 self.node_store.node_id_ref(hedge)
1329 }
1330
1331 pub fn is_self_loop(&self, hedge: Hedge) -> bool {
1332 !self.is_dangling(hedge) && self.node_id(hedge) == self.node_id(self.inv(hedge))
1333 }
1334
1335 pub fn is_dangling(&self, hedge: Hedge) -> bool {
1336 self.inv(hedge) == hedge
1337 }
1338
1339 pub fn nodes<S: SubGraph>(&self, subgraph: &S) -> Vec<NodeIndex> {
1341 let mut nodes = IndexSet::new();
1342 for i in subgraph.included_iter() {
1343 let node = self.node_id(i);
1344 nodes.insert(node);
1345 }
1346
1347 nodes.into_iter().collect()
1348 }
1349
1350 pub fn set_flow(&mut self, hedge: Hedge, flow: Flow) {
1351 self.edge_store.set_flow(hedge, flow);
1352 }
1353
1354 pub fn forget_identification_history(&mut self) -> NodeVec<V> {
1356 self.node_store.forget_identification_history()
1357 }
1358
1359 pub fn identify_nodes(&mut self, nodes: &[NodeIndex], node_data_merge: V) -> NodeIndex {
1361 self.node_store.identify_nodes(nodes, node_data_merge)
1362 }
1363
1364 pub fn contract_subgraph<S: SubGraph<Base = N::Base>>(
1368 &mut self,
1369 subgraph: &S,
1370 node_data_merge: V,
1371 ) {
1372 let nodes: Vec<_> = self.iter_nodes_of(subgraph).map(|(a, _, _)| a).collect();
1373
1374 self.identify_nodes(&nodes, node_data_merge);
1375 self.forget_identification_history();
1376 self.delete_hedges(subgraph);
1377 }
1378
1379 pub fn identify_nodes_without_self_edges<S>(
1381 &mut self,
1382 nodes: &[NodeIndex],
1383 node_data_merge: V,
1384 ) -> (NodeIndex, S)
1385 where
1386 S: ModifySubgraph<Hedge> + SubGraph,
1387 {
1388 let mut self_edges: S = self.empty_subgraph();
1389 for n in nodes {
1390 for h in self.iter_crown(*n) {
1391 if self.is_self_loop(h) {
1392 self_edges.add(h);
1393 }
1394 }
1395 }
1396 let n = self.node_store.identify_nodes(nodes, node_data_merge);
1397
1398 for h in self.iter_crown(n) {
1399 if self.is_self_loop(h) {
1400 if self_edges.includes(&h) {
1401 self_edges.sub(h);
1402 } else {
1403 self_edges.add(h);
1404 }
1405 }
1406 }
1407
1408 (n, self_edges)
1411 }
1412
1413 pub fn edges<S: SubGraph>(&self, subgraph: &S) -> Vec<EdgeIndex> {
1416 self.iter_edges_of(subgraph).map(|(_, i, _)| i).collect()
1417 }
1418}
1419
1420pub enum NodeKind<Data> {
1421 Internal(Data),
1422 External { data: Data, flow: Flow },
1423}
1424
1425pub enum DanglingMatcher<Data> {
1426 Actual { hedge: Hedge, data: Data },
1427 Internal { data: Data },
1428 Saturator { hedge: Hedge },
1429}
1430
1431impl<Data> DanglingMatcher<Data> {
1432 fn new(pair: HedgePair, data: Data) -> Self {
1433 match pair {
1434 HedgePair::Unpaired { hedge, .. } => DanglingMatcher::Actual { hedge, data },
1435 HedgePair::Paired { .. } => DanglingMatcher::Internal { data },
1436 _ => panic!("Split"),
1437 }
1438 }
1439 pub fn matches(&self, other: &Self) -> bool {
1440 match (self, other) {
1441 (
1442 DanglingMatcher::Actual { hedge: h1, .. },
1443 DanglingMatcher::Saturator { hedge: h2 },
1444 ) => h1 == h2,
1445 _ => false,
1446 }
1447 }
1448
1449 pub fn unwrap(self) -> Data {
1450 match self {
1451 DanglingMatcher::Actual { data, .. } => data,
1452 DanglingMatcher::Internal { data } => data,
1453 DanglingMatcher::Saturator { .. } => panic!("Cannot unwrap a saturator"),
1454 }
1455 }
1456}
1457
1458impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
1460 pub fn saturate_dangling<V2>(
1461 self,
1462 node_map: impl FnMut(&Involution, NodeIndex, V) -> V2,
1463 mut dangling_map: impl FnMut(&Involution, &N, Hedge, Flow, EdgeData<&E>) -> (V2, H),
1464 ) -> HedgeGraph<E, V2, H, <<N as NodeStorageOps>::OpStorage<V2> as NodeStorageOps>::OpStorage<V2>>
1465 {
1466 let ext = self.external_filter();
1467
1468 let mut saturator = HedgeGraphBuilder::new();
1469 for i in ext.included_iter() {
1470 let flow = self.flow(i);
1471 let d = &self[[&i]];
1472 let orientation = self.orientation(i);
1473 let (new_node_data, h) = dangling_map(
1474 self.edge_store.as_ref(),
1475 &self.node_store,
1476 i,
1477 flow,
1478 EdgeData::new(d, orientation),
1479 );
1480
1481 let n = saturator.add_node(new_node_data).add_data(h);
1482
1483 saturator.add_external_edge(
1484 n,
1485 DanglingMatcher::Saturator { hedge: i },
1486 orientation,
1487 -flow,
1488 );
1489 }
1490
1491 let saturator = saturator.build();
1492 let new_graph = self.map(
1493 node_map,
1494 |_, _, p, _, e| e.map(|d| DanglingMatcher::new(p, d)),
1495 |_, h| h,
1496 );
1497 new_graph
1498 .join(
1499 saturator,
1500 |_, dl, _, dr| dl.data.matches(dr.data),
1501 |fl, dl, _, _| (fl, dl),
1502 )
1503 .unwrap()
1504 .map(|_, _, v| v, |_, _, _, _, e| e.map(|d| d.unwrap()), |_, h| h)
1505 }
1506
1507 pub fn map_data_ref<'a, E2, V2, H2>(
1508 &'a self,
1509 node_map: impl FnMut(&'a Self, N::NeighborsIter<'a>, &'a V) -> V2,
1510 edge_map: impl FnMut(&'a Self, EdgeIndex, HedgePair, EdgeData<&'a E>) -> EdgeData<E2>,
1511 mut hedge_map: impl FnMut(Hedge, &'a H) -> H2,
1512 ) -> HedgeGraph<E2, V2, H2, N::OpStorage<V2>> {
1513 HedgeGraph {
1514 hedge_data: self
1515 .hedge_data
1516 .iter()
1517 .map(|(i, a)| hedge_map(i, a))
1518 .collect(),
1519 node_store: self.node_store.map_data_ref_graph(self, node_map),
1520 edge_store: self.edge_store.map_data_ref(self, edge_map),
1521 }
1522 }
1523
1524 pub fn to_ref(&self) -> HedgeGraph<&E, &V, &H, N::OpStorage<&V>> {
1525 self.map_data_ref(|_, _, v| v, |_, _, _, e| e, |_, h| h)
1526 }
1527
1528 pub fn map_data_ref_mut<'a, E2, V2, H2>(
1529 &'a mut self,
1530 node_map: impl FnMut(N::NeighborsIter<'a>, &'a mut V) -> V2,
1531 edge_map: impl FnMut(EdgeIndex, HedgePair, EdgeData<&'a mut E>) -> EdgeData<E2>,
1532 hedge_map: impl FnMut((Hedge, &'a H)) -> H2,
1533 ) -> HedgeGraph<E2, V2, H2, N::OpStorage<V2>> {
1534 HedgeGraph {
1535 hedge_data: self.hedge_data.iter().map(hedge_map).collect(),
1536 node_store: self.node_store.map_data_ref_mut_graph(node_map),
1537 edge_store: self.edge_store.map_data_ref_mut(edge_map),
1538 }
1539 }
1540
1541 pub fn map_data_ref_result<'a, E2, V2, H2, Er>(
1542 &'a self,
1543 node_map: impl FnMut(&'a Self, N::NeighborsIter<'a>, &'a V) -> Result<V2, Er>,
1544 edge_map: impl FnMut(
1545 &'a Self,
1546 EdgeIndex,
1547 HedgePair,
1548 EdgeData<&'a E>,
1549 ) -> Result<EdgeData<E2>, Er>,
1550 hedge_map: impl FnMut((Hedge, &'a H)) -> Result<H2, Er>,
1551 ) -> Result<HedgeGraph<E2, V2, H2, N::OpStorage<V2>>, Er> {
1552 let hedge_data = self
1553 .hedge_data
1554 .iter()
1555 .map(hedge_map)
1556 .collect::<Result<HedgeVec<_>, _>>()?;
1557 Ok(HedgeGraph {
1558 hedge_data,
1559 node_store: self.node_store.map_data_ref_graph_result(self, node_map)?,
1560 edge_store: self.edge_store.map_data_ref_result(self, edge_map)?,
1561 })
1562 }
1563
1564 pub fn just_structure(&self) -> HedgeGraph<(), (), (), N::OpStorage<()>> {
1565 self.map_data_ref(|_, _, _| (), |_, _, _, d| d.map(|_| ()), |_, _| ())
1566 }
1567
1568 pub fn map_nodes_ref<'a, V2>(
1569 &'a self,
1570 f: impl FnMut(&'a Self, N::NeighborsIter<'a>, &'a V) -> V2,
1571 ) -> HedgeGraph<&'a E, V2, &'a H, N::OpStorage<V2>> {
1572 HedgeGraph {
1573 hedge_data: self.hedge_data.iter().collect(),
1574 node_store: self.node_store.map_data_ref_graph(self, f),
1575 edge_store: self.edge_store.map_data_ref(self, &|_, _, _, e| e),
1576 }
1577 }
1578 pub fn map<E2, V2, H2>(
1579 self,
1580 f: impl FnMut(&Involution, NodeIndex, V) -> V2,
1581 g: impl FnMut(&Involution, &N, HedgePair, EdgeIndex, EdgeData<E>) -> EdgeData<E2>,
1582 mut h: impl FnMut(Hedge, H) -> H2,
1583 ) -> HedgeGraph<E2, V2, H2, N::OpStorage<V2>> {
1584 let edge_store = self.edge_store.map_data(&self.node_store, g);
1585 HedgeGraph {
1586 hedge_data: self
1587 .hedge_data
1588 .into_iter()
1589 .map(|(heg, i)| h(heg, i))
1590 .collect(),
1591 node_store: self.node_store.map_data_graph(edge_store.as_ref(), f),
1592 edge_store,
1593 }
1594 }
1595 pub fn map_result<E2, V2, H2, Err>(
1596 self,
1597 f: impl FnMut(&Involution, NodeIndex, V) -> Result<V2, Err>,
1598 g: impl FnMut(&Involution, &N, HedgePair, EdgeIndex, EdgeData<E>) -> Result<EdgeData<E2>, Err>,
1599 mut h: impl FnMut(Hedge, H) -> Result<H2, Err>,
1600 ) -> Result<HedgeGraph<E2, V2, H2, N::OpStorage<V2>>, Err> {
1601 let edge_store = self.edge_store.map_data_result(&self.node_store, g)?;
1602 Ok(HedgeGraph {
1603 hedge_data: self
1604 .hedge_data
1605 .into_iter()
1606 .map(|(heg, i)| h(heg, i))
1607 .collect::<Result<HedgeVec<_>, Err>>()?,
1608 node_store: self
1609 .node_store
1610 .map_data_graph_result(edge_store.as_ref(), f)?,
1611 edge_store,
1612 })
1613 }
1614 pub fn new_smart_hedgevec<T>(
1615 &self,
1616 f: &impl Fn(HedgePair, EdgeData<&E>) -> EdgeData<T>,
1617 ) -> SmartEdgeVec<T> {
1618 self.edge_store.map(f)
1619 }
1620
1621 pub fn new_edgevec<T>(&self, f: impl FnMut(&E, EdgeIndex, &HedgePair) -> T) -> EdgeVec<T> {
1622 self.edge_store.new_edgevec(f)
1623 }
1624
1625 pub fn new_nodevec<'a, T>(
1626 &'a self,
1627 f: impl FnMut(NodeIndex, N::NeighborsIter<'a>, &'a V) -> T,
1628 ) -> NodeVec<T> {
1629 self.node_store.new_nodevec(f)
1630 }
1631
1632 pub fn new_hedgevec<T>(&self, mut f: impl FnMut(Hedge, &H) -> T) -> HedgeVec<T> {
1633 self.hedge_data.iter().map(|(i, h)| f(i, h)).collect()
1634 }
1635
1636 pub fn new_edgevec_from_iter<T, I: IntoIterator<Item = T>>(
1637 &self,
1638 iter: I,
1639 ) -> Result<EdgeVec<T>, HedgeGraphError> {
1640 self.edge_store.new_edgevec_from_iter(iter)
1641 }
1642}
1643
1644impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
1646 fn non_cut_edges_impl(
1647 &self,
1648 connected_components: usize,
1649 cyclotomatic_number: usize,
1650 start: Hedge,
1651 current: &mut BitVec,
1652 set: &mut AHashSet<BitVec>,
1653 ) {
1654 if current.count_ones() > 2 * cyclotomatic_number {
1655 return;
1656 }
1657
1658 let complement = current.complement(self);
1659
1660 if current.count_ones() > 0
1661 && self.count_connected_components(&complement) == connected_components
1662 && complement.covers(self) == self.full_filter()
1663 {
1664 set.insert(current.clone());
1666 }
1667
1668 for i in (start.0..self.n_hedges()).map(Hedge) {
1669 let j = self.inv(i);
1670 if i > j {
1671 current.set(i.0, true);
1672 current.set(j.0, true);
1673 self.non_cut_edges_impl(
1674 connected_components,
1675 cyclotomatic_number,
1676 Hedge(i.0 + 1),
1677 current,
1678 set,
1679 );
1680 current.set(i.0, false);
1681 current.set(j.0, false);
1682 }
1683 }
1684 }
1685
1686 pub fn non_cut_edges(&self) -> AHashSet<BitVec> {
1688 let connected_components = self.count_connected_components(&self.full_filter());
1689
1690 let cyclotomatic_number = self.cyclotomatic_number(&self.full_node().internal_graph);
1691
1692 let mut current = self.empty_subgraph::<BitVec>();
1693 let mut set = AHashSet::new();
1694
1695 self.non_cut_edges_impl(
1696 connected_components,
1697 cyclotomatic_number,
1698 Hedge(0),
1699 &mut current,
1700 &mut set,
1701 );
1702
1703 set
1704 }
1705
1706 pub fn non_bridges(&self) -> BitVec {
1714 let (c, _) = self.cycle_basis();
1715 let mut cycle_cover: BitVec = self.empty_subgraph();
1716 for cycle in c {
1717 cycle_cover.union_with(&cycle.filter);
1718 }
1719
1720 cycle_cover
1721 }
1722
1723 pub fn bridges(&self) -> BitVec {
1724 self.non_bridges().complement(self)
1725 }
1726
1727 pub fn combine_to_single_hedgenode(&self, source: &[NodeIndex]) -> HedgeNode {
1728 let s: BitVec =
1729 source
1730 .iter()
1731 .map(|a| self.iter_crown(*a))
1732 .fold(self.empty_subgraph(), |mut acc, e| {
1733 acc.union_with_iter(e);
1734 acc
1735 });
1736
1737 let (hairs, internal_graph) = self.split_hairs_and_internal_hedges(s);
1738
1739 HedgeNode {
1740 internal_graph,
1741 hairs,
1742 }
1743 }
1744
1745 pub fn all_cuts_from_ids(
1746 &self,
1747 source: &[NodeIndex],
1748 target: &[NodeIndex],
1749 ) -> Vec<(BitVec, OrientedCut, BitVec)>
1750 where
1751 N: NodeStorageOps,
1752 {
1753 let source = self.combine_to_single_hedgenode(source);
1754 let target = self.combine_to_single_hedgenode(target);
1755 self.all_cuts(source, target)
1756 }
1757
1758 pub fn tadpoles(&self, externals: &[NodeIndex]) -> Vec<BitVec> {
1759 let mut identified: HedgeGraph<(), (), (), N::OpStorage<()>> = self.just_structure();
1760
1761 let n = identified.identify_nodes(externals, ());
1762 let hairs = identified.iter_crown(n).next().unwrap();
1763
1764 let non_bridges = identified.non_bridges();
1765 identified
1766 .connected_components(&non_bridges)
1767 .into_iter()
1768 .filter_map(|mut a| {
1769 if !a.includes(&hairs) {
1770 let full = a.covers(self);
1771
1772 for i in full.included_iter() {
1773 a.set(i.0, true);
1774 a.set(self.inv(i).0, true);
1775 }
1776 Some(a)
1777 } else {
1778 None
1779 }
1780 })
1781 .collect()
1782 }
1783
1784 pub fn all_cuts(
1785 &self,
1786 source: HedgeNode,
1787 target: HedgeNode,
1788 ) -> Vec<(BitVec, OrientedCut, BitVec)>
1789 where
1790 N: NodeStorageOps,
1791 {
1792 let full_source = source.internal_and_hairs();
1796 let full_target = target.internal_and_hairs();
1797 let s_connectivity = self.count_connected_components(&full_source);
1798
1799 let t_connectivity = self.count_connected_components(&full_target);
1800
1801 let augmented: HedgeGraph<(), (), (), N::OpStorage<()>> = self.just_structure();
1802 let s_nodes = self
1803 .iter_nodes_of(&source)
1804 .map(|a| self.id_from_crown(a.1).unwrap())
1805 .collect::<Vec<_>>();
1806 let t_nodes = self
1807 .iter_nodes_of(&target)
1808 .map(|a| self.id_from_crown(a.1).unwrap())
1809 .collect::<Vec<_>>();
1810
1811 let t_node = t_nodes[0];
1812 let s_node = s_nodes[0];
1813
1814 let augmented = s_nodes.iter().fold(augmented, |aug, n| {
1815 let (_, _, augmented) = aug.add_pair(*n, t_node, (), false).unwrap();
1816 augmented
1817 });
1818
1819 let augmented = t_nodes.iter().fold(augmented, |aug, n| {
1820 let (_, _, augmented) = aug.add_pair(s_node, *n, (), false).unwrap();
1821 augmented
1822 });
1823
1824 let mut non_bridges = augmented.non_bridges();
1825
1826 for _ in &s_nodes {
1827 non_bridges.pop();
1828 non_bridges.pop();
1829 }
1830 for _ in &t_nodes {
1831 non_bridges.pop();
1832 non_bridges.pop();
1833 }
1834
1835 non_bridges.union_with(&source.hairs);
1838 non_bridges.union_with(&target.hairs);
1839
1840 let mut regions = AHashSet::new();
1843 self.all_s_t_cuts_impl(
1844 &non_bridges,
1845 s_connectivity,
1846 source,
1847 &target,
1848 t_connectivity,
1849 &mut regions,
1850 );
1851
1852 let mut cuts = vec![];
1853 let bridges = non_bridges.complement(self);
1854
1855 for mut r in regions.drain() {
1856 let cut = OrientedCut::from_underlying_coerce(r.hairs.clone(), self).unwrap();
1866 r.add_all_hairs(self);
1867 let mut s_side_covers = r.internal_and_hairs();
1868 for i in bridges.included_iter() {
1869 if s_side_covers.includes(&self.inv(i)) {
1870 s_side_covers.set(i.0, true);
1871 }
1872 }
1873
1874 let t_side_covers = s_side_covers.complement(self);
1875
1876 cuts.push((s_side_covers, cut, t_side_covers));
1882 }
1883
1884 cuts
1885 }
1886
1887 pub fn all_s_t_cuts_impl<S: SubGraph<Base = BitVec>>(
1888 &self,
1889 subgraph: &S,
1890 s_connectivity: usize,
1891 s: HedgeNode, t: &HedgeNode,
1893 t_connectivity: usize,
1894 regions: &mut AHashSet<HedgeNode>,
1895 ) {
1896 let hairy = s.internal_graph.filter.union(&s.hairs);
1900 let mut complement = hairy.complement(self);
1901 complement.intersect_with(subgraph.included());
1902 if !complement.includes(&t.hairs) {
1903 return;
1904 }
1905
1906 let t_count = self.count_connected_components(&complement);
1907 let s_count = self.count_connected_components(&hairy);
1908
1909 if t_count <= t_connectivity && s_count <= s_connectivity && regions.get(&s).is_none() {
1910 for h in s.hairs.included_iter() {
1911 let invh = self.inv(h);
1912
1913 if invh != h && !t.hairs.includes(&invh) && subgraph.includes(&invh) {
1914 let mut new_node = s.clone();
1915
1916 new_node.hairs.union_with_iter(self.neighbors(invh));
1917 new_node.hairs.intersect_with(subgraph.included());
1918
1919 new_node.fix(self);
1920 self.all_s_t_cuts_impl(
1921 subgraph,
1922 s_connectivity,
1923 new_node,
1924 t,
1925 t_connectivity,
1926 regions,
1927 );
1928 }
1929 }
1930 regions.insert(s);
1931 }
1932 }
1933}
1934
1935impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
1937 pub fn all_spanning_trees<S: SubGraph>(&self, subgraph: &S) -> Vec<S::Base>
1940 where
1941 for<'a> N::OpStorage<&'a V>: Clone,
1942 S::Base: SubGraph<Base = S::Base>
1943 + SubGraphOps
1944 + Clone
1945 + ModifySubgraph<HedgePair>
1946 + ModifySubgraph<Hedge>,
1947 {
1948 let ref_self = self.to_ref();
1949
1950 let exts = self.internal_crown(subgraph);
1951
1952 if let Some((root_node, _, _)) = self.iter_nodes_of(subgraph).next() {
1953 let tree = SimpleTraversalTree::depth_first_traverse(self, subgraph, &root_node, None)
1954 .unwrap();
1955 let mut nodes = tree.node_order();
1956 nodes.remove(0);
1957
1958 let mut included = subgraph.included().clone();
1959 for h in exts.included_iter() {
1960 included.sub(h);
1961 }
1962
1963 ref_self.contract_edge_for_spanning(nodes, included)
1964 } else {
1965 vec![]
1966 }
1967 }
1968
1969 fn contract_edge_for_spanning<S>(self, mut nodes: Vec<NodeIndex>, mut subgraph: S) -> Vec<S>
1970 where
1971 V: Clone,
1972 E: Clone,
1973 H: Clone,
1974 N: Clone,
1975 S: SubGraphOps
1976 + Clone
1977 + SubGraph<Base = S>
1978 + ModifySubgraph<HedgePair>
1979 + ModifySubgraph<Hedge>,
1980 {
1981 let mut trees = vec![];
1982 if let Some(node) = nodes.pop() {
1983 for h in self.iter_crown(node) {
1984 if subgraph.includes(&h) && subgraph.includes(&self.inv(h)) {
1986 if let Some(new_node) = self.involved_node_id(h) {
1988 let node_data_merge = self[node].clone();
1992 let mut new_self = self.clone();
1993
1994 let (mapped_node, parallel): (_, S::Base) = new_self
1996 .identify_nodes_without_self_edges(&[node, new_node], node_data_merge);
1997
1998 let mapped_nodes = nodes
1999 .iter()
2000 .map(|a| {
2001 if *a == new_node || *a == node {
2002 mapped_node
2003 } else {
2004 *a
2005 }
2006 })
2007 .collect();
2008
2009 for v in new_self
2010 .contract_edge_for_spanning(mapped_nodes, subgraph.subtract(¶llel))
2011 {
2013 for (p, _, _) in self.iter_edges_of(¶llel.intersection(&subgraph)) {
2015 let mut with_p = v.clone();
2016 with_p.add(p);
2017 trees.push(with_p);
2018 }
2019 }
2020
2021 subgraph.subtract_with(¶llel);
2023 }
2024 }
2025 }
2026 } else {
2027 trees.push(self.empty_subgraph())
2028 }
2029
2030 trees
2031 }
2032}
2033
2034impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
2036 pub fn cyclotomatic_number<S: SubGraph>(&self, subgraph: &S) -> usize {
2037 let n_hedges = self.count_internal_edges(subgraph);
2038 let n_nodes = self.number_of_nodes_in_subgraph(subgraph);
2040 let n_components = self.count_connected_components(subgraph);
2042
2043 n_hedges + n_components - n_nodes
2044 }
2045
2046 pub fn cycle_basis(&self) -> (Vec<Cycle>, SimpleTraversalTree) {
2047 self.paton_cycle_basis(&self.full_graph(), &self.node_id(Hedge(0)), None)
2048 .unwrap()
2049 }
2050
2051 pub fn order_basis(&self, basis: &[HedgeNode]) -> Vec<Vec<InternalSubGraph>> {
2052 let mut seen = vec![basis[0].internal_graph.clone()];
2053 let mut partitions = vec![seen.clone()];
2054
2055 for cycle in basis.iter() {
2056 if seen
2057 .iter()
2058 .any(|p| !p.empty_intersection(&cycle.internal_graph))
2059 {
2060 partitions
2061 .last_mut()
2062 .unwrap()
2063 .push(cycle.internal_graph.clone());
2064 } else {
2065 for p in partitions.last().unwrap() {
2066 seen.push(p.clone());
2067 }
2068 partitions.push(vec![cycle.internal_graph.clone()]);
2069 }
2070 }
2071
2072 partitions
2073 }
2074
2075 pub fn all_cycles(&self) -> Vec<Cycle> {
2076 Cycle::all_sum_powerset_filter_map(&self.cycle_basis().0, &|mut c| {
2077 if c.is_circuit(self) {
2078 c.loop_count = Some(1);
2079 Some(c)
2080 } else {
2081 None
2082 }
2083 })
2084 .unwrap()
2085 .into_iter()
2086 .collect()
2087 }
2088
2089 pub fn all_cycle_sym_diffs(&self) -> Result<Vec<InternalSubGraph>, TryFromIntError> {
2090 Cycle::all_sum_powerset_filter_map(&self.cycle_basis().0, &Some)
2091 .map(|a| a.into_iter().map(|c| c.internal_graph(self)).collect())
2092 }
2093
2094 pub fn all_cycle_unions(&self) -> AHashSet<InternalSubGraph> {
2095 InternalSubGraph::all_unions_iterative(&self.all_cycle_sym_diffs().unwrap())
2096 }
2097 pub fn paton_count_loops(
2098 &self,
2099 subgraph: &InternalSubGraph,
2100 start: &NodeIndex,
2101 ) -> Result<usize, HedgeGraphError> {
2102 let tree = SimpleTraversalTree::depth_first_traverse(self, subgraph, start, None)?;
2103
2104 let cuts = subgraph.subtract(&tree.tree_subgraph(self));
2105 Ok(self.edge_store.n_internals(&cuts))
2106 }
2107
2108 pub fn paton_cycle_basis<S: SubGraph<Base = BitVec>>(
2109 &self,
2110 subgraph: &S,
2111 start: &NodeIndex,
2112 included_hedge: Option<Hedge>,
2113 ) -> Result<(Vec<Cycle>, SimpleTraversalTree), HedgeGraphError> {
2114 let tree =
2115 SimpleTraversalTree::depth_first_traverse(self, subgraph, start, included_hedge)?;
2116
2117 let cuts = subgraph.included().subtract(&tree.tree_subgraph);
2118
2119 let mut cycle_basis = Vec::new();
2120
2121 for c in cuts.included_iter() {
2122 if c > self.inv(c) && subgraph.includes(&self.inv(c)) {
2123 cycle_basis.push(tree.get_cycle(c, self).unwrap());
2124 }
2125 }
2126
2127 Ok((cycle_basis, tree))
2128 }
2129
2130 pub fn all_spinneys_with_basis(&self, basis: &[&InternalSubGraph]) -> AHashSet<HedgeNode> {
2131 let mut spinneys = AHashSet::new();
2132 let mut base_cycle: InternalSubGraph = self.empty_subgraph();
2133
2134 for cycle in basis {
2135 base_cycle.sym_diff_with(cycle);
2136 }
2137
2138 spinneys.insert(self.nesting_node_from_subgraph(base_cycle.clone()));
2139
2140 if basis.len() == 1 {
2141 return spinneys;
2142 }
2143
2144 for i in 0..basis.len() {
2145 for s in self.all_spinneys_with_basis(
2146 &basis
2147 .iter()
2148 .enumerate()
2149 .filter_map(|(j, s)| if j != i { Some(*s) } else { None })
2150 .collect_vec(),
2151 ) {
2152 spinneys
2153 .insert(self.nesting_node_from_subgraph(s.internal_graph.union(&base_cycle)));
2154 spinneys.insert(s);
2155 }
2156 }
2157
2158 spinneys
2159 }
2160
2161 pub fn all_spinneys_rec(&self, spinneys: &mut AHashSet<HedgeNode>, cycle_sums: Vec<HedgeNode>) {
2162 let _len = spinneys.len();
2163
2164 let mut pset = PowersetIterator::new(cycle_sums.len() as u8);
2165
2166 pset.next(); for (ci, cj) in cycle_sums.iter().tuple_combinations() {
2169 let _union = ci.internal_graph.union(&cj.internal_graph);
2170
2171 }
2173 }
2174
2175 pub fn all_spinneys(
2176 &self,
2177 ) -> AHashMap<InternalSubGraph, Vec<(InternalSubGraph, Option<InternalSubGraph>)>> {
2178 let basis_cycles = self.cycle_basis().0;
2179
2180 let mut all_combinations = PowersetIterator::new(basis_cycles.len() as u8);
2181 all_combinations.next(); let mut spinneys: AHashMap<
2184 InternalSubGraph,
2185 Vec<(InternalSubGraph, Option<InternalSubGraph>)>,
2186 > = AHashMap::new();
2187
2188 let mut cycles: Vec<InternalSubGraph> = Vec::new();
2189 for p in all_combinations {
2190 let mut base_cycle: InternalSubGraph = self.empty_subgraph();
2191
2192 for i in p.iter_ones() {
2193 base_cycle.sym_diff_with(&basis_cycles[i].clone().internal_graph(self));
2194 }
2195
2196 cycles.push(base_cycle);
2197 }
2198
2199 for (ci, cj) in cycles.iter().tuple_combinations() {
2200 let union = ci.union(cj);
2201
2202 if let Some(v) = spinneys.get_mut(&union) {
2203 v.push((ci.clone(), Some(cj.clone())));
2204 } else {
2205 spinneys.insert(union, vec![(ci.clone(), Some(cj.clone()))]);
2206 }
2207 }
2208
2209 for c in cycles {
2210 spinneys.insert(c.clone(), vec![(c.clone(), None)]);
2211 }
2212 spinneys
2213 }
2214
2215 pub fn all_spinneys_alt(&self) -> AHashSet<InternalSubGraph> {
2216 let mut spinneys = AHashSet::new();
2217 let cycles = self.all_cycles();
2218
2219 let mut pset = PowersetIterator::new(cycles.len() as u8);
2220 pset.next(); for p in pset {
2223 let mut union: InternalSubGraph = self.empty_subgraph();
2224
2225 for i in p.iter_ones() {
2226 union.union_with(&cycles[i].clone().internal_graph(self));
2227 }
2228
2229 spinneys.insert(union);
2230 }
2231
2232 for c in cycles {
2233 spinneys.insert(c.internal_graph(self));
2234 }
2235 spinneys
2236 }
2237}
2238
2239impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
2241 pub fn count_connected_components<S: SubGraph>(&self, subgraph: &S) -> usize {
2242 self.connected_components(subgraph).len()
2243 }
2244
2245 pub fn connected_components<S: SubGraph>(&self, subgraph: &S) -> Vec<BitVec> {
2246 let mut visited_edges: BitVec = self.empty_subgraph();
2247
2248 let mut components = vec![];
2249
2250 for hedge_index in subgraph.included_iter() {
2252 if !visited_edges.includes(&hedge_index) {
2253 let root_node = self.node_id(hedge_index);
2257 let reachable_edges =
2258 SimpleTraversalTree::depth_first_traverse(self, subgraph, &root_node, None)
2259 .unwrap()
2260 .covers(subgraph);
2261
2262 visited_edges.union_with(&reachable_edges);
2263
2264 components.push(reachable_edges);
2265 }
2266 }
2267 components
2268 }
2269 pub fn align_underlying_to_superficial(&mut self) {
2270 self.edge_store.align_underlying_to_superficial();
2271 }
2272
2273 pub fn align_underlying_to_tree<P: ForestNodeStore<NodeData = ()>>(
2278 &mut self,
2279 tree: &SimpleTraversalTree<P>,
2280 ) {
2281 for (h, tt, i) in tree.iter_hedges() {
2282 match tt {
2284 tree::TTRoot::Root => {
2285 if i.is_some() {
2286 self.edge_store.set_flow(h, Flow::Sink);
2287 } else {
2288 self.edge_store.set_flow(h, Flow::Source);
2289 }
2290 }
2291 tree::TTRoot::Child(_) => {
2292 if let Some(root_pointer) = i {
2293 if root_pointer == h {
2294 self.edge_store.set_flow(h, Flow::Source);
2295 } else {
2296 self.edge_store.set_flow(h, Flow::Sink);
2297 }
2298 } else {
2299 let current_node_id = tree.node_id(h);
2300 let involved_node_id = tree.node_id(self.inv(h));
2301
2302 let order =
2303 tree.tree_order(current_node_id, involved_node_id, &self.edge_store);
2304 match order {
2305 Some(Ordering::Equal) => {
2306 }
2308 Some(Ordering::Less) => {
2309 self.edge_store.set_flow(h, Flow::Sink);
2311 }
2312 Some(Ordering::Greater) => {
2313 self.edge_store.set_flow(h, Flow::Source);
2314 }
2315 None => {}
2316 }
2317 }
2318 }
2319 tree::TTRoot::None => {}
2320 }
2321 }
2322 }
2323
2324 pub fn align_superficial_to_tree<P: ForestNodeStore<NodeData = ()>>(
2328 &mut self,
2329 tree: &SimpleTraversalTree<P>,
2330 ) {
2331 for (h, tt, i) in tree.iter_hedges() {
2332 match tt {
2333 tree::TTRoot::Root => {
2334 if i.is_some() {
2335 let flow = self.edge_store.flow(h);
2336 match flow {
2337 Flow::Source => {
2338 self.edge_store.set_orientation(h, Orientation::Reversed);
2339 }
2340 Flow::Sink => {
2341 self.edge_store.set_orientation(h, Orientation::Default);
2342 }
2343 }
2344 } else {
2345 self.edge_store.set_orientation(h, Orientation::Undirected);
2346 }
2347 }
2348 tree::TTRoot::Child(_) => {
2349 if let Some(root_pointer) = i {
2350 let flow = self.edge_store.flow(h);
2351 if root_pointer == h {
2352 match flow {
2353 Flow::Source => {
2354 self.edge_store.set_orientation(h, Orientation::Default);
2355 }
2356 Flow::Sink => {
2357 self.edge_store.set_orientation(h, Orientation::Reversed);
2358 }
2359 }
2360 } else {
2361 match flow {
2362 Flow::Source => {
2363 self.edge_store.set_orientation(h, Orientation::Reversed);
2364 }
2365 Flow::Sink => {
2366 self.edge_store.set_orientation(h, Orientation::Default);
2367 }
2368 }
2369
2370 }
2372 } else {
2373 self.edge_store.set_orientation(h, Orientation::Undirected);
2374 }
2375 }
2376 tree::TTRoot::None => {}
2377 }
2378 }
2379 }
2380
2381 }
2411
2412impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
2414 pub fn iter_hedges(&self) -> impl Iterator<Item = (Hedge, &H)> {
2415 self.hedge_data.iter()
2416 }
2417
2418 pub fn iter_nodes(&self) -> impl Iterator<Item = (NodeIndex, N::NeighborsIter<'_>, &V)> {
2420 self.node_store.iter_nodes()
2421 }
2422
2423 pub fn iter_nodes_mut(
2424 &mut self,
2425 ) -> impl Iterator<Item = (NodeIndex, N::NeighborsIter<'_>, &mut V)> {
2426 self.node_store.iter_nodes_mut()
2427 }
2428
2429 pub fn iter_node_ids(&self) -> impl Iterator<Item = NodeIndex> + '_ {
2430 self.node_store.iter_node_id()
2431 }
2432
2433 pub fn iter_edge_ids_of<'a, S: SubGraph>(
2434 &'a self,
2435 subgraph: &'a S,
2436 ) -> EdgeIter<'a, E, V, H, S, N, S::BaseIter<'a>> {
2437 EdgeIter::new(self, subgraph)
2438 }
2439
2440 pub fn iter_edges_of<'a, S: SubGraph>(
2441 &'a self,
2442 subgraph: &'a S,
2443 ) -> impl Iterator<Item = (HedgePair, EdgeIndex, EdgeData<&'a E>)> + 'a {
2444 self.edge_store.iter_edges_of(subgraph)
2445 }
2446
2447 pub fn iter_edges(&self) -> impl Iterator<Item = (HedgePair, EdgeIndex, EdgeData<&E>)> {
2448 self.edge_store.iter_edges()
2449 }
2450
2451 pub fn iter_nodes_of<'a, S: SubGraph>(
2452 &'a self,
2453 subgraph: &'a S,
2454 ) -> impl Iterator<Item = (NodeIndex, N::NeighborsIter<'a>, &'a V)>
2455 where
2456 N::NeighborsIter<'a>: Clone,
2457 {
2458 NodeIterator {
2459 graph: self,
2460 edges: subgraph.included_iter(),
2461 seen: bitvec![usize, Lsb0; 0; self.n_nodes()],
2462 }
2463 }
2464}
2465
2466impl<E, V, H, N: NodeStorageOps<NodeData = V>> HedgeGraph<E, V, H, N> {
2468 pub fn dot_impl_fmt<S: SubGraph, Str1: AsRef<str>>(
2469 &self,
2470 writer: &mut impl std::fmt::Write,
2471 subgraph: &S,
2472 graph_info: Str1,
2473 hedge_attr: &impl Fn(&H) -> Option<String>,
2474 edge_attr: &impl Fn(&E) -> Option<String>,
2475 node_attr: &impl Fn(&V) -> Option<String>,
2476 ) -> Result<(), std::fmt::Error> {
2477 subgraph.dot_fmt(writer, self, graph_info, hedge_attr, edge_attr, node_attr)
2478 }
2479 pub fn dot_impl_io<S: SubGraph, Str1: AsRef<str>>(
2480 &self,
2481 writer: &mut impl std::io::Write,
2482 subgraph: &S,
2483 graph_info: Str1,
2484 hedge_attr: &impl Fn(&H) -> Option<String>,
2485 edge_attr: &impl Fn(&E) -> Option<String>,
2486 node_attr: &impl Fn(&V) -> Option<String>,
2487 ) -> Result<(), std::io::Error> {
2488 subgraph.dot_io(writer, self, graph_info, hedge_attr, edge_attr, node_attr)
2489 }
2490
2491 pub fn dot_impl<S: SubGraph, Str1: AsRef<str>>(
2492 &self,
2493 subgraph: &S,
2494 graph_info: Str1,
2495 hedge_attr: &impl Fn(&H) -> Option<String>,
2496 edge_attr: &impl Fn(&E) -> Option<String>,
2497 node_attr: &impl Fn(&V) -> Option<String>,
2498 ) -> String {
2499 let mut output = String::new();
2500 subgraph
2501 .dot_fmt(
2502 &mut output,
2503 self,
2504 graph_info,
2505 hedge_attr,
2506 edge_attr,
2507 node_attr,
2508 )
2509 .unwrap();
2510 output
2511 }
2512
2513 pub fn dot<S: SubGraph>(&self, node_as_graph: &S) -> String {
2514 let mut output = String::new();
2515 self.dot_impl_fmt(
2516 &mut output,
2517 node_as_graph,
2518 "start=2;\n",
2519 &|_| None,
2520 &|_| None,
2521 &|_| None,
2522 )
2523 .unwrap();
2524 output
2525 }
2526
2527 pub fn dot_display<S: SubGraph>(&self, node_as_graph: &S) -> String
2528 where
2529 E: Display,
2530 V: Display,
2531 H: Display,
2532 {
2533 let mut output = String::new();
2534 self.dot_impl_fmt(
2535 &mut output,
2536 node_as_graph,
2537 "start=2;\n",
2538 &|h| Some(format!("{h}")),
2539 &|a| Some(format!("{a}")),
2540 &|v| Some(format!("{v}")),
2541 )
2542 .unwrap();
2543 output
2544 }
2545
2546 pub fn dot_label<S: SubGraph>(&self, node_as_graph: &S) -> String
2547 where
2548 E: Display,
2549 V: Display,
2550 {
2551 let mut output = String::new();
2552 self.dot_impl_fmt(
2553 &mut output,
2554 node_as_graph,
2555 "start=2;\n",
2556 &|_| None,
2557 &|a| Some(format!("label=\"{a}\"")),
2558 &|v| Some(format!("label=\"{v}\"")),
2559 )
2560 .unwrap();
2561 output
2562 }
2563
2564 pub fn base_dot(&self) -> String {
2565 self.dot(&self.full_filter())
2566 }
2567}
2568
2569impl<E, V, H, N: NodeStorage<NodeData = V>> Index<Hedge> for HedgeGraph<E, V, H, N> {
2570 type Output = H;
2571 fn index(&self, index: Hedge) -> &Self::Output {
2572 &self.hedge_data[index]
2573 }
2574}
2575
2576impl<E, V, H, N: NodeStorage<NodeData = V>> IndexMut<Hedge> for HedgeGraph<E, V, H, N> {
2577 fn index_mut(&mut self, index: Hedge) -> &mut Self::Output {
2578 &mut self.hedge_data[index]
2579 }
2580}
2581
2582impl<E, V, H, N: NodeStorage<NodeData = V>> Index<&Hedge> for HedgeGraph<E, V, H, N> {
2583 type Output = EdgeIndex;
2584 fn index(&self, index: &Hedge) -> &Self::Output {
2585 &self.edge_store[index]
2586 }
2587}
2588
2589impl<E, V, H, N: NodeStorage<NodeData = V>> Index<[&Hedge; 1]> for HedgeGraph<E, V, H, N> {
2590 type Output = E;
2591 fn index(&self, index: [&Hedge; 1]) -> &Self::Output {
2592 &self[self[index[0]]]
2593 }
2594}
2595
2596impl<E, V, H, N: NodeStorage<NodeData = V>> IndexMut<[&Hedge; 1]> for HedgeGraph<E, V, H, N> {
2597 fn index_mut(&mut self, index: [&Hedge; 1]) -> &mut Self::Output {
2599 let edgeid = self[index[0]];
2600 &mut self[edgeid]
2601 }
2602}
2603
2604impl<E, V, H, N: NodeStorageOps<NodeData = V>> Index<NodeIndex> for HedgeGraph<E, V, H, N> {
2605 type Output = V;
2606 fn index(&self, index: NodeIndex) -> &Self::Output {
2607 self.node_store.get_node_data(index)
2608 }
2609}
2610impl<E, V, H, N: NodeStorageOps<NodeData = V>> IndexMut<NodeIndex> for HedgeGraph<E, V, H, N> {
2611 fn index_mut(&mut self, index: NodeIndex) -> &mut Self::Output {
2612 self.node_store.get_node_data_mut(index)
2613 }
2614}
2615impl<E, V, H, N: NodeStorage<NodeData = V>> Index<EdgeIndex> for HedgeGraph<E, V, H, N> {
2637 type Output = E;
2638 fn index(&self, index: EdgeIndex) -> &Self::Output {
2639 &self.edge_store[index]
2640 }
2641}
2642
2643impl<E, V, H, N: NodeStorage<NodeData = V>> Index<&EdgeIndex> for HedgeGraph<E, V, H, N> {
2644 type Output = (E, HedgePair);
2645 fn index(&self, index: &EdgeIndex) -> &Self::Output {
2646 &self.edge_store[index]
2647 }
2648}
2649
2650impl<E, V, H, N: NodeStorage<NodeData = V>> IndexMut<EdgeIndex> for HedgeGraph<E, V, H, N> {
2651 fn index_mut(&mut self, index: EdgeIndex) -> &mut Self::Output {
2652 &mut self.edge_store[index]
2653 }
2654}
2655
2656impl<E, V, H, N: NodeStorage<NodeData = V>> IndexMut<&EdgeIndex> for HedgeGraph<E, V, H, N> {
2657 fn index_mut(&mut self, index: &EdgeIndex) -> &mut Self::Output {
2658 &mut self.edge_store[index]
2659 }
2660}
2661
2662pub struct NodeIterator<'a, E, V, H, N: NodeStorage<NodeData = V>, I = IterOnes<'a, usize, Lsb0>> {
2663 graph: &'a HedgeGraph<E, V, H, N>,
2664 edges: I,
2665 seen: BitVec,
2666}
2667
2668impl<'a, E, V, H, I: Iterator<Item = Hedge>, N: NodeStorageOps<NodeData = V>> Iterator
2669 for NodeIterator<'a, E, V, H, N, I>
2670where
2671 N::NeighborsIter<'a>: Clone,
2672{
2673 type Item = (NodeIndex, N::NeighborsIter<'a>, &'a V);
2674
2675 fn next(&mut self) -> Option<Self::Item> {
2676 if let Some(next) = self.edges.next() {
2677 let node = self.graph.neighbors(next);
2678 let node_pos = self.graph.id_from_crown(node.clone()).unwrap();
2679
2680 if self.seen[node_pos.0] {
2681 self.next()
2682 } else {
2683 self.seen.set(node_pos.0, true);
2684 Some((node_pos, node, &self.graph[node_pos]))
2685 }
2686 } else {
2687 None
2688 }
2689 }
2690}
2691
2692#[cfg(feature = "symbolica")]
2693pub mod symbolica_interop;
2694
2695use subgraph::{
2696 BaseSubgraph, Cycle, FullOrEmpty, HedgeNode, Inclusion, InternalSubGraph, ModifySubgraph,
2697 OrientedCut, SubGraph, SubGraphOps,
2698};
2699
2700use thiserror::Error;
2701use tree::SimpleTraversalTree;
2702
2703use crate::define_indexed_vec;
2704use crate::tree::ForestNodeStore;
2705
2706#[derive(Error, Debug)]
2707pub enum HedgeError {
2708 #[error("Invalid start node")]
2709 InvalidStart,
2710}
2711
2712pub struct EdgeIter<'a, E, V, H, S, N: NodeStorage<NodeData = V>, I: Iterator<Item = Hedge> + 'a> {
2713 graph: &'a HedgeGraph<E, V, H, N>,
2714 included_iter: I,
2715 subgraph: &'a S,
2716}
2717impl<'a, E, V, H, S, N: NodeStorage<NodeData = V>> EdgeIter<'a, E, V, H, S, N, S::BaseIter<'a>>
2718where
2719 S: SubGraph,
2720{
2721 pub fn new(graph: &'a HedgeGraph<E, V, H, N>, subgraph: &'a S) -> Self {
2722 EdgeIter {
2723 graph,
2724 subgraph,
2725 included_iter: subgraph.included_iter(),
2726 }
2727 }
2728}
2729
2730impl<'a, E, V, H, S, N: NodeStorage<NodeData = V>> Iterator
2731 for EdgeIter<'a, E, V, H, S, N, S::BaseIter<'a>>
2732where
2733 S: SubGraph,
2734{
2735 type Item = (HedgePair, EdgeData<&'a E>);
2736
2737 fn next(&mut self) -> Option<Self::Item> {
2738 let i = self.included_iter.next()?;
2739 let orientation = self.graph.edge_store.orientation(i);
2740 let data = &self.graph[self.graph[&i]];
2741 if let Some(e) =
2742 HedgePair::from_source_with_subgraph(i, &self.graph.edge_store, self.subgraph)
2743 {
2744 Some((e, EdgeData::new(data, orientation)))
2745 } else {
2746 self.next()
2747 }
2748 }
2749}
2750
2751#[derive(Debug, Error)]
2752pub enum HedgeGraphError {
2753 #[error("Node ({0}) that Hedge {1} points to does not contain it")]
2754 NodeDoesNotContainHedge(NodeIndex, Hedge),
2755 #[error("Nodes do not partition: {0}")]
2756 NodesDoNotPartition(String),
2757 #[error("Invalid node")]
2758 NoNode,
2759 #[error("Invalid hedge {0}")]
2760 InvalidHedge(Hedge),
2761 #[error("External hedge as included: {0}")]
2762 ExternalHedgeIncluded(Hedge),
2763
2764 #[error("Included hedge {0} is not in node {1}")]
2765 NotInNode(Hedge, NodeIndex),
2766
2767 #[error("Traversal Root node not in subgraph {0}")]
2768 RootNodeNotInSubgraph(NodeIndex),
2769 #[error("Invalid node {0}")]
2770 InvalidNode(NodeIndex),
2771 #[error("Invalid edge")]
2772 NoEdge,
2773 #[error("Dangling Half edge present")]
2774 HasIdentityHedge,
2775 #[error("SymbolicaError: {0}")]
2776 SymbolicaError(&'static str),
2777 #[error("InvolutionError: {0}")]
2778 InvolutionError(#[from] InvolutionError),
2779 #[error("Data length mismatch")]
2780 DataLengthMismatch,
2781 #[error("Invalid hedge pair {0:?} not equal to {1:?} for edge {2}")]
2782 InvalidHedgePair(HedgePair, HedgePair, EdgeIndex),
2783 }
2788
2789pub mod hedgevec;
2790pub mod tree;
2791pub mod typed_vec;
2792
2793#[cfg(feature = "drawing")]
2794pub mod drawing;
2795#[cfg(feature = "drawing")]
2796pub mod layout;
2797#[cfg(test)]
2798mod test_graphs;
2799#[cfg(test)]
2800mod tests;