permutation_rs/group/
special.rs

1//! Home for special groups.
2
3use super::{GroupElement, GroupAction, Morphism};
4use super::tree::SLP;
5use super::permutation::Permutation;
6use super::free::Word;
7
8/// A special product of a `SLP` and a `Permutation`.
9#[derive(Debug, PartialEq)]
10pub struct SLPPermutation {
11    /// The product of a SLP and a Permutation.
12    pub element : (SLP, Permutation),
13}
14
15impl SLPPermutation {
16    /// Create an `SLPPermutation`.
17    pub fn new(slp: SLP, permutation: Permutation) -> SLPPermutation {
18        SLPPermutation { element : (slp, permutation) }
19    }
20
21    /// Map the `SLPPermutation` in to a `Word` according to the `Morphism`.
22    pub fn transform(&self, morphism: &Morphism<SLP, Word>) -> Word {
23        self.element.0.transform(&morphism)
24    }
25}
26
27impl GroupElement for SLPPermutation {
28    fn is_identity(&self) -> bool {
29        self.element.1.is_identity()
30    }
31
32    fn times(&self, multiplicant: &SLPPermutation) -> SLPPermutation {
33        SLPPermutation::new(
34            self.element.0.times(&multiplicant.element.0),
35            self.element.1.times(&multiplicant.element.1))
36    }
37
38    fn inverse(&self) -> SLPPermutation {
39        SLPPermutation::new(
40            self.element.0.inverse(),
41            self.element.1.inverse())
42    }
43}
44
45impl GroupAction for SLPPermutation {
46    type Domain = u64;
47
48    fn act_on(&self, original: &u64) -> u64 {
49        self.element.1.act_on(original)
50    }
51}
52
53#[cfg(test)]
54mod tests {
55    use std::collections::HashMap;
56    use super::super::{GroupElement, GroupAction};
57    use super::super::tree::SLP;
58    use super::super::permutation::Permutation;
59    use super::SLPPermutation;
60
61    #[test]
62    fn slp_permutaion_should_know_when_it_is_the_identity() {
63        let mut not_identity_images = HashMap::new();
64        not_identity_images.insert(0u64, 1u64);
65        not_identity_images.insert(1u64, 0u64);
66        let not_identity: SLPPermutation = SLPPermutation::new(
67            SLP::Generator(1),
68            Permutation::new(not_identity_images));
69
70        assert!(!not_identity.is_identity());
71
72        let mut identity_images = HashMap::new();
73        identity_images.insert(0u64, 0u64);
74        identity_images.insert(1u64, 1u64);
75        let identity: SLPPermutation = SLPPermutation::new(
76            SLP::Identity,
77            Permutation::new(identity_images));
78
79        assert!(identity.is_identity());
80    }
81
82    #[test]
83    fn multiplication_should_be_from_left_to_right() {
84        let mut first_images = HashMap::new();
85        first_images.insert(0u64, 1u64);
86        first_images.insert(1u64, 0u64);
87        first_images.insert(2u64, 2u64);
88        let first: SLPPermutation = SLPPermutation::new(
89            SLP::Generator(1),
90            Permutation::new(first_images));
91
92        let mut second_images = HashMap::new();
93        second_images.insert(0u64, 0u64);
94        second_images.insert(1u64, 2u64);
95        second_images.insert(2u64, 1u64);
96        let second: SLPPermutation = SLPPermutation::new(
97            SLP::Generator(2),
98            Permutation::new(second_images));
99
100        let product = first.times(&second);
101
102        let mut expected_images = HashMap::new();
103        expected_images.insert(0u64, 2u64);
104        expected_images.insert(1u64, 0u64);
105        expected_images.insert(2u64, 1u64);
106        let expected: SLPPermutation = SLPPermutation::new(
107            SLP::Product(Box::new(SLP::Generator(1)), Box::new(SLP::Generator(2))),
108            Permutation::new(expected_images));
109
110        assert_eq!(product, expected);
111    }
112
113    #[test]
114    fn inverse_should_multiply_to_identity() {
115        let mut first_images = HashMap::new();
116        first_images.insert(0u64, 1u64);
117        first_images.insert(1u64, 2u64);
118        first_images.insert(2u64, 0u64);
119        let first: SLPPermutation = SLPPermutation::new(
120            SLP::Generator(1),
121            Permutation::new(first_images));
122
123        let second = first.inverse();
124
125        let product = first.times(&second);
126
127        assert!(product.is_identity());
128    }
129
130    #[test]
131    fn permutation_should_act_upon_integers() {
132        let mut permutation_images = HashMap::new();
133        permutation_images.insert(0u64, 1u64);
134        permutation_images.insert(1u64, 2u64);
135        permutation_images.insert(2u64, 0u64);
136        let permutation: SLPPermutation = SLPPermutation::new(
137            SLP::Generator(1),
138            Permutation::new(permutation_images));
139
140        assert_eq!(permutation.act_on(&0u64), 1u64);
141        assert_eq!(permutation.act_on(&1u64), 2u64);
142        assert_eq!(permutation.act_on(&2u64), 0u64);
143    }
144
145    // #[test]
146    // fn permutation_should_display_correctly() {
147    //     let mut identity_images = HashMap::new();
148    //     identity_images.insert(0u64, 0u64);
149    //     identity_images.insert(1u64, 1u64);
150    //     let identity = Permutation::new(identity_images);
151
152    //     let mut permutation_images = HashMap::new();
153    //     permutation_images.insert(0u64, 1u64);
154    //     permutation_images.insert(1u64, 2u64);
155    //     permutation_images.insert(2u64, 0u64);
156    //     permutation_images.insert(3u64, 4u64);
157    //     permutation_images.insert(4u64, 3u64);
158    //     let permutation = Permutation::new(permutation_images);
159
160    //     assert_eq!("Id", format!("{}", identity));
161    //     assert_eq!("(0 1 2)(3 4)", format!("{}", permutation));
162    // }
163}