1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
pub mod modgroup;

use core::ops::{Add, Neg};

pub trait AddIdentity: Sized + Add<Output = Self> {
    /// the identity of mod add operation, typically zero
    const ADD_IDENTITY: Self;
    const ZERO: Self = Self::ADD_IDENTITY;
}

/// # Safety
/// 
/// this trait is safe only when for all a, b, c: a + (b + c) = (a + b) + c
pub trait AssociativeAdd: Sized + Add<Output = Self> {}

/// # Safety
/// 
/// this trait is safe only when for all a, b, a + b = b + a
pub trait CommunicativeAdd: Sized + Add<Output = Self> {}

/// A group on addition arithmetic
/// 
/// This arithmetic should satisfy the following propertise
/// 
/// 1. the set should be closed under addition
/// 2. the addition should be associativity
/// 3. the identity should exist
/// 4. there exists inverse of group element
pub trait Group:
    Sized + 
    Add<Output = Self> +   // 1. closed under addition
    AssociativeAdd +       // 2. addition is associated
    AddIdentity +          // 3. addition identity exists
    Neg<Output = Self>     // 4. addition inverse exists
{ }

/// A group is called a alelian group (or communicative group) if forall a, b in G, a + b = b + a
pub trait AbelianGroup: Group + CommunicativeAdd {}