    --------------------------------------------------------------------
    -- |
    -- Module    : Test.SmallCheck
    -- Copyright : (c) Colin Runciman et al.
    -- License   : BSD3
    -- Maintainer: Roman Cheplyaka <roma@ro-che.info>
    --
    -- This module exports the main pieces of SmallCheck functionality.
    --
    -- To generate test cases for your own types, refer to
    -- "Test.SmallCheck.Series".
    --
    -- For pointers to other sources of information about SmallCheck, please refer
    -- to the README at
    -- <https://github.com/Bodigrim/smallcheck/blob/master/README.md>
    --------------------------------------------------------------------

    {-# LANGUAGE CPP #-}
    {-# LANGUAGE NoImplicitPrelude #-}
    #if __GLASGOW_HASKELL__ >= 704
    {-# LANGUAGE Safe #-}
    #endif

    module Test.SmallCheck (
      -- * Constructing tests

      -- | The simplest kind of test is a function (possibly of many
      -- arguments) returning 'Data.Bool.Bool'. The function arguments are interpreted
      -- as being universally, existentially or uniquely quantified, depending
      -- on the quantification context.
      --
      -- The default quantification context is universal ('forAll').
      --
      -- 'forAll', 'exists' and 'existsUnique' functions set the quantification
      -- context for function arguments. Depending on the quantification
      -- context, the test @\\x y -> p x y@ may be equivalent to:
      --
      -- * \( \forall x, y\colon p\, x \, y \) ('forAll'),
      --
      -- * \( \exists x, y\colon p\, x \, y \) ('exists'),
      --
      -- * \( \exists! x, y\colon p\, x \, y \) ('existsUnique').
      --
      -- The quantification context affects all the variables immediately
      -- following the quantification operator, also extending past 'over',
      -- 'changeDepth' and 'changeDepth1' functions.
      --
      -- However, it doesn't extend past other functions, like 'monadic', and
      -- doesn't affect the operands of '==>'. Such functions start a fresh
      -- default quantification context.

      -- ** Examples

      -- |
      -- * @\\x y -> p x y@ means
      --   \( \forall x, y\colon p\, x \, y \).
      --
      -- * @'exists' $ \\x y -> p x y@ means
      --   \( \exists x, y\colon p\, x \, y \).
      --
      -- * @'exists' $ \\x -> 'forAll' $ \\y -> p x y@ means
      --   \( \exists x\colon \forall y\colon p \, x \, y  \).
      --
      -- * @'existsUnique' $ \\x y -> p x y@ means
      --   \( \exists! x, y\colon p\, x \, y \).
      --
      -- * @'existsUnique' $ \\x -> 'over' s $ \\y -> p x y@ means
      --   \( \exists! x, y \colon y \in s \wedge p \, x \, y \).
      --
      -- * @'existsUnique' $ \\x -> 'monadic' $ \\y -> p x y@ means
      --   \( \exists! x \colon \forall y \colon [p \, x \, y] \).
      --
      -- * @'existsUnique' $ \\x -> 'existsUnique' $ \\y -> p x y@ means
      --   \( \exists! x \colon \exists! y \colon p \, x \, y \).
      --
      -- * @'exists' $ \\x -> (\\y -> p y) '==>' (\\z -> q z)@ means
      --   \( \exists x \colon (\forall y\colon p\, y) \implies (\forall z\colon q\, z)  \).

      forAll,
      exists,
      existsUnique,
      over,
      monadic,

      (==>),
      changeDepth,
      changeDepth1,

      -- * Running tests
      -- | 'smallCheck' is a simple way to run a test.
      --
      -- As an alternative, consider using a testing framework.
      --
      -- The packages
      -- <http://hackage.haskell.org/package/tasty-smallcheck> and
      -- <http://hackage.haskell.org/package/hspec-smallcheck>
      -- provide integration with Tasty and HSpec, two popular testing
      -- frameworks.
      --
      -- They allow to organize SmallCheck properties into a test suite (possibly
      -- together with HUnit or QuickCheck tests) and provide other useful
      -- features.
      --
      -- For more ways to run the tests, see "Test.SmallCheck.Drivers".
      Depth,
      smallCheck,

      -- * Main types and classes
      Testable(..),
      Property,
      Reason

      ) where

    import Test.SmallCheck.Property
    import Test.SmallCheck.Drivers