{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
module IntervalAlgebra.Arbitrary
( arbitraryWithRelation
) where
import Control.Applicative ( (<$>)
, liftA2
)
import Control.Monad ( liftM2 )
import Data.Bool
import Data.Fixed
import Data.Function ( ($)
, (.)
, flip
)
import Data.Maybe ( Maybe(Just, Nothing) )
import Data.Ord
import qualified Data.Set ( Set
, difference
, null
, singleton
)
import Data.Time as DT
( Day(ModifiedJulianDay)
, DiffTime
, NominalDiffTime
, UTCTime(..)
, picosecondsToDiffTime
, secondsToDiffTime
, secondsToNominalDiffTime
, toModifiedJulianDay
)
import GHC.Float
import GHC.Int ( Int )
import GHC.Num
import GHC.Real
import IntervalAlgebra ( Interval
, IntervalRelation(..)
, IntervalSizeable
, Intervallic
, PairedInterval
, beginerval
, converse
, duration
, makePairedInterval
, moment
, predicate
, strictWithinRelations
)
import Prelude ( (==)
, Eq
)
import Test.QuickCheck ( Arbitrary(arbitrary, shrink)
, Gen
, NonNegative
, arbitrarySizedNatural
, elements
, resize
, sized
, suchThat
)
arbitrarySizedPositive :: Integral a => Gen a
arbitrarySizedPositive :: Gen a
arbitrarySizedPositive = (a -> a -> a
forall a. Num a => a -> a -> a
+ a
1) (a -> a) -> Gen a -> Gen a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen a
forall a. Integral a => Gen a
arbitrarySizedNatural
maxDiffTime :: Int
maxDiffTime :: Int
maxDiffTime = Int
86399
instance Arbitrary DT.Day where
arbitrary :: Gen Day
arbitrary = (Int -> Gen Day) -> Gen Day
forall a. (Int -> Gen a) -> Gen a
sized (\Int
s -> Integer -> Day
DT.ModifiedJulianDay (Integer -> Day) -> Gen Integer -> Gen Day
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Int
s Int -> Gen Integer -> Gen Integer
forall a. Int -> Gen a -> Gen a
`resize` Gen Integer
forall a. Arbitrary a => Gen a
arbitrary)
shrink :: Day -> [Day]
shrink = (Integer -> Day
DT.ModifiedJulianDay (Integer -> Day) -> [Integer] -> [Day]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>) ([Integer] -> [Day]) -> (Day -> [Integer]) -> Day -> [Day]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> [Integer]
forall a. Arbitrary a => a -> [a]
shrink (Integer -> [Integer]) -> (Day -> Integer) -> Day -> [Integer]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Day -> Integer
DT.toModifiedJulianDay
instance Arbitrary DT.NominalDiffTime where
arbitrary :: Gen NominalDiffTime
arbitrary = (Int -> Gen NominalDiffTime) -> Gen NominalDiffTime
forall a. (Int -> Gen a) -> Gen a
sized
(\Int
s -> Integer -> NominalDiffTime
forall a. Num a => Integer -> a
fromInteger (Integer -> NominalDiffTime) -> Gen Integer -> Gen NominalDiffTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
s Int
maxDiffTime Int -> Gen Integer -> Gen Integer
forall a. Int -> Gen a -> Gen a
`resize` Gen Integer
forall a. Integral a => Gen a
arbitrarySizedNatural))
instance Arbitrary DT.DiffTime where
arbitrary :: Gen DiffTime
arbitrary = (Int -> Gen DiffTime) -> Gen DiffTime
forall a. (Int -> Gen a) -> Gen a
sized
(\Int
s -> Integer -> DiffTime
forall a. Num a => Integer -> a
fromInteger (Integer -> DiffTime) -> Gen Integer -> Gen DiffTime
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min Int
s Int
maxDiffTime Int -> Gen Integer -> Gen Integer
forall a. Int -> Gen a -> Gen a
`resize` Gen Integer
forall a. Integral a => Gen a
arbitrarySizedNatural))
instance Arbitrary DT.UTCTime where
arbitrary :: Gen UTCTime
arbitrary = (Day -> DiffTime -> UTCTime)
-> Gen Day -> Gen DiffTime -> Gen UTCTime
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Day -> DiffTime -> UTCTime
UTCTime Gen Day
forall a. Arbitrary a => Gen a
arbitrary Gen DiffTime
forall a. Arbitrary a => Gen a
arbitrary
arbitraryWithRelation
:: forall i a b
. (IntervalSizeable a b, Intervallic i, Arbitrary (i a))
=> i a
-> Data.Set.Set IntervalRelation
-> Gen (Maybe (i a))
arbitraryWithRelation :: i a -> Set IntervalRelation -> Gen (Maybe (i a))
arbitraryWithRelation i a
iv Set IntervalRelation
rs
| Set IntervalRelation
rs Set IntervalRelation -> Set IntervalRelation -> Bool
forall a. Eq a => a -> a -> Bool
== IntervalRelation -> Set IntervalRelation
forall a. a -> Set a
Data.Set.singleton IntervalRelation
Equals = [Maybe (i a)] -> Gen (Maybe (i a))
forall a. [a] -> Gen a
elements [i a -> Maybe (i a)
forall a. a -> Maybe a
Just i a
iv]
| Bool
isEnclose Bool -> Bool -> Bool
&& Bool
isMom = [Maybe (i a)] -> Gen (Maybe (i a))
forall a. [a] -> Gen a
elements [Maybe (i a)
forall a. Maybe a
Nothing]
| Bool
isMom = i a -> Maybe (i a)
forall a. a -> Maybe a
Just (i a -> Maybe (i a)) -> Gen (i a) -> Gen (Maybe (i a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (i a)
forall a. Arbitrary a => Gen a
arbitrary Gen (i a) -> (i a -> Bool) -> Gen (i a)
forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` Set IntervalRelation -> ComparativePredicateOf2 (i a) (i a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Ord a, Intervallic i0, Intervallic i1) =>
Set IntervalRelation -> ComparativePredicateOf2 (i0 a) (i1 a)
predicate Set IntervalRelation
notStrictEnclose i a
iv
| Bool
otherwise = i a -> Maybe (i a)
forall a. a -> Maybe a
Just (i a -> Maybe (i a)) -> Gen (i a) -> Gen (Maybe (i a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen (i a)
forall a. Arbitrary a => Gen a
arbitrary Gen (i a) -> (i a -> Bool) -> Gen (i a)
forall a. Gen a -> (a -> Bool) -> Gen a
`suchThat` Set IntervalRelation -> ComparativePredicateOf2 (i a) (i a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Ord a, Intervallic i0, Intervallic i1) =>
Set IntervalRelation -> ComparativePredicateOf2 (i0 a) (i1 a)
predicate Set IntervalRelation
rs i a
iv
where
notStrictEnclose :: Set IntervalRelation
notStrictEnclose = Set IntervalRelation
-> Set IntervalRelation -> Set IntervalRelation
forall a. Ord a => Set a -> Set a -> Set a
Data.Set.difference Set IntervalRelation
rs (Set IntervalRelation -> Set IntervalRelation
converse Set IntervalRelation
strictWithinRelations)
isEnclose :: Bool
isEnclose = Set IntervalRelation -> Bool
forall a. Set a -> Bool
Data.Set.null Set IntervalRelation
notStrictEnclose
isMom :: Bool
isMom = i a -> b
forall a b (i :: * -> *).
(IntervalSizeable a b, Intervallic i) =>
i a -> b
duration i a
iv b -> b -> Bool
forall a. Eq a => a -> a -> Bool
== forall b a. IntervalSizeable a b => b
forall a b a. IntervalSizeable a b => b
moment @a