1use crate::lattice::Lattice;
5use serde::{Deserialize, Serialize};
6use std::collections::BTreeSet;
7#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
32pub struct GSet<T: Ord + Clone> {
33 elements: BTreeSet<T>,
34}
35
36impl<T: Ord + Clone> GSet<T> {
37 pub fn new() -> Self {
39 Self {
40 elements: BTreeSet::new(),
41 }
42 }
43
44 pub fn insert(&mut self, value: T) {
46 self.elements.insert(value);
47 }
48
49 pub fn contains(&self, value: &T) -> bool {
51 self.elements.contains(value)
52 }
53
54 pub fn iter(&self) -> impl Iterator<Item = &T> {
56 self.elements.iter()
57 }
58
59 pub fn len(&self) -> usize {
61 self.elements.len()
62 }
63
64 pub fn is_empty(&self) -> bool {
66 self.elements.is_empty()
67 }
68}
69
70impl<T: Ord + Clone> Default for GSet<T> {
71 fn default() -> Self {
72 Self::new()
73 }
74}
75
76impl<T: Ord + Clone> Lattice for GSet<T> {
77 fn bottom() -> Self {
78 Self::new()
79 }
80
81 fn join(&self, other: &Self) -> Self {
82 let mut elements = self.elements.clone();
84 elements.extend(other.elements.iter().cloned());
85 Self { elements }
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92 use proptest::prelude::*;
93
94 proptest! {
96 #[test]
97 fn gset_join_is_commutative(
98 a in prop::collection::btree_set(0i32..100, 0.. 20),
99 b in prop::collection::btree_set(0i32..100, 0..20)
100 ) {
101 let set_a = GSet { elements: a };
102 let set_b = GSet { elements: b };
103
104 prop_assert_eq!(set_a.join(&set_b), set_b.join(&set_a));
105 }
106
107 #[test]
108 fn gset_join_is_associative(
109 a in prop::collection::btree_set(0i32.. 100, 0.. 10),
110 b in prop::collection::btree_set(0i32..100, 0..10),
111 c in prop::collection::btree_set(0i32..100, 0..10)
112 ) {
113 let set_a = GSet { elements: a };
114 let set_b = GSet { elements: b };
115 let set_c = GSet { elements: c };
116
117 let left = set_a. join(&set_b).join(&set_c);
118 let right = set_a.join(&set_b. join(&set_c));
119
120 prop_assert_eq!(left, right);
121 }
122
123 #[test]
124 fn gset_join_is_idempotent(
125 a in prop:: collection::btree_set(0i32..100, 0..20)
126 ) {
127 let set_a = GSet { elements: a };
128
129 prop_assert_eq!(set_a.join(&set_a), set_a);
130 }
131 }
132}