All Downloads are FREE. Search and download functionalities are using the official Maven repository.

algebra.laws.Rules.scala Maven / Gradle / Ivy

The newest version!
package algebra
package laws

import org.scalacheck.{Arbitrary, Prop}
import org.scalacheck.Prop._
import Prop.{False, Proof, Result}

import algebra.std.boolean._

object Rules {

  def serializable[M](m: M): (String, Prop) = Platform.serializable(m)
 
  // Comparison operators for testing are supplied by CheckEqOps and
  // CheckOrderOps in package.scala. They are:
  //
  //    ?==  Ensure that x equals y
  //    ?!=  Ensure that x does not equal y
  //    ?<   Ensure that x < y
  //    ?<=  Ensure that x <= y
  //    ?>   Ensure that x > y
  //    ?>=  Ensure that x >= y
  //
  // The reason to prefer these operators is that when tests fail, we
  // will get more detaild output about what the failing values were
  // (in addition to the input values generated by ScalaCheck).

  def associativity[A: Arbitrary: Eq](f: (A, A) => A): (String, Prop) =
    "associativity" -> forAll { (x: A, y: A, z: A) =>
      f(f(x, y), z) ?== f(x, f(y, z))
    }

  def leftIdentity[A: Arbitrary: Eq](id: A)(f: (A, A) => A): (String, Prop) =
    "leftIdentity" -> forAll { (x: A) =>
      f(id, x) ?== x
    }

  def rightIdentity[A: Arbitrary: Eq](id: A)(f: (A, A) => A): (String, Prop) =
    "rightIdentity" -> forAll { (x: A) =>
      f(x, id) ?== x
    }

  def leftInverse[A: Arbitrary: Eq](id: A)(f: (A, A) => A)(inv: A => A): (String, Prop) =
    "left inverse" -> forAll { (x: A) =>
      id ?== f(inv(x), x)
    }

  def rightInverse[A: Arbitrary: Eq](id: A)(f: (A, A) => A)(inv: A => A): (String, Prop) =
    "right inverse" -> forAll { (x: A) =>
      id ?== f(x, inv(x))
    }

  def commutative[A: Arbitrary: Eq](f: (A, A) => A): (String, Prop) =
    "commutative" -> forAll { (x: A, y: A) =>
      f(x, y) ?== f(y, x)
    }

  def idempotence[A: Arbitrary: Eq](f: (A, A) => A): (String, Prop) =
    "idempotence" -> forAll { (x: A) =>
      f(x, x) ?== x
    }

  def consistentInverse[A: Arbitrary: Eq](name: String)(m: (A, A) => A)(f: (A, A) => A)(inv: A => A): (String, Prop) =
    s"consistent $name" -> forAll { (x: A, y: A) =>
      m(x, y) ?== f(x, inv(y))
    }

  def repeat0[A: Arbitrary: Eq](name: String, sym: String, id: A)(r: (A, Int) => A): (String, Prop) =
    s"$name(a, 0) == $sym" -> forAll { (a: A) =>
      r(a, 0) ?== id
    }

  def repeat1[A: Arbitrary: Eq](name: String)(r: (A, Int) => A): (String, Prop) =
    s"$name(a, 1) == a" -> forAll { (a: A) =>
      r(a, 1) ?== a
    }

  def repeat2[A: Arbitrary: Eq](name: String, sym: String)(r: (A, Int) => A)(f: (A, A) => A): (String, Prop) =
    s"$name(a, 2) == a $sym a" -> forAll { (a: A) =>
      r(a, 2) ?== f(a, a)
    }

  def collect0[A: Arbitrary: Eq](name: String, sym: String, id: A)(c: Seq[A] => A): (String, Prop) =
    s"$name(Nil) == $sym" -> forAll { (a: A) =>
      c(Nil) ?== id
    }

  def isId[A: Arbitrary: Eq](name: String, id: A)(p: A => Boolean): (String, Prop) =
    name -> forAll { (x: A) =>
      Eq.eqv(x, id) ?== p(x)
    }

  def distributive[A: Arbitrary: Eq](a: (A, A) => A)(m: (A, A) => A): (String, Prop) =
    "distributive" → forAll { (x: A, y: A, z: A) =>
      (m(x, a(y, z)) ?== a(m(x, y), m(x, z))) &&
      (m(a(x, y), z) ?== a(m(x, z), m(y, z)))
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy