# Speculate

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 tests enumeratively using LeanCheck,
QuickSpec tests randomly using QuickCheck;
- Speculate is able to report inequalities directly;
- QuickSpec allows polymorphism, Speculate does not;
- 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.
Speculate is also subject to a chapter in a PhD Thesis (2017).