algebraeon_sets/structure/
pairs.rs

1use crate::structure::Signature;
2
3use super::{EqSignature, SetSignature};
4use std::fmt::Debug;
5
6/// The set of Pairs
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct PairsStructure<S> {
9    set: S,
10}
11
12impl<S: SetSignature> PairsStructure<S> {
13    pub fn new(set: S) -> Self {
14        Self { set }
15    }
16
17    /// Construct a new pair from two elements of a set
18    pub fn new_pair(&self, a: S::Set, b: S::Set) -> Result<(S::Set, S::Set), String> {
19        self.set.is_element(&a)?;
20        self.set.is_element(&b)?;
21        Ok((a, b))
22    }
23}
24
25impl<S: SetSignature> Signature for PairsStructure<S> {}
26
27impl<S: SetSignature> SetSignature for PairsStructure<S> {
28    type Set = (S::Set, S::Set);
29
30    fn is_element(&self, x: &Self::Set) -> Result<(), String> {
31        self.set.is_element(&x.0)?;
32        self.set.is_element(&x.1)?;
33        Ok(())
34    }
35}
36
37impl<S: SetSignature + EqSignature> EqSignature for PairsStructure<S> {
38    fn equal(&self, a: &Self::Set, b: &Self::Set) -> bool {
39        self.set.equal(&a.0, &b.0) && self.set.equal(&a.1, &b.1)
40    }
41}
42
43/// The set of unordered Pairs of distinct elements
44#[derive(Debug, Clone, PartialEq, Eq)]
45pub struct UnorderedPairs<Set> {
46    set: Set,
47}
48
49impl<Set: SetSignature> UnorderedPairs<Set> {
50    pub fn new(set: Set) -> Self {
51        Self { set }
52    }
53}
54
55#[derive(Debug, Clone, PartialEq, Eq, Hash)]
56pub struct UnorderedPair<T>(T, T);
57
58impl<S: SetSignature + EqSignature> UnorderedPairs<S> {
59    pub fn new_pair(&self, a: &S::Set, b: &S::Set) -> Result<UnorderedPair<S::Set>, String> {
60        if self.set.equal(a, b) {
61            Err("UnorderedPair elements must be distinct".to_string())
62        } else {
63            Ok(UnorderedPair(a.clone(), b.clone()))
64        }
65    }
66}
67
68impl<S: SetSignature> Signature for UnorderedPairs<S> {}
69
70impl<S: SetSignature + EqSignature> SetSignature for UnorderedPairs<S> {
71    type Set = UnorderedPair<S::Set>;
72
73    fn is_element(&self, x: &Self::Set) -> Result<(), String> {
74        self.set.is_element(&x.0)?;
75        self.set.is_element(&x.1)?;
76        if self.set.equal(&x.0, &x.1) {
77            Err("UnorderedPair elements must be distinct".to_string())
78        } else {
79            Ok(())
80        }
81    }
82}
83
84impl<S: SetSignature + EqSignature> EqSignature for UnorderedPairs<S> {
85    fn equal(&self, a: &Self::Set, b: &Self::Set) -> bool {
86        self.set.equal(&a.0, &b.0) && self.set.equal(&a.1, &b.1)
87            || self.set.equal(&a.0, &b.1) && self.set.equal(&a.1, &b.0)
88    }
89}