The speculate package

[ Tags: bsd3, library, testing ] [ Propose Tags ]

Speculate automatically discovers laws about Haskell functions. Give Speculate a bunch of Haskell functions and it will discover laws like:


[Skip to Readme]

Properties

Versions 0.2.0, 0.2.1, 0.2.2, 0.2.3, 0.2.4, 0.2.5, 0.2.6, 0.2.7, 0.2.8, 0.2.9, 0.2.10, 0.3.0, 0.3.1
Dependencies base (==4.*), cmdargs, containers, leancheck (>=0.6.3) [details]
License BSD3
Author Rudy Matela, Colin Runciman
Maintainer Rudy Matela <rudy@matela.com.br>
Category Testing
Home page https://github.com/rudymatela/speculate#readme
Source repository head: git clone https://github.com/rudymatela/speculate
this: git clone https://github.com/rudymatela/speculate(tag v0.3.1)
Uploaded Wed Nov 22 15:21:38 UTC 2017 by rudymatela
Distributions NixOS:0.3.0, Stackage:0.3.0
Downloads 516 total (93 in the last 30 days)
Rating (no votes yet) [estimated by rule of succession]
Your Rating
  • λ
  • λ
  • λ
Status Docs available [build log]
Last success reported on 2017-11-22 [all 1 reports]
Hackage Matrix CI

Modules

[Index]

Downloads

Maintainer's Corner

For package maintainers and hackage trustees


Readme for speculate-0.3.1

[back to package description]

Speculate

Speculate Build Status Speculate on Hackage Speculate on Stackage LTS Speculate on Stackage Nightly

Speculate automatically discovers laws about Haskell functions. Give Speculate a bunch of Haskell functions and it will discover laws like:

  • equations, such as id x == x;
  • inequalities, such as 0 <= x * x;
  • conditional equations, such as x <= 0 ==> x + abs x == 0.

Speculate is similar to, and inspired by, QuickSpec.

Installing Speculate

To install the latest Speculate version from Hackage, just:

$ cabal update
$ cabal install speculate

Pre-requisites are cmdargs and leancheck. They should be automatically resolved and installed by Cabal.

Using Speculate

Speculate is used as a library: import it, then call the function speculate with relevant arguments. The following program Speculates about the functions (+) and abs:

import Test.Speculate

main :: IO ()
main = speculate args
  { constants =
      [ showConstant (0::Int)
      , showConstant (1::Int)
      , constant "+"   ((+)  :: Int -> Int -> Int)
      , constant "abs" (abs  :: Int -> Int)
      ]
  }

when run, it prints the following:

_ :: Int  (holes: Int)
0 :: Int
1 :: Int
(+) :: Int -> Int -> Int
abs :: Int -> Int

    abs (abs x) == abs x
          x + 0 == x
          x + y == y + x
    (x + y) + z == x + (y + z)
abs (x + abs x) == x + abs x
  abs x + abs x == abs (x + x)
abs (1 + abs x) == 1 + abs x

x <= abs x
0 <= abs x
x <= x + 1

Now, if we add <= and < as background constants on args

  , constants =
      [ showConstant (0::Int)
      , showConstant (1::Int)
      , constant "+"   ((+)  :: Int -> Int -> Int)
      , constant "abs" (abs  :: Int -> Int)
      , background
      , constant "<="  ((<=) :: Int -> Int -> Bool)
      , constant "<"   ((<)  :: Int -> Int -> Bool)
      ]

then run again, we get the following as well:

    y <= x ==> abs (x + abs y) == x + abs y
    x <= 0 ==>       x + abs x == 0
abs x <= y ==>     abs (x + y) == x + y
abs y <= x ==>     abs (x + y) == x + y

For more examples, see the eg folder.

Similarities and Differences to QuickSpec

Speculate is inspired by QuickSpec. Like QuickSpec, Speculate uses testing to speculate equational laws about given Haskell functions. There are some differences:

| | Speculate | QuickSpec | | ----------------: | ------------------------- | --------------------------------- | | testing | enumerative (LeanCheck) | random (QuickCheck) | | equational laws | yes (after completion) | yes (as discovered) | | inequational laws | yes | no | | conditional laws | yes | restricted to a set of predicates | | polymorphism | no | yes | | performance | slower | faster |

For most examples, Speculate runs slower than QuickSpec 2 but faster than QuickSpec 1.

More documentation

For more examples, see the eg and bench folders.

Speculate has been subject to a paper, see the Speculate Paper on Haskell Symposium 2017.