// // # Example: The game of _rock_, _paper_, _scissors_. // // The values {`R`,`P`, `S`} representing the choices in a game of rock, // paper, scissors [RPS] form a _magma_. In this game plays are // commutative, but _not_ associative, so they do not form a semigroup // or other derived algebraic structure. // // [RPS]: https://en.wikipedia.org/wiki/Commutative_magma // #![allow(non_snake_case)] use proptest_derive::*; use un_algebra::tests::*; use un_algebra::prelude::*; // // The game choices in rock, paper, scissors. // #[derive(Copy, Clone, PartialEq, Debug, Arbitrary)] pub enum RPS { R, P, S } // // Rock, paper, scissors choices form a magma. // impl Magma for RPS { // Magma operation as per the game rules. fn op(&self, other: &Self) -> Self { // Redundant branch expressions used for clarity. match (self, other) { (RPS::R, RPS::R) => RPS::R, (RPS::R, RPS::P) => RPS::P, (RPS::R, RPS::S) => RPS::R, (RPS::P, RPS::R) => RPS::P, (RPS::P, RPS::P) => RPS::P, (RPS::P, RPS::S) => RPS::S, (RPS::S, RPS::R) => RPS::R, (RPS::S, RPS::P) => RPS::S, (RPS::S, RPS::S) => RPS::S } } } // // Generative tests of rock, paper, scissors algebraic axioms. // proptest! { #![proptest_config(config::standard())] #[test] fn closure((x, y) in any::<(RPS, RPS)>()) { prop_assert!(MagmaLaws::closure(&x, &y)) } #[test] fn closure_t2([xs, ys] in any::<[(RPS, RPS); 2]>()) { prop_assert!(MagmaLaws::closure(&xs, &ys)) } #[test] fn closure_a2([xs, ys] in any::<[[RPS; 2]; 2]>()) { prop_assert!(MagmaLaws::closure(&xs, &ys)) } #[test] fn commutivity((x, y) in any::<(RPS, RPS)>()) { prop_assert!(x.op(&y) == y.op(&x)) } #[test] fn commutivity_t1((x, y) in any::<(RPS, RPS)>()) { prop_assert!((x,).op(&(y,)) == (y,).op(&(x,))) } #[test] fn commutivity_a1((x, y) in any::<(RPS, RPS)>()) { prop_assert!([x].op(&[y]) == [y].op(&[x])) } } fn main() { }