{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
module IntervalAlgebra.IntervalUtilities
(
combineIntervals
, combineIntervalsFromSorted
, rangeInterval
, (><)
, (.+.)
, lookback
, lookahead
, gaps
, pairGaps
, relations
, intersect
, clip
, durations
) where
import Control.Applicative (Applicative (pure), liftA2,
(<$>), (<*>))
import qualified Control.Foldl as L
import Control.Monad (Functor (fmap))
import Data.Bool (Bool (..), not, otherwise,
(&&), (||))
import Data.Eq (Eq ((==)))
import Data.Foldable (Foldable (foldl', foldr, null, toList),
all, any, or)
import Data.Function (flip, ($), (.))
import Data.List (map, reverse, sortOn)
import Data.Maybe (Maybe (..), mapMaybe, maybe,
maybeToList)
import Data.Monoid (Monoid (mempty))
import Data.Ord (Ord (max, min), (<), (>=))
import Data.Semigroup (Semigroup ((<>)))
import Data.Traversable (Traversable (sequenceA))
import Data.Tuple (fst, uncurry)
import GHC.Int (Int)
import GHC.Show (Show)
import IntervalAlgebra.Core
import IntervalAlgebra.PairedInterval (PairedInterval, equalPairData,
getPairData,
makePairedInterval)
pairGaps
:: (Intervallic i, SizedIv (Interval a), Ord a, Ord (Moment (Interval a)))
=> [i a]
-> [Maybe (Moment (Interval a))]
pairGaps :: [i a] -> [Maybe (Moment (Interval a))]
pairGaps [i a]
es = ((i a, i a) -> Maybe (Moment (Interval a)))
-> [(i a, i a)] -> [Maybe (Moment (Interval a))]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Interval a -> Moment (Interval a))
-> Maybe (Interval a) -> Maybe (Moment (Interval a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Interval a -> Moment (Interval a)
forall iv. SizedIv iv => iv -> Moment iv
duration (Maybe (Interval a) -> Maybe (Moment (Interval a)))
-> ((i a, i a) -> Maybe (Interval a))
-> (i a, i a)
-> Maybe (Moment (Interval a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (i a -> i a -> Maybe (Interval a))
-> (i a, i a) -> Maybe (Interval a)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry i a -> i a -> Maybe (Interval a)
forall a (i :: * -> *).
(Iv (Interval a), Ord (Moment (Interval a)), SizedIv (Interval a),
Intervallic i) =>
i a -> i a -> Maybe (Interval a)
(><)) ([i a] -> [(i a, i a)]
forall t. [t] -> [(t, t)]
pairs [i a]
es)
where
pairs :: [t] -> [(t, t)]
pairs = [t] -> [(t, t)]
forall t. [t] -> [(t, t)]
go
where
go :: [t] -> [(t, t)]
go [] = []
go (t
x : [t]
xs) = (t -> (t, t)) -> [t] -> [(t, t)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (t
x, ) [t]
xs [(t, t)] -> [(t, t)] -> [(t, t)]
forall a. Semigroup a => a -> a -> a
<> [t] -> [(t, t)]
go [t]
xs
lookback
:: (Intervallic i, SizedIv (Interval a), Ord (Moment (Interval a)))
=> Moment (Interval a)
-> i a
-> Interval a
lookback :: Moment (Interval a) -> i a -> Interval a
lookback Moment (Interval a)
d i a
x = Moment (Interval a) -> a -> Interval a
forall a.
SizedIv (Interval a) =>
Moment (Interval a) -> a -> Interval a
enderval Moment (Interval a)
d (i a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin i a
x)
lookahead
:: (Intervallic i, SizedIv (Interval a), Ord (Moment (Interval a)))
=> Moment (Interval a)
-> i a
-> Interval a
lookahead :: Moment (Interval a) -> i a -> Interval a
lookahead Moment (Interval a)
d i a
x = Moment (Interval a) -> a -> Interval a
forall a.
SizedIv (Interval a) =>
Moment (Interval a) -> a -> Interval a
beginerval Moment (Interval a)
d (i a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end i a
x)
relations
:: ( Intervallic i
, Iv (Interval a)
)
=> [i a]
-> [IntervalRelation]
relations :: [i a] -> [IntervalRelation]
relations [] = []
relations [i a
x] = []
relations (i a
x : i a
y : [i a]
xs) = i a -> i a -> IntervalRelation
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
i0 a -> i1 a -> IntervalRelation
relate i a
x i a
y IntervalRelation -> [IntervalRelation] -> [IntervalRelation]
forall a. a -> [a] -> [a]
: [i a] -> [IntervalRelation]
forall (i :: * -> *) a.
(Intervallic i, Iv (Interval a)) =>
[i a] -> [IntervalRelation]
relations (i a
y i a -> [i a] -> [i a]
forall a. a -> [a] -> [a]
: [i a]
xs)
intersect
:: (Intervallic i, SizedIv (Interval a), Ord a, Ord (Moment (Interval a))) => i a -> i a -> Maybe (Interval a)
intersect :: i a -> i a -> Maybe (Interval a)
intersect i a
x i a
y | ComparativePredicateOf2 (i a) (i a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(SizedIv (Interval a), Ord a, Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
disjoint i a
x i a
y = Maybe (Interval a)
forall a. Maybe a
Nothing
| Bool
otherwise = Interval a -> Maybe (Interval a)
forall a. a -> Maybe a
Just (Interval a -> Maybe (Interval a))
-> Interval a -> Maybe (Interval a)
forall a b. (a -> b) -> a -> b
$ (a, a) -> Interval a
forall a.
(SizedIv (Interval a), Ord (Moment (Interval a))) =>
(a, a) -> Interval a
safeInterval (a
b, a
e)
where
b :: a
b = a -> a -> a
forall a. Ord a => a -> a -> a
max (i a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin i a
x) (i a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin i a
y)
e :: a
e = a -> a -> a
forall a. Ord a => a -> a -> a
min (i a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end i a
x) (i a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end i a
y)
gaps :: (
SizedIv (Interval a),
Intervallic i,
Ord a,
Ord (Moment (Interval a))
) =>
[i a] ->
[Interval a]
gaps :: [i a] -> [Interval a]
gaps [i a]
xs = ((i a, i a) -> Maybe (Interval a)) -> [(i a, i a)] -> [Interval a]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe ((i a -> i a -> Maybe (Interval a))
-> (i a, i a) -> Maybe (Interval a)
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry i a -> i a -> Maybe (Interval a)
forall a (i :: * -> *).
(Iv (Interval a), Ord (Moment (Interval a)), SizedIv (Interval a),
Intervallic i) =>
i a -> i a -> Maybe (Interval a)
(><)) ([(i a, i a)] -> [Interval a]) -> [(i a, i a)] -> [Interval a]
forall a b. (a -> b) -> a -> b
$ [i a] -> [(i a, i a)]
forall t. [t] -> [(t, t)]
pair ([i a] -> [(i a, i a)]) -> [i a] -> [(i a, i a)]
forall a b. (a -> b) -> a -> b
$ (i a -> Interval a) -> [i a] -> [i a]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn i a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval [i a]
xs
where pair :: [a] -> [(a, a)]
pair [] = []
pair [a
x] = []
pair (a
x : a
y : [a]
ys) = (a
x, a
y) (a, a) -> [(a, a)] -> [(a, a)]
forall a. a -> [a] -> [a]
: [a] -> [(a, a)]
pair (a
y a -> [a] -> [a]
forall a. a -> [a] -> [a]
: [a]
ys)
durations :: (Functor f, Intervallic i, SizedIv (Interval a)) => f (i a) -> f (Moment (Interval a))
durations :: f (i a) -> f (Moment (Interval a))
durations = (i a -> Moment (Interval a)) -> f (i a) -> f (Moment (Interval a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Interval a -> Moment (Interval a)
forall iv. SizedIv iv => iv -> Moment iv
duration (Interval a -> Moment (Interval a))
-> (i a -> Interval a) -> i a -> Moment (Interval a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval)
clip
:: (Intervallic i0, Intervallic i1, SizedIv (Interval a), Ord a, Ord (Moment (Interval a)))
=> i0 a
-> i1 a
-> Maybe (Interval a)
clip :: i0 a -> i1 a -> Maybe (Interval a)
clip i0 a
x i1 a
y
| ComparativePredicateOf2 (i0 a) (i1 a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
overlaps i0 a
x i1 a
y = Interval a -> Maybe (Interval a)
forall a. a -> Maybe a
Just (Interval a -> Maybe (Interval a))
-> Interval a -> Maybe (Interval a)
forall a b. (a -> b) -> a -> b
$ (a, a) -> Interval a
forall a.
(SizedIv (Interval a), Ord (Moment (Interval a))) =>
(a, a) -> Interval a
safeInterval (i1 a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin i1 a
y, i0 a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end i0 a
x)
| ComparativePredicateOf2 (i0 a) (i1 a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
overlappedBy i0 a
x i1 a
y = Interval a -> Maybe (Interval a)
forall a. a -> Maybe a
Just (Interval a -> Maybe (Interval a))
-> Interval a -> Maybe (Interval a)
forall a b. (a -> b) -> a -> b
$ (a, a) -> Interval a
forall a.
(SizedIv (Interval a), Ord (Moment (Interval a))) =>
(a, a) -> Interval a
safeInterval (i0 a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin i0 a
x, i1 a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end i1 a
y)
| ComparativePredicateOf2 (i0 a) (i1 a)
jx i0 a
x i1 a
y = Interval a -> Maybe (Interval a)
forall a. a -> Maybe a
Just (i0 a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval i0 a
x)
| ComparativePredicateOf2 (i0 a) (i1 a)
jy i0 a
x i1 a
y = Interval a -> Maybe (Interval a)
forall a. a -> Maybe a
Just (i1 a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval i1 a
y)
| Bool
otherwise = Maybe (Interval a)
forall a. Maybe a
Nothing
where
jy :: ComparativePredicateOf2 (i0 a) (i1 a)
jy = ComparativePredicateOf2 (i0 a) (i1 a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
equals ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
forall (i0 :: * -> *) (i1 :: * -> *) a.
(Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
<|> ComparativePredicateOf2 (i0 a) (i1 a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
startedBy ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
forall (i0 :: * -> *) (i1 :: * -> *) a.
(Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
<|> ComparativePredicateOf2 (i0 a) (i1 a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
contains ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
forall (i0 :: * -> *) (i1 :: * -> *) a.
(Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
<|> ComparativePredicateOf2 (i0 a) (i1 a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
finishedBy
jx :: ComparativePredicateOf2 (i0 a) (i1 a)
jx = ComparativePredicateOf2 (i0 a) (i1 a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
starts ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
forall (i0 :: * -> *) (i1 :: * -> *) a.
(Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
<|> ComparativePredicateOf2 (i0 a) (i1 a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
during ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
forall (i0 :: * -> *) (i1 :: * -> *) a.
(Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
-> ComparativePredicateOf2 (i0 a) (i1 a)
<|> ComparativePredicateOf2 (i0 a) (i1 a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
finishes
{-# INLINABLE clip #-}
combineIntervals :: (SizedIv (Interval a), Intervallic i, Ord a) => [i a] -> [Interval a]
combineIntervals :: [i a] -> [Interval a]
combineIntervals = [i a] -> [Interval a]
forall a (i :: * -> *).
(Ord a, Intervallic i, SizedIv (Interval a)) =>
[i a] -> [Interval a]
combineIntervalsFromSorted ([i a] -> [Interval a])
-> ([i a] -> [i a]) -> [i a] -> [Interval a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (i a -> Interval a) -> [i a] -> [i a]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn i a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval
combineIntervalsFromSorted
:: forall a i . (Ord a, Intervallic i, SizedIv (Interval a)) => [i a] -> [Interval a]
combineIntervalsFromSorted :: [i a] -> [Interval a]
combineIntervalsFromSorted = [Interval a] -> [Interval a]
forall a. [a] -> [a]
reverse ([Interval a] -> [Interval a])
-> ([i a] -> [Interval a]) -> [i a] -> [Interval a]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([Interval a] -> i a -> [Interval a])
-> [Interval a] -> [i a] -> [Interval a]
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' [Interval a] -> i a -> [Interval a]
forall (i1 :: * -> *) a.
(Intervallic i1, Ord a, SizedIv (Interval a)) =>
[Interval a] -> i1 a -> [Interval a]
op []
where
op :: [Interval a] -> i1 a -> [Interval a]
op [] i1 a
y = [i1 a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval i1 a
y]
op (Interval a
x : [Interval a]
xs) i1 a
y = if Interval a
x ComparativePredicateOf2 (Interval a) (i1 a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
`before` i1 a
y
then Interval a
yiv Interval a -> [Interval a] -> [Interval a]
forall a. a -> [a] -> [a]
: Interval a
x Interval a -> [Interval a] -> [Interval a]
forall a. a -> [a] -> [a]
: [Interval a]
xs
else Interval a -> Interval a -> Interval a
forall a (i :: * -> *).
(SizedIv (Interval a), Ord a, Intervallic i) =>
i a -> i a -> Interval a
extenterval Interval a
x Interval a
yiv Interval a -> [Interval a] -> [Interval a]
forall a. a -> [a] -> [a]
: [Interval a]
xs
where yiv :: Interval a
yiv = i1 a -> Interval a
forall (i :: * -> *) a. Intervallic i => i a -> Interval a
getInterval i1 a
y
rangeInterval :: (L.Foldable t, Ord a, SizedIv (Interval a)) => t (Interval a) -> Maybe (Interval a)
rangeInterval :: t (Interval a) -> Maybe (Interval a)
rangeInterval = Fold (Interval a) (Maybe (Interval a))
-> t (Interval a) -> Maybe (Interval a)
forall (f :: * -> *) a b. Foldable f => Fold a b -> f a -> b
L.fold ((Interval a -> Interval a -> Interval a)
-> Maybe (Interval a) -> Maybe (Interval a) -> Maybe (Interval a)
forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Interval a -> Interval a -> Interval a
forall a (i :: * -> *).
(SizedIv (Interval a), Ord a, Intervallic i) =>
i a -> i a -> Interval a
extenterval (Maybe (Interval a) -> Maybe (Interval a) -> Maybe (Interval a))
-> Fold (Interval a) (Maybe (Interval a))
-> Fold (Interval a) (Maybe (Interval a) -> Maybe (Interval a))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Fold (Interval a) (Maybe (Interval a))
forall a. Ord a => Fold a (Maybe a)
L.minimum Fold (Interval a) (Maybe (Interval a) -> Maybe (Interval a))
-> Fold (Interval a) (Maybe (Interval a))
-> Fold (Interval a) (Maybe (Interval a))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Fold (Interval a) (Maybe (Interval a))
forall a. Ord a => Fold a (Maybe a)
L.maximum)
(><) :: (Iv (Interval a), Ord (Moment (Interval a)), SizedIv (Interval a), Intervallic i) => i a -> i a -> Maybe (Interval a)
>< :: i a -> i a -> Maybe (Interval a)
(><) i a
x i a
y
| i a
x ComparativePredicateOf2 (i a) (i a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
`before` i a
y = Interval a -> Maybe (Interval a)
forall a. a -> Maybe a
Just (Interval a -> Maybe (Interval a))
-> Interval a -> Maybe (Interval a)
forall a b. (a -> b) -> a -> b
$ (a, a) -> Interval a
forall a.
(SizedIv (Interval a), Ord (Moment (Interval a))) =>
(a, a) -> Interval a
safeInterval (i a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end i a
x, i a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin i a
y)
| Bool
otherwise = Maybe (Interval a)
forall a. Maybe a
Nothing
(.+.) :: (Iv (Interval a), Ord (Moment (Interval a)), SizedIv (Interval a), Intervallic i) => i a -> i a -> Maybe (Interval a)
.+. :: i a -> i a -> Maybe (Interval a)
(.+.) i a
x i a
y
| i a
x ComparativePredicateOf2 (i a) (i a)
forall a (i0 :: * -> *) (i1 :: * -> *).
(Iv (Interval a), Intervallic i0, Intervallic i1) =>
ComparativePredicateOf2 (i0 a) (i1 a)
`meets` i a
y = Interval a -> Maybe (Interval a)
forall a. a -> Maybe a
Just (Interval a -> Maybe (Interval a))
-> Interval a -> Maybe (Interval a)
forall a b. (a -> b) -> a -> b
$ (a, a) -> Interval a
forall a.
(SizedIv (Interval a), Ord (Moment (Interval a))) =>
(a, a) -> Interval a
safeInterval (i a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
begin i a
x, i a -> a
forall (i :: * -> *) a.
(SizedIv (Interval a), Intervallic i) =>
i a -> a
end i a
y)
| Bool
otherwise = Maybe (Interval a)
forall a. Maybe a
Nothing