Skip to main content

oxilean_std/set/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use super::functions::*;
6use std::collections::HashSet;
7
8/// Finite relation as a set of ordered pairs.
9#[allow(dead_code)]
10#[derive(Debug, Clone)]
11pub struct Relation<A: Clone + Eq + std::hash::Hash> {
12    pub domain: Vec<A>,
13    pub pairs: std::collections::HashSet<(usize, usize)>,
14}
15#[allow(dead_code)]
16impl<A: Clone + Eq + std::hash::Hash> Relation<A> {
17    pub fn new(domain: Vec<A>) -> Self {
18        Relation {
19            domain,
20            pairs: std::collections::HashSet::new(),
21        }
22    }
23    pub fn add_pair(&mut self, a: &A, b: &A) {
24        let i = self.domain.iter().position(|x| x == a);
25        let j = self.domain.iter().position(|x| x == b);
26        if let (Some(i), Some(j)) = (i, j) {
27            self.pairs.insert((i, j));
28        }
29    }
30    pub fn contains(&self, a: &A, b: &A) -> bool {
31        let i = self.domain.iter().position(|x| x == a);
32        let j = self.domain.iter().position(|x| x == b);
33        match (i, j) {
34            (Some(i), Some(j)) => self.pairs.contains(&(i, j)),
35            _ => false,
36        }
37    }
38    pub fn is_reflexive(&self) -> bool {
39        (0..self.domain.len()).all(|i| self.pairs.contains(&(i, i)))
40    }
41    pub fn is_symmetric(&self) -> bool {
42        self.pairs
43            .iter()
44            .all(|&(i, j)| self.pairs.contains(&(j, i)))
45    }
46    pub fn is_transitive(&self) -> bool {
47        let n = self.domain.len();
48        for i in 0..n {
49            for j in 0..n {
50                if self.pairs.contains(&(i, j)) {
51                    for k in 0..n {
52                        if self.pairs.contains(&(j, k)) && !self.pairs.contains(&(i, k)) {
53                            return false;
54                        }
55                    }
56                }
57            }
58        }
59        true
60    }
61    pub fn is_equivalence(&self) -> bool {
62        self.is_reflexive() && self.is_symmetric() && self.is_transitive()
63    }
64    pub fn is_antisymmetric(&self) -> bool {
65        self.pairs
66            .iter()
67            .all(|&(i, j)| i == j || !self.pairs.contains(&(j, i)))
68    }
69    pub fn is_partial_order(&self) -> bool {
70        self.is_reflexive() && self.is_antisymmetric() && self.is_transitive()
71    }
72    pub fn equivalence_class(&self, a: &A) -> Vec<A> {
73        let i = self.domain.iter().position(|x| x == a);
74        match i {
75            None => Vec::new(),
76            Some(i) => self
77                .pairs
78                .iter()
79                .filter(|&&(x, _)| x == i)
80                .map(|&(_, j)| self.domain[j].clone())
81                .collect(),
82        }
83    }
84}
85/// Set partition into disjoint non-empty blocks.
86#[allow(dead_code)]
87#[derive(Debug, Clone)]
88pub struct SetPartition {
89    pub n: usize,
90    pub blocks: Vec<std::collections::HashSet<usize>>,
91}
92#[allow(dead_code)]
93impl SetPartition {
94    pub fn discrete(n: usize) -> Self {
95        SetPartition {
96            n,
97            blocks: (0..n)
98                .map(|i| {
99                    let mut s = std::collections::HashSet::new();
100                    s.insert(i);
101                    s
102                })
103                .collect(),
104        }
105    }
106    pub fn trivial(n: usize) -> Self {
107        let mut block = std::collections::HashSet::new();
108        for i in 0..n {
109            block.insert(i);
110        }
111        SetPartition {
112            n,
113            blocks: vec![block],
114        }
115    }
116    pub fn n_blocks(&self) -> usize {
117        self.blocks.len()
118    }
119    pub fn block_of(&self, element: usize) -> Option<usize> {
120        self.blocks.iter().position(|b| b.contains(&element))
121    }
122    pub fn merge_blocks(&mut self, i: usize, j: usize) {
123        if i == j || i >= self.blocks.len() || j >= self.blocks.len() {
124            return;
125        }
126        let block_j = self.blocks[j].clone();
127        let block_i = &mut self.blocks[i];
128        for x in block_j {
129            block_i.insert(x);
130        }
131        self.blocks.remove(j);
132    }
133    pub fn is_valid(&self) -> bool {
134        let mut covered = vec![false; self.n];
135        for block in &self.blocks {
136            if block.is_empty() {
137                return false;
138            }
139            for &x in block {
140                if x >= self.n || covered[x] {
141                    return false;
142                }
143                covered[x] = true;
144            }
145        }
146        covered.iter().all(|&c| c)
147    }
148}
149/// Ordered pair (Kuratowski definition: {a} and {a,b} as sets).
150#[allow(dead_code)]
151#[derive(Debug, Clone, PartialEq, Eq)]
152pub struct OrderedPair<A: Clone + Eq, B: Clone + Eq> {
153    pub fst: A,
154    pub snd: B,
155}
156#[allow(dead_code)]
157impl<A: Clone + Eq, B: Clone + Eq> OrderedPair<A, B> {
158    pub fn new(a: A, b: B) -> Self {
159        OrderedPair { fst: a, snd: b }
160    }
161    pub fn swap(self) -> OrderedPair<B, A> {
162        OrderedPair {
163            fst: self.snd,
164            snd: self.fst,
165        }
166    }
167}