graaf/op/
is_symmetric.rs

1//! Check whether a digraph is symmetric.
2//!
3//! A digraph is symmetric if for every arc `(u, v)` there is an arc
4//! `(v, u)`.
5//!
6//! # Examples
7//!
8//! ```
9//! use graaf::{
10//!     AddArc,
11//!     AdjacencyList,
12//!     Empty,
13//!     IsSymmetric,
14//!     RemoveArc,
15//! };
16//!
17//! let mut digraph = AdjacencyList::empty(2);
18//!
19//! digraph.add_arc(0, 1);
20//! digraph.add_arc(1, 0);
21//!
22//! assert!(digraph.is_symmetric());
23//!
24//! digraph.remove_arc(1, 0);
25//!
26//! assert!(!digraph.is_symmetric());
27//!
28//! let mut digraph = AdjacencyList::empty(3);
29//!
30//! digraph.add_arc(0, 1);
31//! digraph.add_arc(0, 2);
32//! digraph.add_arc(1, 2);
33//! digraph.add_arc(2, 0);
34//!
35//! assert!(!digraph.is_symmetric());
36//! ```
37
38use crate::{
39    Arcs,
40    HasArc,
41};
42
43/// Check whether a digraph is symmetric.
44pub trait IsSymmetric {
45    /// Check whether the digraph is symmetric.
46    ///
47    /// # Examples
48    /// ```
49    /// use graaf::{
50    ///     AddArc,
51    ///     AdjacencyList,
52    ///     Empty,
53    ///     IsSymmetric,
54    ///     RemoveArc,
55    /// };
56    ///
57    /// let mut digraph = AdjacencyList::empty(2);
58    ///
59    /// digraph.add_arc(0, 1);
60    /// digraph.add_arc(1, 0);
61    ///
62    /// assert!(digraph.is_symmetric());
63    ///
64    /// digraph.remove_arc(1, 0);
65    ///
66    /// assert!(!digraph.is_symmetric());
67    /// ```
68    #[must_use]
69    fn is_symmetric(&self) -> bool;
70}
71
72impl<D> IsSymmetric for D
73where
74    D: Arcs + HasArc,
75{
76    fn is_symmetric(&self) -> bool {
77        self.arcs().all(|(u, v)| self.has_arc(v, u))
78    }
79}
80
81/// `IsSymmetric` tests
82#[macro_export]
83macro_rules! test_is_symmetric {
84    ($fixture:path) => {
85        use $fixture::{
86            bang_jensen_34,
87            bang_jensen_94,
88            bang_jensen_196,
89            kattis_builddeps,
90            kattis_cantinaofbabel_1,
91            kattis_cantinaofbabel_2,
92            kattis_escapewallmaria_1,
93            kattis_escapewallmaria_2,
94            kattis_escapewallmaria_3,
95        };
96
97        #[test]
98        fn is_symmetric_bang_jensen_196() {
99            assert!(!bang_jensen_196().is_symmetric());
100        }
101
102        #[test]
103        fn is_symmetric_bang_jensen_34() {
104            assert!(!bang_jensen_34().is_symmetric());
105        }
106
107        #[test]
108        fn is_symmetric_bang_jensen_94() {
109            assert!(!bang_jensen_94().is_symmetric());
110        }
111
112        #[test]
113        fn is_symmetric_kattis_builddeps() {
114            assert!(!kattis_builddeps().is_symmetric());
115        }
116
117        #[test]
118        fn is_symmetric_kattis_cantinaofbabel_1() {
119            assert!(!kattis_cantinaofbabel_1().is_symmetric());
120        }
121
122        #[test]
123        fn is_symmetric_kattis_cantinaofbabel_2() {
124            assert!(!kattis_cantinaofbabel_2().is_symmetric());
125        }
126
127        #[test]
128        fn is_symmetric_kattis_escapewallmaria_1() {
129            assert!(!kattis_escapewallmaria_1().is_symmetric());
130        }
131
132        #[test]
133        fn is_symmetric_kattis_escapewallmaria_2() {
134            assert!(!kattis_escapewallmaria_2().is_symmetric());
135        }
136
137        #[test]
138        fn is_symmetric_kattis_escapewallmaria_3() {
139            assert!(kattis_escapewallmaria_3().is_symmetric());
140        }
141    };
142}