1use crate::lattice::Lattice;
5use serde::{Deserialize, Serialize};
6use std::collections::BTreeSet;
7#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
10pub struct GSet<T: Ord + Clone> {
11 elements: BTreeSet<T>,
12}
13
14impl<T: Ord + Clone> GSet<T> {
15 pub fn new() -> Self {
16 Self {
17 elements: BTreeSet::new(),
18 }
19 }
20
21 pub fn insert(&mut self, value: T) {
23 self.elements.insert(value);
24 }
25
26 pub fn contains(&self, value: &T) -> bool {
27 self.elements.contains(value)
28 }
29
30 pub fn iter(&self) -> impl Iterator<Item = &T> {
31 self.elements.iter()
32 }
33
34 pub fn len(&self) -> usize {
35 self.elements.len()
36 }
37
38 pub fn is_empty(&self) -> bool {
39 self.elements.is_empty()
40 }
41}
42
43impl<T: Ord + Clone> Default for GSet<T> {
44 fn default() -> Self {
45 Self::new()
46 }
47}
48
49impl<T: Ord + Clone> Lattice for GSet<T> {
50 fn bottom() -> Self {
51 Self::new()
52 }
53
54 fn join(&self, other: &Self) -> Self {
55 Self {
56 elements: self.elements.union(&other.elements).cloned().collect(),
57 }
58 }
59}
60
61#[cfg(test)]
62mod tests {
63 use super::*;
64 use proptest::prelude::*;
65
66 proptest! {
68 #[test]
69 fn gset_join_is_commutative(
70 a in prop::collection::btree_set(0i32..100, 0.. 20),
71 b in prop::collection::btree_set(0i32..100, 0..20)
72 ) {
73 let set_a = GSet { elements: a };
74 let set_b = GSet { elements: b };
75
76 prop_assert_eq!(set_a.join(&set_b), set_b.join(&set_a));
77 }
78
79 #[test]
80 fn gset_join_is_associative(
81 a in prop::collection::btree_set(0i32.. 100, 0.. 10),
82 b in prop::collection::btree_set(0i32..100, 0..10),
83 c in prop::collection::btree_set(0i32..100, 0..10)
84 ) {
85 let set_a = GSet { elements: a };
86 let set_b = GSet { elements: b };
87 let set_c = GSet { elements: c };
88
89 let left = set_a. join(&set_b).join(&set_c);
90 let right = set_a.join(&set_b. join(&set_c));
91
92 prop_assert_eq!(left, right);
93 }
94
95 #[test]
96 fn gset_join_is_idempotent(
97 a in prop:: collection::btree_set(0i32..100, 0..20)
98 ) {
99 let set_a = GSet { elements: a };
100
101 prop_assert_eq!(set_a.join(&set_a), set_a);
102 }
103 }
104}