{-| Module : Clif.Arbitrary Copyright : (c) Matti A. Eskelinen, 2016-2017 License : MIT Maintainer : matti.a.eskelinen@gmail.com Stability : experimental Portability : POSIX This module provides (orphan) Arbitrary instances and various other generators for creating random 'Clif's and 'Basis' elements using "Test.QuickCheck". -} {-# OPTIONS_GHC -fno-warn-orphans #-} module Clif.Arbitrary ( -- * Generators ascList, ascLists , kBlade ) where import Clif.Basis import Clif.Internal import Data.List (nub) import Test.QuickCheck -- | Arbitrary instance for 'Euclidean' instance Arbitrary a => Arbitrary (Euclidean a) where arbitrary = E <$> arbitrary shrink = genericShrink -- | Arbitrary Instance for 'Lorentzian' instance Arbitrary a => Arbitrary (Lorentzian a) where arbitrary = elements [T, S] <*> arbitrary shrink = genericShrink -- | Arbitrary instance for a 'Clif' instance (Ord b, Arbitrary a, Arbitrary b) => Arbitrary (Clif b a) where arbitrary = Clif <$> arbitrary shrink = map Clif . shrink . unClif -- | 'orderedList' with only unique elements. -- Useful for generating blades with e.g. -- -- @ -- 'blade' '<$>' 'ascList' -- @ -- ascList :: (Ord a, Arbitrary a) => Gen [a] ascList = nub <$> orderedList -- | An ascending list split into two at a random point. Useful for generating a pair of blades without common vectors. ascLists :: (Ord a, Arbitrary a) => Gen ([a], [a]) ascLists = do xs <- ascList split <- elements [0..length xs] return $ splitAt split xs -- | Given k, returns a generator for k-blades ('Clif's containing only a single blade of grade k). kBlade :: (Eq a, Basis b a, Arbitrary a, Arbitrary b) => Int -> Gen (Clif b a) kBlade k = blade <$> vector k <*> arbitrary