{-|
Module      : Interval Algebra
Description : Implementation of Allen's interval algebra
Copyright   : (c) NoviSci, Inc 2020
License     : BSD3
Maintainer  : bsaul@novisci.com
Stability   : experimental

The @IntervalAlgebra@ module provides data types and related classes for the 
interval-based temporal logic described in [Allen (1983)](https://doi.org/10.1145/182.358434)
and axiomatized in [Allen and Hayes (1987)](https://doi.org/10.1111/j.1467-8640.1989.tb00329.x). 

A good primer on Allen's algebra can be [found here](https://thomasalspaugh.org/pub/fnd/allen.html).

= Design

The module is built around four typeclasses designed to separate concerns of 
constructing, relating, and combining types that contain @'Interval'@s: 

1. @'Intervallic'@ provides an interface to the data structures which contain an
   @'Interval'@.
2. @'IntervalAlgebraic'@ provides an interface to the @'IntervalRelation's@, 
   the workhorse of Allen's temporal logic.
3. @'IntervalCombinable'@ provides an interface to methods of combining two
   @'Interval's@.
4. @'IntervalSizeable'@ provides methods for measuring and modifying the size of
    an interval.

An advantage of nested typeclass design is that developers can define an 
@'Interval'@ of type @a@ with just the amount of structure that they need.

== Total Ordering of @Interval@s 

The modules makes the (opinionated) choice of a total ordering for @'Intervallic'@ 
@'Interval'@s. Namely, the ordering is based on first ordering the 'begin's 
then the 'end's.

= Development

This module is under development and the API may change in the future.
-}

{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE AllowAmbiguousTypes #-}

-- {-# LANGUAGE MonoLocalBinds #-}
module IntervalAlgebra(

    -- * Classes
      Intervallic(..)
    , IntervalAlgebraic(..)
    , IntervalCombinable(..)
    , IntervalSizeable(..)

    -- * Types
    , Interval
    , parseInterval
    , IntervalRelation(..)
    , ComparativePredicateOf

    -- * Functions for creating new intervals from existing    
    , expand
    , expandl
    , expandr
    , beginerval
    , enderval
    , extenterval
) where

import Prelude (Eq, Ord, Show, Read, Enum(..), Bounded(..), Ordering (LT)
               , Maybe(..), Either(..), String, Integer, Int, Bool(..), Num
               , Foldable (maximum, minimum, foldMap, foldr)
               , map, otherwise, flip, show, fst, snd, min, max, any, negate, not
               , replicate, id, uncurry
               , (++), (==), (&&), (<), (>), (<=), ($), (+), (-), (.), (!!))
import Data.Monoid ( (<>), Monoid )               
import Data.Functor ( Functor(fmap) )
import Data.Time as DT ( Day, addDays, diffDays, addGregorianYearsClip, calendarYear )
import Data.Semigroup ( Semigroup((<>)) )
import Data.Set(Set, fromList, difference, intersection, union, map, toList)
import Data.Ord( Ord(..), Ordering(..))
import GHC.Base (Applicative(pure))

{- | An @'Interval' a@ is a pair of @a@s \( (x, y) \text{ where } x < y\). The
@'parseInterval'@ function that returns @'Left'@ error if \(y < x\) and
@'Right' 'Interval'@ otherwise. 
-}
newtype Interval a = Interval (a, a) deriving (Interval a -> Interval a -> Bool
(Interval a -> Interval a -> Bool)
-> (Interval a -> Interval a -> Bool) -> Eq (Interval a)
forall a. Eq a => Interval a -> Interval a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Interval a -> Interval a -> Bool
$c/= :: forall a. Eq a => Interval a -> Interval a -> Bool
== :: Interval a -> Interval a -> Bool
$c== :: forall a. Eq a => Interval a -> Interval a -> Bool
Eq)
    
-- | Safely parse a pair of @a@s to create an @'Interval' a@.
parseInterval :: (Show a, Ord a) => a -> a -> Either String (Interval a)
parseInterval :: a -> a -> Either String (Interval a)
parseInterval a
x a
y
    -- TODO: create more general framework for error handling
    |  a
y a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
x    = String -> Either String (Interval a)
forall a b. a -> Either a b
Left  (String -> Either String (Interval a))
-> String -> Either String (Interval a)
forall a b. (a -> b) -> a -> b
$ a -> String
forall a. Show a => a -> String
show a
y String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"<" String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show a
x
    | Bool
otherwise = Interval a -> Either String (Interval a)
forall a b. b -> Either a b
Right (Interval a -> Either String (Interval a))
-> Interval a -> Either String (Interval a)
forall a b. (a -> b) -> a -> b
$ (a, a) -> Interval a
forall a. (a, a) -> Interval a
Interval (a
x, a
y)

intervalBegin :: Interval a -> a
intervalBegin :: Interval a -> a
intervalBegin (Interval (a, a)
x) = (a, a) -> a
forall a b. (a, b) -> a
fst (a, a)
x

intervalEnd :: Interval a -> a
intervalEnd :: Interval a -> a
intervalEnd (Interval (a, a)
x) = (a, a) -> a
forall a b. (a, b) -> b
snd (a, a)
x

{- | 
The @'Intervallic'@ typeclass defines how to get and set the 'Interval' content
of a data structure. It also includes functions for getting the @'begin'@ and 
@'end'@ this data.
-}
class (Ord a, Show a) => Intervallic i a where

    -- | Get the interval from an @i a@
    getInterval :: i a -> Interval a

    -- | Set the interval in an @i a@
    setInterval :: i a -> Interval a -> i a

    -- | Access the ends of an @i a@ .
    begin, end :: i a -> a
    begin = Interval a -> a
forall a. Interval a -> a
intervalBegin (Interval a -> a) -> (i a -> Interval a) -> i a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i a -> Interval a
forall (i :: * -> *) a. Intervallic i a => i a -> Interval a
getInterval
    end   = Interval a -> a
forall a. Interval a -> a
intervalEnd (Interval a -> a) -> (i a -> Interval a) -> i a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. i a -> Interval a
forall (i :: * -> *) a. Intervallic i a => i a -> Interval a
getInterval

{- | 

The 'IntervalRelation' type enumerates the thirteen possible ways that two 
@'Interval' a@ objects can relate according to the interval algebra.

=== Meets, Metby

> x `meets` y
> y `metBy` x

@ 
x: |-----|
y:       |-----| 
@

=== Before, After

> x `before` y
> y `after` x

@ 
x: |-----|  
y:          |-----|
@


=== Overlaps, OverlappedBy

> x `overlaps` y
> y `overlappedBy` x

@ 
x: |-----|
y:     |-----|
@

=== Starts, StartedBy

> x `starts` y
> y `startedBy` x

@ 
x: |---| 
y: |-----|
@

=== Finishes, FinishedBy

> x `finishes` y
> y `finishedBy` x

@ 
x:   |---| 
y: |-----|
@

=== During, Contains

> x `during` y
> y `contains` x

@ 
x:   |-| 
y: |-----|
@

=== Equal

> x `equal` y
> y `equal` x

@ 
x: |-----| 
y: |-----|
@

-}
data IntervalRelation a =
      Meets
    | MetBy
    | Before
    | After
    | Overlaps
    | OverlappedBy
    | Starts
    | StartedBy
    | Finishes
    | FinishedBy
    | During
    | Contains
    | Equals
    deriving (IntervalRelation a -> IntervalRelation a -> Bool
(IntervalRelation a -> IntervalRelation a -> Bool)
-> (IntervalRelation a -> IntervalRelation a -> Bool)
-> Eq (IntervalRelation a)
forall a. IntervalRelation a -> IntervalRelation a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: IntervalRelation a -> IntervalRelation a -> Bool
$c/= :: forall a. IntervalRelation a -> IntervalRelation a -> Bool
== :: IntervalRelation a -> IntervalRelation a -> Bool
$c== :: forall a. IntervalRelation a -> IntervalRelation a -> Bool
Eq, Int -> IntervalRelation a -> String -> String
[IntervalRelation a] -> String -> String
IntervalRelation a -> String
(Int -> IntervalRelation a -> String -> String)
-> (IntervalRelation a -> String)
-> ([IntervalRelation a] -> String -> String)
-> Show (IntervalRelation a)
forall a. Int -> IntervalRelation a -> String -> String
forall a. [IntervalRelation a] -> String -> String
forall a. IntervalRelation a -> String
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
showList :: [IntervalRelation a] -> String -> String
$cshowList :: forall a. [IntervalRelation a] -> String -> String
show :: IntervalRelation a -> String
$cshow :: forall a. IntervalRelation a -> String
showsPrec :: Int -> IntervalRelation a -> String -> String
$cshowsPrec :: forall a. Int -> IntervalRelation a -> String -> String
Show, ReadPrec [IntervalRelation a]
ReadPrec (IntervalRelation a)
Int -> ReadS (IntervalRelation a)
ReadS [IntervalRelation a]
(Int -> ReadS (IntervalRelation a))
-> ReadS [IntervalRelation a]
-> ReadPrec (IntervalRelation a)
-> ReadPrec [IntervalRelation a]
-> Read (IntervalRelation a)
forall a. ReadPrec [IntervalRelation a]
forall a. ReadPrec (IntervalRelation a)
forall a. Int -> ReadS (IntervalRelation a)
forall a. ReadS [IntervalRelation a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [IntervalRelation a]
$creadListPrec :: forall a. ReadPrec [IntervalRelation a]
readPrec :: ReadPrec (IntervalRelation a)
$creadPrec :: forall a. ReadPrec (IntervalRelation a)
readList :: ReadS [IntervalRelation a]
$creadList :: forall a. ReadS [IntervalRelation a]
readsPrec :: Int -> ReadS (IntervalRelation a)
$creadsPrec :: forall a. Int -> ReadS (IntervalRelation a)
Read)

instance Bounded (IntervalRelation a) where
    minBound :: IntervalRelation a
minBound = IntervalRelation a
forall a. IntervalRelation a
Before
    maxBound :: IntervalRelation a
maxBound = IntervalRelation a
forall a. IntervalRelation a
After

instance Enum (IntervalRelation a) where
    fromEnum :: IntervalRelation a -> Int
fromEnum IntervalRelation a
r = case IntervalRelation a
r of
                    IntervalRelation a
Before       -> Int
0
                    IntervalRelation a
Meets        -> Int
1
                    IntervalRelation a
Overlaps     -> Int
2
                    IntervalRelation a
FinishedBy   -> Int
3
                    IntervalRelation a
Contains     -> Int
4
                    IntervalRelation a
Starts       -> Int
5
                    IntervalRelation a
Equals       -> Int
6
                    IntervalRelation a
StartedBy    -> Int
7
                    IntervalRelation a
During       -> Int
8
                    IntervalRelation a
Finishes     -> Int
9
                    IntervalRelation a
OverlappedBy -> Int
10
                    IntervalRelation a
MetBy        -> Int
11
                    IntervalRelation a
After        -> Int
12

    toEnum :: Int -> IntervalRelation a
toEnum Int
i = case Int
i of
               Int
0  -> IntervalRelation a
forall a. IntervalRelation a
Before
               Int
1  -> IntervalRelation a
forall a. IntervalRelation a
Meets
               Int
2  -> IntervalRelation a
forall a. IntervalRelation a
Overlaps
               Int
3  -> IntervalRelation a
forall a. IntervalRelation a
FinishedBy
               Int
4  -> IntervalRelation a
forall a. IntervalRelation a
Contains
               Int
5  -> IntervalRelation a
forall a. IntervalRelation a
Starts
               Int
6  -> IntervalRelation a
forall a. IntervalRelation a
Equals
               Int
7  -> IntervalRelation a
forall a. IntervalRelation a
StartedBy
               Int
8  -> IntervalRelation a
forall a. IntervalRelation a
During
               Int
9 -> IntervalRelation a
forall a. IntervalRelation a
Finishes
               Int
10 -> IntervalRelation a
forall a. IntervalRelation a
OverlappedBy
               Int
11 -> IntervalRelation a
forall a. IntervalRelation a
MetBy
               Int
12 -> IntervalRelation a
forall a. IntervalRelation a
After

instance Ord (IntervalRelation a) where
    compare :: IntervalRelation a -> IntervalRelation a -> Ordering
compare IntervalRelation a
x IntervalRelation a
y = Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (IntervalRelation a -> Int
forall a. Enum a => a -> Int
fromEnum IntervalRelation a
x) (IntervalRelation a -> Int
forall a. Enum a => a -> Int
fromEnum IntervalRelation a
y)

-- | The 'Set' of all 'IntervalRelation's.
intervalRelations :: Set (IntervalRelation a)
intervalRelations :: Set (IntervalRelation a)
intervalRelations = [IntervalRelation a] -> Set (IntervalRelation a)
forall a. Ord a => [a] -> Set a
fromList ((Int -> IntervalRelation a) -> [Int] -> [IntervalRelation a]
forall a b. (a -> b) -> [a] -> [b]
Prelude.map Int -> IntervalRelation a
forall a. Enum a => Int -> a
toEnum [Int
0..Int
12] ::[IntervalRelation a])

-- | Find the converse of a single 'IntervalRelation'
converseRelation :: IntervalRelation a -> IntervalRelation a
converseRelation :: IntervalRelation a -> IntervalRelation a
converseRelation IntervalRelation a
x = Int -> IntervalRelation a
forall a. Enum a => Int -> a
toEnum (Int
12 Int -> Int -> Int
forall a. Num a => a -> a -> a
- IntervalRelation a -> Int
forall a. Enum a => a -> Int
fromEnum IntervalRelation a
x)

-- | The lookup table for the compositions of interval relations.
composeRelationLookup :: [[[IntervalRelation a]]]
composeRelationLookup :: [[[IntervalRelation a]]]
composeRelationLookup =
      [ [[IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
pmosd, [IntervalRelation a]
forall a. [IntervalRelation a]
pmosd, [IntervalRelation a]
forall a. [IntervalRelation a]
pmosd, [IntervalRelation a]
forall a. [IntervalRelation a]
pmosd, [IntervalRelation a]
forall a. [IntervalRelation a]
full ]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
m    , [IntervalRelation a]
forall a. [IntervalRelation a]
m , [IntervalRelation a]
forall a. [IntervalRelation a]
m    , [IntervalRelation a]
forall a. [IntervalRelation a]
osd  , [IntervalRelation a]
forall a. [IntervalRelation a]
osd  , [IntervalRelation a]
forall a. [IntervalRelation a]
osd  , [IntervalRelation a]
forall a. [IntervalRelation a]
fef  , [IntervalRelation a]
forall a. [IntervalRelation a]
dsomp]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
pmo  , [IntervalRelation a]
forall a. [IntervalRelation a]
pmo  , [IntervalRelation a]
forall a. [IntervalRelation a]
pmofd, [IntervalRelation a]
forall a. [IntervalRelation a]
o    , [IntervalRelation a]
forall a. [IntervalRelation a]
o , [IntervalRelation a]
forall a. [IntervalRelation a]
ofd  , [IntervalRelation a]
forall a. [IntervalRelation a]
osd  , [IntervalRelation a]
forall a. [IntervalRelation a]
osd  , [IntervalRelation a]
forall a. [IntervalRelation a]
cncr , [IntervalRelation a]
forall a. [IntervalRelation a]
dso  , [IntervalRelation a]
forall a. [IntervalRelation a]
dsomp]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
m    , [IntervalRelation a]
forall a. [IntervalRelation a]
o    , [IntervalRelation a]
forall a. [IntervalRelation a]
f'   , [IntervalRelation a]
forall a. [IntervalRelation a]
d'   , [IntervalRelation a]
forall a. [IntervalRelation a]
o    , [IntervalRelation a]
forall a. [IntervalRelation a]
f', [IntervalRelation a]
forall a. [IntervalRelation a]
d'   , [IntervalRelation a]
forall a. [IntervalRelation a]
osd  , [IntervalRelation a]
forall a. [IntervalRelation a]
fef  , [IntervalRelation a]
forall a. [IntervalRelation a]
dso  , [IntervalRelation a]
forall a. [IntervalRelation a]
dso  , [IntervalRelation a]
forall a. [IntervalRelation a]
dsomp]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
pmofd, [IntervalRelation a]
forall a. [IntervalRelation a]
ofd  , [IntervalRelation a]
forall a. [IntervalRelation a]
ofd  , [IntervalRelation a]
forall a. [IntervalRelation a]
d'   , [IntervalRelation a]
forall a. [IntervalRelation a]
d'   , [IntervalRelation a]
forall a. [IntervalRelation a]
ofd  , [IntervalRelation a]
forall a. [IntervalRelation a]
d', [IntervalRelation a]
forall a. [IntervalRelation a]
d'   , [IntervalRelation a]
forall a. [IntervalRelation a]
cncr , [IntervalRelation a]
forall a. [IntervalRelation a]
dso  , [IntervalRelation a]
forall a. [IntervalRelation a]
dso  , [IntervalRelation a]
forall a. [IntervalRelation a]
dso  , [IntervalRelation a]
forall a. [IntervalRelation a]
dsomp]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
pmo  , [IntervalRelation a]
forall a. [IntervalRelation a]
pmo  , [IntervalRelation a]
forall a. [IntervalRelation a]
pmofd, [IntervalRelation a]
forall a. [IntervalRelation a]
s    , [IntervalRelation a]
forall a. [IntervalRelation a]
s , [IntervalRelation a]
forall a. [IntervalRelation a]
ses  , [IntervalRelation a]
forall a. [IntervalRelation a]
d    , [IntervalRelation a]
forall a. [IntervalRelation a]
d    , [IntervalRelation a]
forall a. [IntervalRelation a]
dfo  , [IntervalRelation a]
forall a. [IntervalRelation a]
m'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   ]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
m    , [IntervalRelation a]
forall a. [IntervalRelation a]
o    , [IntervalRelation a]
forall a. [IntervalRelation a]
f'   , [IntervalRelation a]
forall a. [IntervalRelation a]
d'   , [IntervalRelation a]
forall a. [IntervalRelation a]
s    , [IntervalRelation a]
forall a. [IntervalRelation a]
e , [IntervalRelation a]
forall a. [IntervalRelation a]
s'   , [IntervalRelation a]
forall a. [IntervalRelation a]
d    , [IntervalRelation a]
forall a. [IntervalRelation a]
f    , [IntervalRelation a]
forall a. [IntervalRelation a]
o'   , [IntervalRelation a]
forall a. [IntervalRelation a]
m'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   ]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
pmofd, [IntervalRelation a]
forall a. [IntervalRelation a]
ofd  , [IntervalRelation a]
forall a. [IntervalRelation a]
ofd  , [IntervalRelation a]
forall a. [IntervalRelation a]
d'   , [IntervalRelation a]
forall a. [IntervalRelation a]
d'   , [IntervalRelation a]
forall a. [IntervalRelation a]
ses  , [IntervalRelation a]
forall a. [IntervalRelation a]
s', [IntervalRelation a]
forall a. [IntervalRelation a]
s'   , [IntervalRelation a]
forall a. [IntervalRelation a]
dfo  , [IntervalRelation a]
forall a. [IntervalRelation a]
o'   , [IntervalRelation a]
forall a. [IntervalRelation a]
o'   , [IntervalRelation a]
forall a. [IntervalRelation a]
m'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   ]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
pmosd, [IntervalRelation a]
forall a. [IntervalRelation a]
pmosd, [IntervalRelation a]
forall a. [IntervalRelation a]
full , [IntervalRelation a]
forall a. [IntervalRelation a]
d    , [IntervalRelation a]
forall a. [IntervalRelation a]
d , [IntervalRelation a]
forall a. [IntervalRelation a]
dfomp, [IntervalRelation a]
forall a. [IntervalRelation a]
d    , [IntervalRelation a]
forall a. [IntervalRelation a]
d    , [IntervalRelation a]
forall a. [IntervalRelation a]
dfomp, [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   ]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
p    , [IntervalRelation a]
forall a. [IntervalRelation a]
m    , [IntervalRelation a]
forall a. [IntervalRelation a]
osd  , [IntervalRelation a]
forall a. [IntervalRelation a]
fef  , [IntervalRelation a]
forall a. [IntervalRelation a]
dsomp, [IntervalRelation a]
forall a. [IntervalRelation a]
d    , [IntervalRelation a]
forall a. [IntervalRelation a]
f , [IntervalRelation a]
forall a. [IntervalRelation a]
omp  , [IntervalRelation a]
forall a. [IntervalRelation a]
d    , [IntervalRelation a]
forall a. [IntervalRelation a]
f    , [IntervalRelation a]
forall a. [IntervalRelation a]
omp  , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   ]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
pmofd, [IntervalRelation a]
forall a. [IntervalRelation a]
ofd  , [IntervalRelation a]
forall a. [IntervalRelation a]
cncr , [IntervalRelation a]
forall a. [IntervalRelation a]
dso  , [IntervalRelation a]
forall a. [IntervalRelation a]
dsomp, [IntervalRelation a]
forall a. [IntervalRelation a]
dfo  , [IntervalRelation a]
forall a. [IntervalRelation a]
o', [IntervalRelation a]
forall a. [IntervalRelation a]
omp  , [IntervalRelation a]
forall a. [IntervalRelation a]
dfo  , [IntervalRelation a]
forall a. [IntervalRelation a]
o'   , [IntervalRelation a]
forall a. [IntervalRelation a]
omp  , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   ]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
pmofd, [IntervalRelation a]
forall a. [IntervalRelation a]
ses  , [IntervalRelation a]
forall a. [IntervalRelation a]
dfo  , [IntervalRelation a]
forall a. [IntervalRelation a]
m'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
dfo  , [IntervalRelation a]
forall a. [IntervalRelation a]
m', [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
dfo  , [IntervalRelation a]
forall a. [IntervalRelation a]
m'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   ]
      , [[IntervalRelation a]
forall a. [IntervalRelation a]
full , [IntervalRelation a]
forall a. [IntervalRelation a]
dfomp, [IntervalRelation a]
forall a. [IntervalRelation a]
dfomp, [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
dfomp, [IntervalRelation a]
forall a. [IntervalRelation a]
p', [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
dfomp, [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   , [IntervalRelation a]
forall a. [IntervalRelation a]
p'   ]
      ]
      where p :: [IntervalRelation a]
p  = [IntervalRelation a
forall a. IntervalRelation a
Before]
            m :: [IntervalRelation a]
m  = [IntervalRelation a
forall a. IntervalRelation a
Meets]
            o :: [IntervalRelation a]
o  = [IntervalRelation a
forall a. IntervalRelation a
Overlaps]
            f' :: [IntervalRelation a]
f' = [IntervalRelation a
forall a. IntervalRelation a
FinishedBy]
            d' :: [IntervalRelation a]
d' = [IntervalRelation a
forall a. IntervalRelation a
Contains]
            s :: [IntervalRelation a]
s  = [IntervalRelation a
forall a. IntervalRelation a
Starts]
            e :: [IntervalRelation a]
e  = [IntervalRelation a
forall a. IntervalRelation a
Equals]
            s' :: [IntervalRelation a]
s' = [IntervalRelation a
forall a. IntervalRelation a
StartedBy]
            d :: [IntervalRelation a]
d  = [IntervalRelation a
forall a. IntervalRelation a
During]
            f :: [IntervalRelation a]
f  = [IntervalRelation a
forall a. IntervalRelation a
Finishes]
            o' :: [IntervalRelation a]
o' = [IntervalRelation a
forall a. IntervalRelation a
OverlappedBy]
            m' :: [IntervalRelation a]
m' = [IntervalRelation a
forall a. IntervalRelation a
MetBy]
            p' :: [IntervalRelation a]
p' = [IntervalRelation a
forall a. IntervalRelation a
After]
            ses :: [IntervalRelation a]
ses    = [IntervalRelation a]
forall a. [IntervalRelation a]
s [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
e [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
s'
            fef :: [IntervalRelation a]
fef    = [IntervalRelation a]
forall a. [IntervalRelation a]
f' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
e [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
f
            pmo :: [IntervalRelation a]
pmo    = [IntervalRelation a]
forall a. [IntervalRelation a]
p [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
m [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
o
            pmofd :: [IntervalRelation a]
pmofd  = [IntervalRelation a]
forall a. [IntervalRelation a]
pmo [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
f' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
d'
            osd :: [IntervalRelation a]
osd    = [IntervalRelation a]
forall a. [IntervalRelation a]
o [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
s [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
d
            ofd :: [IntervalRelation a]
ofd    = [IntervalRelation a]
forall a. [IntervalRelation a]
o [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
f' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
d'
            omp :: [IntervalRelation a]
omp    = [IntervalRelation a]
forall a. [IntervalRelation a]
o' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
m' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
p'
            dfo :: [IntervalRelation a]
dfo    = [IntervalRelation a]
forall a. [IntervalRelation a]
d [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
f [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
o'
            dfomp :: [IntervalRelation a]
dfomp  = [IntervalRelation a]
forall a. [IntervalRelation a]
dfo [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
m' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
p'
            dso :: [IntervalRelation a]
dso    = [IntervalRelation a]
forall a. [IntervalRelation a]
d' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
s' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
o'
            dsomp :: [IntervalRelation a]
dsomp  = [IntervalRelation a]
forall a. [IntervalRelation a]
dso [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
m' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
p'
            pmosd :: [IntervalRelation a]
pmosd  = [IntervalRelation a]
forall a. [IntervalRelation a]
p [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
m [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
osd
            cncr :: [IntervalRelation a]
cncr = [IntervalRelation a]
forall a. [IntervalRelation a]
o [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
f' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
d' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
s [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
e [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
s' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
d [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
f [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
o'
            full :: [IntervalRelation a]
full = [IntervalRelation a]
forall a. [IntervalRelation a]
p [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
m [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
cncr [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
m' [IntervalRelation a]
-> [IntervalRelation a] -> [IntervalRelation a]
forall a. [a] -> [a] -> [a]
++ [IntervalRelation a]
forall a. [IntervalRelation a]
p'
{-
Misc
-}

-- | Defines a predicate of two objects of type @a@.
type ComparativePredicateOf a = (a -> a -> Bool)


{- |
The @'IntervalAlgebraic'@ typeclass specifies the functions and relational 
operators for interval-based temporal logic. The typeclass defines the 
relational operators for types that contain an @'Interval a'@, plus other useful
 utilities such as @'disjoint'@, @'within'@, and @'unionPredicates'@.
-}
class (Eq (i a), Intervallic i a) => IntervalAlgebraic i a where

    -- | Compare two @i a@ to determine their 'IntervalRelation'.
    relate :: i a -> i a -> IntervalRelation (i a)
    relate i a
x i a
y
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`before` i a
y       = IntervalRelation (i a)
forall a. IntervalRelation a
Before
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`after`  i a
y       = IntervalRelation (i a)
forall a. IntervalRelation a
After
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`meets`  i a
y       = IntervalRelation (i a)
forall a. IntervalRelation a
Meets
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`metBy`  i a
y       = IntervalRelation (i a)
forall a. IntervalRelation a
MetBy
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`overlaps` i a
y     = IntervalRelation (i a)
forall a. IntervalRelation a
Overlaps
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`overlappedBy` i a
y = IntervalRelation (i a)
forall a. IntervalRelation a
OverlappedBy
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`starts` i a
y       = IntervalRelation (i a)
forall a. IntervalRelation a
Starts
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`startedBy` i a
y    = IntervalRelation (i a)
forall a. IntervalRelation a
StartedBy
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`finishes` i a
y     = IntervalRelation (i a)
forall a. IntervalRelation a
Finishes
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`finishedBy` i a
y   = IntervalRelation (i a)
forall a. IntervalRelation a
FinishedBy
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`during` i a
y       = IntervalRelation (i a)
forall a. IntervalRelation a
During
        | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`contains` i a
y     = IntervalRelation (i a)
forall a. IntervalRelation a
Contains
        | Bool
otherwise          = IntervalRelation (i a)
forall a. IntervalRelation a
Equals

    -- | Maps an 'IntervalRelation' to its corresponding predicate function.
    predicate' :: IntervalRelation (i a) -> ComparativePredicateOf (i a)
    predicate' IntervalRelation (i a)
r =
        case IntervalRelation (i a)
r of
            IntervalRelation (i a)
Before       -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
before
            IntervalRelation (i a)
Meets        -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
meets
            IntervalRelation (i a)
Overlaps     -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
overlaps
            IntervalRelation (i a)
FinishedBy   -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
finishedBy
            IntervalRelation (i a)
Contains     -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
contains
            IntervalRelation (i a)
Starts       -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
starts
            IntervalRelation (i a)
Equals       -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
equals
            IntervalRelation (i a)
StartedBy    -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
startedBy
            IntervalRelation (i a)
During       -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
during
            IntervalRelation (i a)
Finishes     -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
finishes
            IntervalRelation (i a)
OverlappedBy -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
overlappedBy
            IntervalRelation (i a)
MetBy        -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
metBy
            IntervalRelation (i a)
After        -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
after

    -- | Given a set of 'IntervalRelation's return a list of 'predicate' functions 
    --   corresponding to each relation.
    predicates :: Set (IntervalRelation (i a)) -> [ComparativePredicateOf (i a)]
    predicates Set (IntervalRelation (i a))
x = (IntervalRelation (i a) -> ComparativePredicateOf (i a))
-> [IntervalRelation (i a)] -> [ComparativePredicateOf (i a)]
forall a b. (a -> b) -> [a] -> [b]
Prelude.map IntervalRelation (i a) -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
IntervalRelation (i a) -> ComparativePredicateOf (i a)
predicate' (Set (IntervalRelation (i a)) -> [IntervalRelation (i a)]
forall a. Set a -> [a]
toList Set (IntervalRelation (i a))
x)

    -- | Forms a predicate function from the union of a set of 'IntervalRelation's.
    predicate :: Set (IntervalRelation (i a)) -> ComparativePredicateOf (i a)
    predicate = [ComparativePredicateOf (i a)] -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
[ComparativePredicateOf (i a)] -> ComparativePredicateOf (i a)
unionPredicates([ComparativePredicateOf (i a)] -> ComparativePredicateOf (i a))
-> (Set (IntervalRelation (i a)) -> [ComparativePredicateOf (i a)])
-> Set (IntervalRelation (i a))
-> ComparativePredicateOf (i a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.Set (IntervalRelation (i a)) -> [ComparativePredicateOf (i a)]
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
Set (IntervalRelation (i a)) -> [ComparativePredicateOf (i a)]
predicates

    -- ** Algebraic operations on IntervalRelations

    -- | Shortcut to creating a 'Set IntervalRelation' from a list.
    toSet :: [IntervalRelation (i a)] -> Set (IntervalRelation (i a))
    toSet = [IntervalRelation (i a)] -> Set (IntervalRelation (i a))
forall a. Ord a => [a] -> Set a
fromList

    -- | Compose two interval relations according to the rules of the algebra.
    --   The rules are enumerated according to <https://thomasalspaugh.org/pub/fnd/allen.html#BasicCompositionsTable this table>.
    compose :: IntervalRelation (i a)
            -> IntervalRelation (i a)
            -> Set (IntervalRelation (i a))
    compose IntervalRelation (i a)
x IntervalRelation (i a)
y = [IntervalRelation (i a)] -> Set (IntervalRelation (i a))
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
[IntervalRelation (i a)] -> Set (IntervalRelation (i a))
toSet (([[[IntervalRelation (i a)]]]
forall a. [[[IntervalRelation a]]]
composeRelationLookup [[[IntervalRelation (i a)]]] -> Int -> [[IntervalRelation (i a)]]
forall a. [a] -> Int -> a
!! IntervalRelation (i a) -> Int
forall a. Enum a => a -> Int
fromEnum IntervalRelation (i a)
x) [[IntervalRelation (i a)]] -> Int -> [IntervalRelation (i a)]
forall a. [a] -> Int -> a
!! IntervalRelation (i a) -> Int
forall a. Enum a => a -> Int
fromEnum IntervalRelation (i a)
y)

    -- | Finds the complement of a 'Set IntervalRelation'.
    complement :: Set (IntervalRelation (i a)) -> Set (IntervalRelation (i a))
    complement = Set (IntervalRelation (i a))
-> Set (IntervalRelation (i a)) -> Set (IntervalRelation (i a))
forall a. Ord a => Set a -> Set a -> Set a
difference Set (IntervalRelation (i a))
forall a. Set (IntervalRelation a)
intervalRelations

    -- | Find the intersection of two 'Set's of 'IntervalRelation's.
    intersection ::  Set (IntervalRelation (i a))
                  -> Set (IntervalRelation (i a))
                  -> Set (IntervalRelation (i a))
    intersection = Set (IntervalRelation (i a))
-> Set (IntervalRelation (i a)) -> Set (IntervalRelation (i a))
forall a. Ord a => Set a -> Set a -> Set a
Data.Set.intersection

    -- | Find the union of two 'Set's of 'IntervalRelation's.
    union ::  Set (IntervalRelation (i a))
           -> Set (IntervalRelation (i a))
           -> Set (IntervalRelation (i a))
    union = Set (IntervalRelation (i a))
-> Set (IntervalRelation (i a)) -> Set (IntervalRelation (i a))
forall a. Ord a => Set a -> Set a -> Set a
Data.Set.union

    -- | Find the converse of a 'Set IntervalRelation'. 
    converse ::   Set (IntervalRelation (i a))
                  -> Set (IntervalRelation (i a))
    converse = (IntervalRelation (i a) -> IntervalRelation (i a))
-> Set (IntervalRelation (i a)) -> Set (IntervalRelation (i a))
forall b a. Ord b => (a -> b) -> Set a -> Set b
Data.Set.map IntervalRelation (i a) -> IntervalRelation (i a)
forall a. IntervalRelation a -> IntervalRelation a
converseRelation

    -- ** Interval algebra predicates

    -- | Does x equal y?
    equals                 :: ComparativePredicateOf (i a)
    equals   i a
x i a
y  = i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
y Bool -> Bool -> Bool
&& i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
y

    -- | Does x meet y? Is y metBy x?
    meets, metBy           :: ComparativePredicateOf (i a)
    meets    i a
x i a
y  = i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
y
    metBy         = ComparativePredicateOf (i a) -> ComparativePredicateOf (i a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
meets

    -- | Is x before y? Is x after y?
    before, after          :: ComparativePredicateOf (i a)
    before   i a
x i a
y  = i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
y
    after         = ComparativePredicateOf (i a) -> ComparativePredicateOf (i a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
before

    -- | Does x overlap y? Is x overlapped by y?
    overlaps, overlappedBy :: ComparativePredicateOf (i a)
    overlaps i a
x i a
y  = i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
y Bool -> Bool -> Bool
&& i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
y Bool -> Bool -> Bool
&& i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
y
    overlappedBy  = ComparativePredicateOf (i a) -> ComparativePredicateOf (i a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
overlaps

    -- | Does x start y? Is x started by y?
    starts, startedBy      :: ComparativePredicateOf (i a)
    starts   i a
x i a
y  = i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
y Bool -> Bool -> Bool
&& (i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
y)
    startedBy     = ComparativePredicateOf (i a) -> ComparativePredicateOf (i a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
starts

    -- | Synonyms for 'starts' and 'startedBy'
    precedes, precededBy      :: ComparativePredicateOf (i a)
    precedes      = ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
starts
    precededBy    = ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
startedBy

    -- | Does x finish y? Is x finished by y?
    finishes, finishedBy   :: ComparativePredicateOf (i a)
    finishes i a
x i a
y  = i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
y Bool -> Bool -> Bool
&& i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
y
    finishedBy    = ComparativePredicateOf (i a) -> ComparativePredicateOf (i a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
finishes

    -- | Is x during y? Does x contain y?
    during, contains       :: ComparativePredicateOf (i a)
    during   i a
x i a
y  = i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
> i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
y Bool -> Bool -> Bool
&& i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
y
    contains      = ComparativePredicateOf (i a) -> ComparativePredicateOf (i a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
during

    -- ** Interval Algebra utilities

    -- | Compose a list of interval relations with _or_ to create a new
    -- @'ComparativePredicateOf' i a@. For example, 
    -- @unionPredicates [before, meets]@ creates a predicate function determining
    -- if one interval is either before or meets another interval.
    unionPredicates       :: [ComparativePredicateOf (i a)] ->
                              ComparativePredicateOf (i a)
    unionPredicates [ComparativePredicateOf (i a)]
fs i a
x i a
y = (ComparativePredicateOf (i a) -> Bool)
-> [ComparativePredicateOf (i a)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\ ComparativePredicateOf (i a)
f -> ComparativePredicateOf (i a)
f i a
x i a
y) [ComparativePredicateOf (i a)]
fs

    -- | Operator for composing the union of two predicates
    (<|>) ::  ComparativePredicateOf (i a)
        -> ComparativePredicateOf (i a)
        -> ComparativePredicateOf (i a)
    (<|>) ComparativePredicateOf (i a)
f ComparativePredicateOf (i a)
g = [ComparativePredicateOf (i a)] -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
[ComparativePredicateOf (i a)] -> ComparativePredicateOf (i a)
unionPredicates [ComparativePredicateOf (i a)
f, ComparativePredicateOf (i a)
g]

    disjointRelations :: Set (IntervalRelation (i a))
    disjointRelations = [IntervalRelation (i a)] -> Set (IntervalRelation (i a))
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
[IntervalRelation (i a)] -> Set (IntervalRelation (i a))
toSet [IntervalRelation (i a)
forall a. IntervalRelation a
Before, IntervalRelation (i a)
forall a. IntervalRelation a
After, IntervalRelation (i a)
forall a. IntervalRelation a
Meets, IntervalRelation (i a)
forall a. IntervalRelation a
MetBy]

    withinRelations :: Set (IntervalRelation (i a))
    withinRelations = [IntervalRelation (i a)] -> Set (IntervalRelation (i a))
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
[IntervalRelation (i a)] -> Set (IntervalRelation (i a))
toSet [IntervalRelation (i a)
forall a. IntervalRelation a
Starts, IntervalRelation (i a)
forall a. IntervalRelation a
During, IntervalRelation (i a)
forall a. IntervalRelation a
Finishes, IntervalRelation (i a)
forall a. IntervalRelation a
Equals]

    -- | Are x and y disjoint ('before', 'after', 'meets', or 'metBy')?
    disjoint               :: ComparativePredicateOf (i a)
    disjoint = Set (IntervalRelation (i a)) -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
Set (IntervalRelation (i a)) -> ComparativePredicateOf (i a)
predicate Set (IntervalRelation (i a))
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
Set (IntervalRelation (i a))
disjointRelations

    -- | Are x and y not disjoint; i.e. do they share any support?
    notDisjoint            :: ComparativePredicateOf (i a)
    notDisjoint = Set (IntervalRelation (i a)) -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
Set (IntervalRelation (i a)) -> ComparativePredicateOf (i a)
predicate (Set (IntervalRelation (i a)) -> Set (IntervalRelation (i a))
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
Set (IntervalRelation (i a)) -> Set (IntervalRelation (i a))
complement Set (IntervalRelation (i a))
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
Set (IntervalRelation (i a))
disjointRelations)

    -- | A synonym for 'notDisjoint'.
    concur                 :: ComparativePredicateOf (i a)
    concur = ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
notDisjoint

    -- | Is x entirely *within* the endpoints of y? That is, 'during', 
    --   'starts', 'finishes', or 'equals'?
    within                 :: ComparativePredicateOf (i a)
    within = Set (IntervalRelation (i a)) -> ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
Set (IntervalRelation (i a)) -> ComparativePredicateOf (i a)
predicate Set (IntervalRelation (i a))
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
Set (IntervalRelation (i a))
withinRelations

    -- | Does x enclose y? That is, is y 'within' x?
    enclose                :: ComparativePredicateOf (i a)
    enclose = ComparativePredicateOf (i a) -> ComparativePredicateOf (i a)
forall a b c. (a -> b -> c) -> b -> a -> c
flip ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
enclosedBy

    -- | Synonym for 'within'.
    enclosedBy             :: ComparativePredicateOf (i a)
    enclosedBy = ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
within

{- |
The 'IntervalSizeable' typeclass provides functions to determine the size of an
'Intervallic' type and to resize an 'Interval a'.
-}
class (Show a, Ord a, Num b, Ord b) => IntervalSizeable a b| a -> b where

    -- | The smallest duration for an 'Interval a'.
    moment :: b
    moment = b
1

    -- | Gives back a 'moment' based on the input's type.
    moment' :: Intervallic i a => i a -> b
    moment' i a
x = forall b. IntervalSizeable a b => b
forall a b. IntervalSizeable a b => b
moment @a

    -- | Determine the duration of an @'i a'@.
    duration :: Intervallic i a => i a -> b
    duration i a
x = a -> a -> b
forall a b. IntervalSizeable a b => a -> a -> b
diff (i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
x) (i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
x)

    -- | Shifts an @a@. Most often, the @b@ will be the same type as @a@. 
    --   But for example, if @a@ is 'Day' then @b@ could be 'Int'.
    add :: b -> a -> a

    -- | Takes the difference between two @a@ to return a @b@.
    diff :: a -> a -> b

-- | Resize an 'i a' to by expanding to "left" by @l@ and to the 
--   "right" by @r@. In the case that @l@ or @r@ are less than a 'moment'
--   the respective endpoints are unchanged. 
expand :: (IntervalSizeable a b, Intervallic i a) => b -> b -> i a -> i a
expand :: b -> b -> i a -> i a
expand b
l b
r i a
p = i a -> Interval a -> i a
forall (i :: * -> *) a. Intervallic i a => i a -> Interval a -> i a
setInterval i a
p Interval a
i
  where s :: b
s = if b
l b -> b -> Bool
forall a. Ord a => a -> a -> Bool
< i a -> b
forall a b (i :: * -> *).
(IntervalSizeable a b, Intervallic i a) =>
i a -> b
moment' i a
p then b
0 else b -> b
forall a. Num a => a -> a
negate b
l
        e :: b
e = if b
r b -> b -> Bool
forall a. Ord a => a -> a -> Bool
< i a -> b
forall a b (i :: * -> *).
(IntervalSizeable a b, Intervallic i a) =>
i a -> b
moment' i a
p then b
0 else b
r
        i :: Interval a
i = (a, a) -> Interval a
forall a. (a, a) -> Interval a
Interval (b -> a -> a
forall a b. IntervalSizeable a b => b -> a -> a
add b
s (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
p, b -> a -> a
forall a b. IntervalSizeable a b => b -> a -> a
add b
e (a -> a) -> a -> a
forall a b. (a -> b) -> a -> b
$ i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
p)

-- | Expands an 'i a' to left by i.
expandl :: (IntervalSizeable a b, Intervallic i a) => b -> i a -> i a
expandl :: b -> i a -> i a
expandl b
i = b -> b -> i a -> i a
forall a b (i :: * -> *).
(IntervalSizeable a b, Intervallic i a) =>
b -> b -> i a -> i a
expand b
i b
0

-- | Expands an 'i a' to right by i.
expandr :: (IntervalSizeable a b, Intervallic i a) => b -> i a -> i a
expandr :: b -> i a -> i a
expandr = b -> b -> i a -> i a
forall a b (i :: * -> *).
(IntervalSizeable a b, Intervallic i a) =>
b -> b -> i a -> i a
expand b
0

-- | Safely creates an 'Interval a' using @x@ as the 'begin' and adding 
--   @max moment dur@ to @x@ as the 'end'.
beginerval :: (IntervalSizeable a b) => b -> a -> Interval a
beginerval :: b -> a -> Interval a
beginerval b
dur a
x = (a, a) -> Interval a
forall a. (a, a) -> Interval a
Interval (a
x, a
y)
    where i :: Interval a
i = (a, a) -> Interval a
forall a. (a, a) -> Interval a
Interval (a
x, a
x)
          d :: b
d = b -> b -> b
forall a. Ord a => a -> a -> a
max (Interval a -> b
forall a b (i :: * -> *).
(IntervalSizeable a b, Intervallic i a) =>
i a -> b
moment' Interval a
i) b
dur
          y :: a
y = b -> a -> a
forall a b. IntervalSizeable a b => b -> a -> a
add b
d a
x

-- | Safely creates an 'Interval a' using @x@ as the 'end' and adding
--   @negate max moment dur@ to @x@ as the 'begin'.
enderval :: (IntervalSizeable a b) => b -> a -> Interval a
enderval :: b -> a -> Interval a
enderval b
dur a
x = (a, a) -> Interval a
forall a. (a, a) -> Interval a
Interval (b -> a -> a
forall a b. IntervalSizeable a b => b -> a -> a
add (b -> b
forall a. Num a => a -> a
negate (b -> b) -> b -> b
forall a b. (a -> b) -> a -> b
$ b -> b -> b
forall a. Ord a => a -> a -> a
max (Interval a -> b
forall a b (i :: * -> *).
(IntervalSizeable a b, Intervallic i a) =>
i a -> b
moment' Interval a
i) b
dur) a
x, a
x)
    where i :: Interval a
i = (a, a) -> Interval a
forall a. (a, a) -> Interval a
Interval (a
x, a
x)

-- | Creates a new @Interval@ spanning the extent x and y.
extenterval :: IntervalAlgebraic i a => i a -> i a -> Interval a
extenterval :: i a -> i a -> Interval a
extenterval i a
x i a
y = (a, a) -> Interval a
forall a. (a, a) -> Interval a
Interval (a
s, a
e)
    where s :: a
s = a -> a -> a
forall a. Ord a => a -> a -> a
min (i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
x) (i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
y)
          e :: a
e = a -> a -> a
forall a. Ord a => a -> a -> a
max (i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
x) (i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
y)


{- |
The @'IntervalCombinable'@ typeclass provides methods for (possibly) combining
two @i a@s to form an @'Interval'@.
-}
class (IntervalAlgebraic i a) => IntervalCombinable i a where

    -- | Maybe form a new @i a@ by the union of two @i a@s that 'meets'.
    (.+.) ::   i a -> i a -> Maybe (i a)
    (.+.) i a
x i a
y
      | i a
x ComparativePredicateOf (i a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`meets` i a
y = i a -> Maybe (i a)
forall a. a -> Maybe a
Just (i a -> Maybe (i a)) -> i a -> Maybe (i a)
forall a b. (a -> b) -> a -> b
$ i a -> Interval a -> i a
forall (i :: * -> *) a. Intervallic i a => i a -> Interval a -> i a
setInterval i a
y (Interval a -> i a) -> Interval a -> i a
forall a b. (a -> b) -> a -> b
$ (a, a) -> Interval a
forall a. (a, a) -> Interval a
Interval (a
b, a
e)
      | Bool
otherwise   = Maybe (i a)
forall a. Maybe a
Nothing
      where b :: a
b = i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin i a
x
            e :: a
e = i a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end i a
y

    -- | If @x@ is 'before' @y@, then form a new @Just Interval a@ from the 
    --   interval in the "gap" between @x@ and @y@ from the 'end' of @x@ to the
    --   'begin' of @y@. Otherwise, 'Nothing'.
    (><) :: i a -> i a -> Maybe (i a)
 
    -- | If @x@ is 'before' @y@, return @f x@ appended to @f y@. Otherwise, 
    --   return 'extenterval' of @x@ and @y@ (wrapped in @f@). This is useful for 
    --   (left) folding over an *ordered* container of @Interval@s and combining 
    --   intervals when @x@ is *not* 'before' @y@.
    (<+>):: ( Semigroup (f (i a)), Applicative f) =>
               i a
            -> i a
            -> f (i a)


-- {-
-- Instances
-- -}

-- | Imposes a total ordering on @'Interval' a@ based on first ordering the 
--   'begin's then the 'end's.
instance (Eq (Interval a), Intervallic Interval a) => Ord (Interval a) where
    <= :: Interval a -> Interval a -> Bool
(<=) Interval a
x Interval a
y
      | Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<  Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin Interval a
y = Bool
True
      | Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin Interval a
y = Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<= Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end Interval a
y
      | Bool
otherwise = Bool
False
    < :: Interval a -> Interval a -> Bool
(<)  Interval a
x Interval a
y
      | Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
<  Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin Interval a
y = Bool
True
      | Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin Interval a
x a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin Interval a
y = Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end Interval a
x a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end Interval a
y
      | Bool
otherwise = Bool
False

instance Functor Interval where
    fmap :: (a -> b) -> Interval a -> Interval b
fmap a -> b
f (Interval (a
x, a
y)) = (b, b) -> Interval b
forall a. (a, a) -> Interval a
Interval (a -> b
f a
x, a -> b
f a
y)

instance (Intervallic Interval a) => Show (Interval a) where
   show :: Interval a -> String
show Interval a
x = String
"(" String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show (Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin Interval a
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
", " String -> String -> String
forall a. [a] -> [a] -> [a]
++ a -> String
forall a. Show a => a -> String
show (Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end Interval a
x) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"

instance (Ord a, Show a) => Intervallic Interval a where
    getInterval :: Interval a -> Interval a
getInterval = Interval a -> Interval a
forall a. a -> a
id
    setInterval :: Interval a -> Interval a -> Interval a
setInterval Interval a
_ Interval a
x = Interval a
x

instance (Eq a, Ord a, Show a) => IntervalAlgebraic Interval a

instance (Ord a, Show a) => IntervalCombinable Interval a where
    >< :: Interval a -> Interval a -> Maybe (Interval a)
(><) Interval a
x Interval a
y
        | Interval a
x ComparativePredicateOf (Interval a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`before` Interval 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. (a, a) -> Interval a
Interval (Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
end Interval a
x, Interval a -> a
forall (i :: * -> *) a. Intervallic i a => i a -> a
begin Interval a
y)
        | Bool
otherwise    = Maybe (Interval a)
forall a. Maybe a
Nothing

    <+> :: Interval a -> Interval a -> f (Interval a)
(<+>) Interval a
x Interval a
y
        | Interval a
x ComparativePredicateOf (Interval a)
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
ComparativePredicateOf (i a)
`before` Interval a
y = Interval a -> f (Interval a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ( Interval a -> Interval a
forall (i :: * -> *) a. Intervallic i a => i a -> Interval a
getInterval Interval a
x ) f (Interval a) -> f (Interval a) -> f (Interval a)
forall a. Semigroup a => a -> a -> a
<> Interval a -> f (Interval a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ( Interval a -> Interval a
forall (i :: * -> *) a. Intervallic i a => i a -> Interval a
getInterval Interval a
y )
        | Bool
otherwise    = Interval a -> f (Interval a)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ( Interval a -> Interval a -> Interval a
forall (i :: * -> *) a.
IntervalAlgebraic i a =>
i a -> i a -> Interval a
extenterval Interval a
x Interval a
y )

instance IntervalSizeable Int Int where
    moment :: Int
moment = Int
1
    add :: Int -> Int -> Int
add    = Int -> Int -> Int
forall a. Num a => a -> a -> a
(+)
    diff :: Int -> Int -> Int
diff   = (-)

instance IntervalSizeable Integer Integer where
    moment :: Integer
moment = Integer
1
    add :: Integer -> Integer -> Integer
add    = Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
(+)
    diff :: Integer -> Integer -> Integer
diff   = (-)

instance IntervalSizeable DT.Day Integer where
    moment :: Integer
moment = Integer
1
    add :: Integer -> Day -> Day
add    = Integer -> Day -> Day
addDays
    diff :: Day -> Day -> Integer
diff   = Day -> Day -> Integer
diffDays