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 Self {
83 elements: self.elements.union(&other.elements).cloned().collect(),
84 }
85 }
86}
87
88#[cfg(test)]
89mod tests {
90 use super::*;
91 use proptest::prelude::*;
92
93 proptest! {
95 #[test]
96 fn gset_join_is_commutative(
97 a in prop::collection::btree_set(0i32..100, 0.. 20),
98 b in prop::collection::btree_set(0i32..100, 0..20)
99 ) {
100 let set_a = GSet { elements: a };
101 let set_b = GSet { elements: b };
102
103 prop_assert_eq!(set_a.join(&set_b), set_b.join(&set_a));
104 }
105
106 #[test]
107 fn gset_join_is_associative(
108 a in prop::collection::btree_set(0i32.. 100, 0.. 10),
109 b in prop::collection::btree_set(0i32..100, 0..10),
110 c in prop::collection::btree_set(0i32..100, 0..10)
111 ) {
112 let set_a = GSet { elements: a };
113 let set_b = GSet { elements: b };
114 let set_c = GSet { elements: c };
115
116 let left = set_a. join(&set_b).join(&set_c);
117 let right = set_a.join(&set_b. join(&set_c));
118
119 prop_assert_eq!(left, right);
120 }
121
122 #[test]
123 fn gset_join_is_idempotent(
124 a in prop:: collection::btree_set(0i32..100, 0..20)
125 ) {
126 let set_a = GSet { elements: a };
127
128 prop_assert_eq!(set_a.join(&set_a), set_a);
129 }
130 }
131}