1use crate::interface::BidirectedData;
2use std::collections::HashSet;
3use traitgraph::interface::{GraphBase, StaticGraph};
4
5pub trait StaticBigraph: StaticGraph {
10 fn mirror_node(&self, node_id: Self::NodeIndex) -> Option<Self::NodeIndex>;
14
15 fn is_self_mirror_node(&self, node_index: Self::NodeIndex) -> bool {
18 self.mirror_node(node_index).unwrap() == node_index
19 }
20
21 fn topological_mirror_edges(&self, edge_index: Self::EdgeIndex) -> Vec<Self::EdgeIndex> {
23 let endpoints = self.edge_endpoints(edge_index);
24 let reverse_from = if let Some(reverse_from) = self.mirror_node(endpoints.to_node) {
25 reverse_from
26 } else {
27 return Vec::new();
28 };
29 let reverse_to = if let Some(reverse_to) = self.mirror_node(endpoints.from_node) {
30 reverse_to
31 } else {
32 return Vec::new();
33 };
34 self.edges_between(reverse_from, reverse_to).collect()
35 }
36
37 fn verify_node_pairing(&self) -> bool {
42 for node_index in self.node_indices() {
43 let mirror_index = if let Some(mirror_node) = self.mirror_node(node_index) {
44 mirror_node
45 } else {
46 return false;
47 };
48 let mirror_mirror_index =
49 if let Some(mirror_mirror_node) = self.mirror_node(mirror_index) {
50 mirror_mirror_node
51 } else {
52 return false;
53 };
54 if node_index != mirror_mirror_index {
55 return false;
56 }
57 }
58
59 true
60 }
61
62 fn verify_node_pairing_without_self_mirrors(&self) -> bool {
66 for node_index in self.node_indices() {
67 let mirror_index = if let Some(mirror_node) = self.mirror_node(node_index) {
68 mirror_node
69 } else {
70 return false;
71 };
72 let mirror_mirror_index =
73 if let Some(mirror_mirror_node) = self.mirror_node(mirror_index) {
74 mirror_mirror_node
75 } else {
76 return false;
77 };
78 if node_index != mirror_mirror_index || node_index == mirror_index {
79 return false;
80 }
81 }
82
83 true
84 }
85
86 fn out_bidegree(&self, node_index: Self::NodeIndex) -> Option<usize> {
90 let mirror_node = self.mirror_node(node_index).unwrap();
91 if mirror_node == node_index {
92 None
93 } else {
94 let mut out_neighbor_count = 0;
95 let mut inversion_count = 0;
96 for out_neighbor in self.out_neighbors(node_index) {
97 if out_neighbor.node_id == mirror_node {
98 inversion_count += 1;
99 } else {
100 out_neighbor_count += 1;
101 }
102 }
103
104 let in_degree = self.in_degree(node_index);
105 Some(out_neighbor_count + inversion_count.min(in_degree))
106 }
107 }
108
109 fn in_bidegree(&self, node_index: Self::NodeIndex) -> Option<usize> {
113 let mirror_node = self.mirror_node(node_index).unwrap();
114 self.out_bidegree(mirror_node)
115 }
116
117 fn inversion_bidegree(&self, node_index: Self::NodeIndex) -> isize {
120 let mirror_node = self.mirror_node(node_index).unwrap();
121 self.out_neighbors(node_index)
122 .filter(|n| n.node_id == mirror_node)
123 .count() as isize
124 - self
125 .in_neighbors(node_index)
126 .filter(|n| n.node_id == mirror_node)
127 .count() as isize
128 }
129}
130
131pub trait StaticNodeCentricBigraph: StaticBigraph {
137 fn mirror_edge_node_centric(&self, edge_id: Self::EdgeIndex) -> Option<Self::EdgeIndex> {
143 let endpoints = self.edge_endpoints(edge_id);
144 let reverse_from = self.mirror_node(endpoints.to_node)?;
145 let reverse_to = self.mirror_node(endpoints.from_node)?;
146 let mut result = None;
147
148 for reverse_edge_id in self.edges_between(reverse_from, reverse_to) {
149 if let Some(node) = result {
150 if node == edge_id {
151 return Some(reverse_edge_id);
152 }
153 } else if reverse_edge_id == edge_id {
154 result = Some(reverse_edge_id);
155 } else {
156 return Some(reverse_edge_id);
157 }
158 }
159
160 None
161 }
162
163 fn verify_node_mirror_property(&self) -> bool {
170 for from_node in self.node_indices() {
171 for to_node in self.out_neighbors(from_node) {
172 let from_node_mirror = self.mirror_node(from_node).unwrap();
173 let to_node_mirror = self.mirror_node(to_node.node_id).unwrap();
174 if self.edge_count_between(to_node_mirror, from_node_mirror)
175 != self.edge_count_between(from_node, to_node.node_id)
176 {
177 return false;
178 }
179 }
180 }
181
182 true
183 }
184}
185
186pub trait StaticEdgeCentricBigraph: StaticBigraph
191where
192 <Self as GraphBase>::EdgeData: BidirectedData + Eq,
193{
194 fn mirror_edge_edge_centric(&self, edge_id: Self::EdgeIndex) -> Option<Self::EdgeIndex> {
200 let endpoints = self.edge_endpoints(edge_id);
201 let reverse_from = self.mirror_node(endpoints.to_node)?;
202 let reverse_to = self.mirror_node(endpoints.from_node)?;
203 let edge_data = self.edge_data(edge_id);
204 let mut result = None;
205
206 for reverse_edge_id in self.edges_between(reverse_from, reverse_to) {
207 if &edge_data.mirror() == self.edge_data(reverse_edge_id) {
208 if let Some(node) = result {
209 if node == edge_id {
210 return Some(reverse_edge_id);
211 }
212 } else if reverse_edge_id == edge_id {
213 result = Some(reverse_edge_id);
214 } else {
215 return Some(reverse_edge_id);
216 }
217 }
218 }
219
220 None
221 }
222
223 fn verify_edge_mirror_property(&self) -> bool {
230 let mut edge_set = HashSet::new();
231
232 for from_node in self.node_indices() {
233 for neighbor in self.out_neighbors(from_node) {
234 let edge = neighbor.edge_id;
235 if let Some(mirror_edge) = self.mirror_edge_edge_centric(edge) {
236 let to_node = neighbor.node_id;
237 let complete_edge = (from_node, to_node, edge);
238 let mirror_complete_edge = (
239 self.mirror_node(to_node).unwrap(),
240 self.mirror_node(from_node).unwrap(),
241 mirror_edge,
242 );
243
244 if edge_set.contains(&mirror_complete_edge) {
245 edge_set.remove(&mirror_complete_edge);
246 if &self.edge_data(edge).mirror() != self.edge_data(mirror_edge) {
247 return false;
249 }
250 } else {
251 edge_set.insert(complete_edge);
252 }
253 } else {
254 return false;
256 }
257 }
258 }
259
260 edge_set.is_empty()
278 }
279}
280
281pub trait StaticBigraphFromDigraph: StaticBigraph {
287 type Topology: StaticGraph<NodeData = Self::NodeData, EdgeData = Self::EdgeData>;
289
290 fn new(topology: Self::Topology) -> Self;
295
296 fn new_unchecked(topology: Self::Topology) -> Self;
302}
303
304#[cfg(test)]
305mod test {
306 use crate::implementation::node_bigraph_wrapper::NodeBigraphWrapper;
307 use crate::interface::dynamic_bigraph::DynamicBigraph;
308 use crate::interface::static_bigraph::StaticBigraph;
309 use crate::interface::static_bigraph::StaticBigraphFromDigraph;
310 use crate::interface::static_bigraph::StaticEdgeCentricBigraph;
311 use crate::interface::static_bigraph::StaticNodeCentricBigraph;
312 use crate::interface::BidirectedData;
313 use traitgraph::implementation::petgraph_impl::PetGraph;
314 use traitgraph::interface::ImmutableGraphContainer;
315 use traitgraph::interface::MutableGraphContainer;
316
317 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
318 struct EdgeData(usize);
319
320 impl BidirectedData for EdgeData {
321 fn mirror(&self) -> Self {
322 EdgeData(1000 - self.0)
323 }
324 }
325
326 #[test]
327 fn test_verify_node_mirror_property_positive() {
328 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
329 struct NodeData(i32);
330 impl BidirectedData for NodeData {
331 fn mirror(&self) -> Self {
332 Self(if self.0 % 2 == 0 {
333 self.0 + 1
334 } else {
335 self.0 - 1
336 })
337 }
338 }
339
340 let mut graph = PetGraph::new();
341 let n1 = graph.add_node(NodeData(0));
342 let n2 = graph.add_node(NodeData(1));
343 let n3 = graph.add_node(NodeData(2));
344 let n4 = graph.add_node(NodeData(3));
345 graph.add_edge(n1, n3, EdgeData(10));
346 graph.add_edge(n4, n2, EdgeData(11));
347 graph.add_edge(n3, n1, EdgeData(12));
348 graph.add_edge(n2, n4, EdgeData(13));
349 let bigraph = NodeBigraphWrapper::new(graph);
350 debug_assert!(bigraph.verify_node_pairing());
351 debug_assert!(bigraph.verify_node_mirror_property());
352 }
353
354 #[test]
355 fn test_verify_node_mirror_property_unpaired() {
356 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
357 struct NodeData(i32);
358 impl BidirectedData for NodeData {
359 fn mirror(&self) -> Self {
360 Self(if self.0 % 2 == 0 {
361 self.0 + 1
362 } else {
363 self.0 - 1
364 })
365 }
366 }
367
368 let mut graph = PetGraph::new();
369 let n1 = graph.add_node(NodeData(0));
370 let n2 = graph.add_node(NodeData(1));
371 let n3 = graph.add_node(NodeData(2));
372 let n4 = graph.add_node(NodeData(3));
373 graph.add_edge(n1, n3, EdgeData(10));
374 graph.add_edge(n4, n2, EdgeData(11));
375 graph.add_edge(n3, n1, EdgeData(12));
376 let bigraph = NodeBigraphWrapper::new(graph);
377 debug_assert!(bigraph.verify_node_pairing());
378 debug_assert!(!bigraph.verify_node_mirror_property());
379 }
380
381 #[test]
382 fn test_verify_node_mirror_property_duplicate_edges() {
383 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
384 struct NodeData(i32);
385 impl BidirectedData for NodeData {
386 fn mirror(&self) -> Self {
387 Self(if self.0 % 2 == 0 {
388 self.0 + 1
389 } else {
390 self.0 - 1
391 })
392 }
393 }
394
395 let mut graph = PetGraph::new();
396 let n1 = graph.add_node(NodeData(0));
397 let n2 = graph.add_node(NodeData(1));
398 let n3 = graph.add_node(NodeData(2));
399 let n4 = graph.add_node(NodeData(3));
400 graph.add_edge(n1, n3, EdgeData(10));
401 graph.add_edge(n4, n2, EdgeData(11));
402 graph.add_edge(n3, n1, EdgeData(12));
403 graph.add_edge(n2, n4, EdgeData(13));
404
405 let mut bigraph = NodeBigraphWrapper::new(graph);
406 debug_assert!(bigraph.verify_node_pairing());
407 debug_assert!(bigraph.verify_node_mirror_property());
408
409 bigraph.add_edge(n1, n3, EdgeData(14));
410 debug_assert!(bigraph.verify_node_pairing());
411 debug_assert!(!bigraph.verify_node_mirror_property());
412
413 bigraph.add_edge(n4, n2, EdgeData(15));
414 debug_assert!(bigraph.verify_node_pairing());
415 debug_assert!(bigraph.verify_node_mirror_property());
416 }
417
418 #[test]
419 fn test_verify_edge_mirror_property_positive() {
420 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
421 struct NodeData(i32);
422 impl BidirectedData for NodeData {
423 fn mirror(&self) -> Self {
424 Self(if self.0 % 2 == 0 {
425 self.0 + 1
426 } else {
427 self.0 - 1
428 })
429 }
430 }
431
432 let mut graph = PetGraph::new();
433 let n1 = graph.add_node(NodeData(0));
434 let n2 = graph.add_node(NodeData(1));
435 let n3 = graph.add_node(NodeData(2));
436 let n4 = graph.add_node(NodeData(3));
437 graph.add_edge(n1, n3, EdgeData(10));
438 graph.add_edge(n4, n2, EdgeData(990));
439 graph.add_edge(n3, n1, EdgeData(12));
440 graph.add_edge(n2, n4, EdgeData(988));
441 let bigraph = NodeBigraphWrapper::new(graph);
442 debug_assert!(bigraph.verify_node_pairing());
443 debug_assert!(bigraph.verify_edge_mirror_property());
444 }
445
446 #[test]
447 fn test_verify_edge_mirror_property_unpaired() {
448 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
449 struct NodeData(i32);
450 impl BidirectedData for NodeData {
451 fn mirror(&self) -> Self {
452 Self(if self.0 % 2 == 0 {
453 self.0 + 1
454 } else {
455 self.0 - 1
456 })
457 }
458 }
459
460 let mut graph = PetGraph::new();
461 let n1 = graph.add_node(NodeData(0));
462 let n2 = graph.add_node(NodeData(1));
463 let n3 = graph.add_node(NodeData(2));
464 let n4 = graph.add_node(NodeData(3));
465 graph.add_edge(n1, n3, EdgeData(10));
466 graph.add_edge(n4, n2, EdgeData(990));
467 graph.add_edge(n3, n1, EdgeData(12));
468 graph.add_edge(n4, n2, EdgeData(990));
469 let bigraph = NodeBigraphWrapper::new(graph);
470 debug_assert!(bigraph.verify_node_pairing());
471 debug_assert!(!bigraph.verify_edge_mirror_property());
472 }
473
474 #[test]
475 fn test_verify_edge_mirror_property_duplicate_edges_with_differing_data() {
476 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
477 struct NodeData(i32);
478 impl BidirectedData for NodeData {
479 fn mirror(&self) -> Self {
480 Self(if self.0 % 2 == 0 {
481 self.0 + 1
482 } else {
483 self.0 - 1
484 })
485 }
486 }
487
488 let mut graph = PetGraph::new();
489 let n1 = graph.add_node(NodeData(0));
490 let n2 = graph.add_node(NodeData(1));
491 let n3 = graph.add_node(NodeData(2));
492 let n4 = graph.add_node(NodeData(3));
493 graph.add_edge(n1, n3, EdgeData(10));
494 graph.add_edge(n4, n2, EdgeData(990));
495 graph.add_edge(n3, n1, EdgeData(12));
496 graph.add_edge(n2, n4, EdgeData(988));
497
498 let mut bigraph = NodeBigraphWrapper::new(graph);
499 debug_assert!(bigraph.verify_node_pairing());
500 debug_assert!(bigraph.verify_edge_mirror_property());
501
502 bigraph.add_edge(n1, n3, EdgeData(14));
503 debug_assert!(bigraph.verify_node_pairing());
504 debug_assert!(!bigraph.verify_edge_mirror_property());
505
506 bigraph.add_edge(n4, n2, EdgeData(986));
507 debug_assert!(bigraph.verify_node_pairing());
508 debug_assert!(bigraph.verify_edge_mirror_property());
509 }
510
511 #[test]
512 fn test_verify_edge_mirror_property_duplicate_edges_with_plus_minus_loop() {
513 #[derive(Clone, Eq, PartialEq, Hash, Debug)]
514 struct NodeData(i32);
515 impl BidirectedData for NodeData {
516 fn mirror(&self) -> Self {
517 Self(1000 - self.0)
518 }
519 }
520
521 let mut graph = NodeBigraphWrapper::new(PetGraph::new());
522 let n1 = graph.add_node(NodeData(0));
523 let n2 = graph.add_node(NodeData(1000));
524 let n3 = graph.add_node(NodeData(500));
525 graph.set_mirror_nodes(n1, n2);
526 graph.set_mirror_nodes(n3, n3);
527 graph.add_edge(n1, n3, EdgeData(10));
528 graph.add_edge(n3, n2, EdgeData(990));
529 graph.add_edge(n3, n1, EdgeData(12));
530 graph.add_edge(n2, n3, EdgeData(988));
531
532 debug_assert!(graph.verify_node_pairing());
533 debug_assert!(graph.verify_edge_mirror_property());
534
535 graph.add_edge(n1, n3, EdgeData(14));
536 debug_assert!(graph.verify_node_pairing());
537 debug_assert!(!graph.verify_edge_mirror_property());
538
539 graph.add_edge(n3, n2, EdgeData(986));
540 debug_assert!(graph.verify_node_pairing());
541 debug_assert!(graph.verify_edge_mirror_property());
542
543 debug_assert_eq!(graph.edge_count(), 6);
544 let mirror_copy = graph.clone();
545
546 graph.add_edge(n1, n3, EdgeData(14));
547 debug_assert!(graph.verify_node_pairing());
548 debug_assert!(!graph.verify_edge_mirror_property());
549
550 graph.add_edge(n3, n2, EdgeData(986));
551 debug_assert!(graph.verify_node_pairing());
552 debug_assert!(!graph.verify_edge_mirror_property());
553 debug_assert_eq!(graph.edge_count(), 8);
554
555 let mut graph = mirror_copy.clone();
556
557 graph.add_edge(n1, n3, EdgeData(100));
558 debug_assert!(graph.verify_node_pairing());
559 debug_assert!(!graph.verify_edge_mirror_property());
560
561 graph.add_edge(n1, n3, EdgeData(100));
562 debug_assert!(graph.verify_node_pairing());
563 debug_assert!(!graph.verify_edge_mirror_property());
564
565 graph.add_edge(n3, n2, EdgeData(900));
566 debug_assert!(graph.verify_node_pairing());
567 debug_assert!(!graph.verify_edge_mirror_property());
568
569 graph.add_edge(n3, n2, EdgeData(900));
570 debug_assert!(graph.verify_node_pairing());
571 debug_assert!(!graph.verify_edge_mirror_property());
572 debug_assert_eq!(graph.edge_count(), 10);
573
574 let mut graph = mirror_copy.clone();
575
576 graph.add_edge(n3, n2, EdgeData(900));
577 debug_assert!(graph.verify_node_pairing());
578 debug_assert!(!graph.verify_edge_mirror_property());
579
580 graph.add_edge(n1, n3, EdgeData(100));
581 debug_assert!(graph.verify_node_pairing());
582 debug_assert!(graph.verify_edge_mirror_property());
583
584 graph.add_edge(n1, n3, EdgeData(100));
585 debug_assert!(graph.verify_node_pairing());
586 debug_assert!(!graph.verify_edge_mirror_property());
587
588 graph.add_edge(n3, n2, EdgeData(900));
589 debug_assert!(graph.verify_node_pairing());
590 debug_assert!(!graph.verify_edge_mirror_property());
591 debug_assert_eq!(graph.edge_count(), 10);
592
593 let mut graph = mirror_copy.clone();
594
595 graph.add_edge(n3, n2, EdgeData(986));
596 debug_assert!(graph.verify_node_pairing());
597 debug_assert!(!graph.verify_edge_mirror_property());
598
599 graph.add_edge(n1, n3, EdgeData(14));
600 debug_assert!(graph.verify_node_pairing());
601 debug_assert!(!graph.verify_edge_mirror_property());
602 debug_assert_eq!(graph.edge_count(), 8);
603
604 let mut graph = mirror_copy;
605
606 graph.add_edge(n3, n3, EdgeData(500));
607 debug_assert!(graph.verify_node_pairing());
608 debug_assert!(!graph.verify_edge_mirror_property());
609
610 graph.add_edge(n3, n3, EdgeData(500));
611 debug_assert!(graph.verify_node_pairing());
612 debug_assert!(graph.verify_edge_mirror_property());
613 debug_assert_eq!(graph.edge_count(), 8);
614
615 graph.add_edge(n3, n3, EdgeData(500));
616 debug_assert!(graph.verify_node_pairing());
617 debug_assert!(!graph.verify_edge_mirror_property());
618
619 graph.add_edge(n3, n3, EdgeData(500));
620 debug_assert!(graph.verify_node_pairing());
621 debug_assert!(!graph.verify_edge_mirror_property());
622 debug_assert_eq!(graph.edge_count(), 10);
623 }
624}