    {-# LANGUAGE ScopedTypeVariables #-}

    {-# OPTIONS_GHC -Wall #-}

    module Test.QuickCheck.Classes.Ix
      ( ixLaws
      ) where

    import Data.Ix (Ix(..))
    import Data.Proxy (Proxy)
    import Test.QuickCheck hiding ((.&.))
    import Test.QuickCheck.Property (Property)

    import Test.QuickCheck.Classes.Internal (Laws(..))

    -- | Tests the various 'Ix' properties:
    --
    --   @'inRange' (l,u) i '==' 'elem' i ('range' (l,u))@
    --
    --   @'range' (l,u) '!!' 'index' (l,u) i '==' i@, when @'inRange' (l,u) i@
    --
    --   @'map' ('index' (l,u)) ('range' (l,u)) '==' [0 .. 'rangeSize' (l,u) - 1]@
    --
    --   @'rangeSize' (l,u) '==' 'length' ('range' (l,u))@
    ixLaws :: (Ix a, Arbitrary a, Show a) => Proxy a -> Laws
    ixLaws :: forall a. (Ix a, Arbitrary a, Show a) => Proxy a -> Laws
    ixLaws Proxy a
    p = String -> [(String, Property)] -> Laws
    Laws String
    "Ix"
      [ (String
    "InRange", Proxy a -> Property
    forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixInRange Proxy a
    p)
      , (String
    "RangeIndex", Proxy a -> Property
    forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixRangeIndex Proxy a
    p)
      , (String
    "MapIndexRange", Proxy a -> Property
    forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixMapIndexRange Proxy a
    p)
      , (String
    "RangeSize", Proxy a -> Property
    forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixRangeSize Proxy a
    p)
      ]

    ixInRange :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixInRange :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixInRange Proxy a
    _ = (a -> a -> a -> Property) -> Property
    forall prop. Testable prop => prop -> Property
    property ((a -> a -> a -> Property) -> Property)
    -> (a -> a -> a -> Property) -> Property
    forall a b. (a -> b) -> a -> b
    $ \(a
    l :: a) (a
    u :: a) (a
    i :: a) -> (a
    l a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a
    u) Bool -> Bool -> Property
    forall prop. Testable prop => Bool -> prop -> Property
    ==> do
      (a, a) -> a -> Bool
    forall a. Ix a => (a, a) -> a -> Bool
    inRange (a
    l,a
    u) a
    i Bool -> Bool -> Bool
    forall a. Eq a => a -> a -> Bool
    == a -> [a] -> Bool
    forall a. Eq a => a -> [a] -> Bool
    forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
    elem a
    i ((a, a) -> [a]
    forall a. Ix a => (a, a) -> [a]
    range (a
    l,a
    u))

    ixRangeIndex :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixRangeIndex :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixRangeIndex Proxy a
    _ = (a -> a -> a -> Property) -> Property
    forall prop. Testable prop => prop -> Property
    property ((a -> a -> a -> Property) -> Property)
    -> (a -> a -> a -> Property) -> Property
    forall a b. (a -> b) -> a -> b
    $ \(a
    l :: a) (a
    u :: a) (a
    i :: a) -> ((a
    l a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a
    u) Bool -> Bool -> Bool
    && (a
    i a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    >= a
    l Bool -> Bool -> Bool
    && a
    i a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a
    u)) Bool -> Bool -> Property
    forall prop. Testable prop => Bool -> prop -> Property
    ==> do
      (a, a) -> [a]
    forall a. Ix a => (a, a) -> [a]
    range (a
    l,a
    u) [a] -> Int -> a
    forall a. HasCallStack => [a] -> Int -> a
    !! (a, a) -> a -> Int
    forall a. Ix a => (a, a) -> a -> Int
    index (a
    l,a
    u) a
    i a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == a
    i

    ixMapIndexRange :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixMapIndexRange :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixMapIndexRange Proxy a
    _ = (a -> a -> Property) -> Property
    forall prop. Testable prop => prop -> Property
    property ((a -> a -> Property) -> Property)
    -> (a -> a -> Property) -> Property
    forall a b. (a -> b) -> a -> b
    $ \(a
    l :: a) (a
    u :: a) -> (a
    l a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a
    u) Bool -> Bool -> Property
    forall prop. Testable prop => Bool -> prop -> Property
    ==> do
      (a -> Int) -> [a] -> [Int]
    forall a b. (a -> b) -> [a] -> [b]
    map ((a, a) -> a -> Int
    forall a. Ix a => (a, a) -> a -> Int
    index (a
    l,a
    u)) ((a, a) -> [a]
    forall a. Ix a => (a, a) -> [a]
    range (a
    l,a
    u)) [Int] -> [Int] -> Bool
    forall a. Eq a => a -> a -> Bool
    == [Int
    0 .. (a, a) -> Int
    forall a. Ix a => (a, a) -> Int
    rangeSize (a
    l,a
    u) Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Int
    1]

    ixRangeSize :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixRangeSize :: forall a. (Show a, Ix a, Arbitrary a) => Proxy a -> Property
    ixRangeSize Proxy a
    _ = (a -> a -> Property) -> Property
    forall prop. Testable prop => prop -> Property
    property ((a -> a -> Property) -> Property)
    -> (a -> a -> Property) -> Property
    forall a b. (a -> b) -> a -> b
    $ \(a
    l :: a) (a
    u :: a) -> (a
    l a -> a -> Bool
    forall a. Ord a => a -> a -> Bool
    <= a
    u) Bool -> Bool -> Property
    forall prop. Testable prop => Bool -> prop -> Property
    ==> do
      (a, a) -> Int
    forall a. Ix a => (a, a) -> Int
    rangeSize (a
    l,a
    u) Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == [a] -> Int
    forall a. [a] -> Int
    forall (t :: * -> *) a. Foldable t => t a -> Int
    length ((a, a) -> [a]
    forall a. Ix a => (a, a) -> [a]
    range (a
    l,a
    u))