un_algebra 0.9.0

Simple implementations of selected abstract algebraic structures--including groups, rings, and fields. Intended for self-study of abstract algebra concepts and not for production use.
//!
//! Algebraic semigroups.
//!
//! An algebraic _semigroup_ is a _magma_ `M`, where the binary
//! operation `∘` is _associative_.
//!
//! # Axioms
//!
//! ```text
//! ∀x, y, z ∈ M
//!
//! Associativity: (x ∘ y) ∘ z = x ∘ (y ∘ z).
//! ```
//!
//! # References
//!
//! See [references] for a formal definition of a semigroup.
//!
#![doc(include = "../../doc/references.md")]

use crate::magma::*;


///
/// An algebraic _semigroup_.
///
pub trait Semigroup: Magma {}


///
/// Laws of semigroups.
///
pub trait SemigroupLaws: Semigroup {

  /// The _associativity_ axiom.
  fn associativity(&self, x: &Self, y: &Self) -> bool {
      self.op(&x.op(y)) == self.op(x).op(y)
  }
}


///
/// Blanket implementation of semigroup laws for semigroup
/// implementations.
///
impl<S: Semigroup> SemigroupLaws for S {}


///
/// 0-tuples form a semigroup.
///
impl Semigroup for () {}


///
/// 1-tuples form a semigroup when their items do.
///
impl<A: Semigroup> Semigroup for (A,) {}


///
/// 2-tuples form a semigroup when their items do.
///
impl<A: Semigroup, B: Semigroup> Semigroup for (A, B) {}


///
/// 3-tuples form a semigroup when their items do.
///
impl<A: Semigroup, B: Semigroup, C: Semigroup> Semigroup for (A, B, C) {}


///
/// Define `Semigroup` implementations for arrays. Maybe not needed if
/// Rust had _const_ _generics_.
///
macro_rules! array_semigroup {
  ($size:expr) => {
    impl<T: Copy + Semigroup> Semigroup for [T; $size] {}
  };

  ($size:expr, $($others:expr),+) => {
    array_semigroup! {$size}
    array_semigroup! {$($others),+}
  };
}


// Array semigroup types.
array_semigroup! {
  0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
}