rings-0.0.2: src/Data/Dioid/Interval.hs
-- | <https://en.wikipedia.org/wiki/Partially_ordered_set#Intervals>
module Data.Dioid.Interval (
Interval()
, (...)
, endpts
, singleton
, upset
, dnset
, empty
) where
import Data.Prd
import Data.Prd.Lattice
import Data.Connection
import Prelude
{-
ivllat :: (Lattice a, Bound a) => Trip (Interval a) a
ivllat = Trip f g h where
f = maybe minimal (uncurry (\/)) . endpts
g = singleton
h = maybe maximal (uncurry (/\)) . endpts
indexed :: Index a => Conn (Interval a) (Maybe (Down a, a))
https://en.wikipedia.org/wiki/Locally_finite_poset
https://en.wikipedia.org/wiki/Incidence_algebra
An interval in a poset P is a subset I of P with the property that, for any x and y in I and any z in P, if x ≤ z ≤ y, then z is also in I.
-}
data Interval a = I !a !a | Empty deriving (Eq, Show)
-- Interval order
-- https://en.wikipedia.org/wiki/Interval_order
instance Ord a => Prd (Interval a) where
Empty <~ Empty = True
Empty <~ _ = False
i@(I _ x) <~ j@(I y _) = x < y || i == j
{-
-- Containment order
-- https://en.wikipedia.org/wiki/Containment_order
instance Prd a => Prd (Interval a) where
Empty <~ _ = True
I x y <~ I x' y' = x' <~ x && y <~ y'
-}
infix 3 ...
-- | Construct an interval from a pair of points.
--
-- If @a <~ b@ then @a ... b = Empty@.
--
(...) :: Prd a => a -> a -> Interval a
a ... b
| a <~ b = I a b
| otherwise = Empty
{-# INLINE (...) #-}
-- | Obtain the endpoints of an interval.
--
endpts :: Interval a -> Maybe (a, a)
endpts Empty = Nothing
endpts (I x y) = Just (x, y)
{-# INLINE endpts #-}
-- | Construct an interval containing a single point.
--
-- >>> singleton 1
-- 1 ... 1
--
singleton :: a -> Interval a
singleton a = I a a
{-# INLINE singleton #-}
{-
properties:
Yoneda lemma for preorders:
x <~ y <==> upset x <~ upset y --containment order
-}
-- | \( X_\geq(x) = \{ y \in X | y \geq x \} \)
--
-- Construct the upper set of an element /x/.
--
-- This function is monotone wrt the containment order.
--
upset :: Max a => a -> Interval a
upset x = x ... maximal
{-# INLINE upset #-}
-- | \( X_\leq(x) = \{ y \in X | y \leq x \} \)
--
-- Construct the lower set of an element /x/.
--
-- This function is antitone wrt the containment order.
--
dnset :: Min a => a -> Interval a
dnset x = minimal ... x
{-# INLINE dnset #-}
-- | The empty interval.
--
-- >>> empty
-- Empty
empty :: Interval a
empty = Empty
{-# INLINE empty #-}