module Util.Ranges (
Ranges, extract, extract1, pair_map
, ranges, sorted_ranges, merge_sorted, range, point, everything, nothing
, overlapping, overlapping_closed, intersection, invert
) where
import qualified Control.DeepSeq as DeepSeq
import qualified Data.List as List
import qualified Util.Lists as Lists
import qualified Util.Pretty as Pretty
data Ranges n = Ranges [(n, n)] | Everything
deriving (Ranges n -> Ranges n -> Bool
forall n. Eq n => Ranges n -> Ranges n -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Ranges n -> Ranges n -> Bool
$c/= :: forall n. Eq n => Ranges n -> Ranges n -> Bool
== :: Ranges n -> Ranges n -> Bool
$c== :: forall n. Eq n => Ranges n -> Ranges n -> Bool
Eq, Int -> Ranges n -> ShowS
forall n. Show n => Int -> Ranges n -> ShowS
forall n. Show n => [Ranges n] -> ShowS
forall n. Show n => Ranges n -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Ranges n] -> ShowS
$cshowList :: forall n. Show n => [Ranges n] -> ShowS
show :: Ranges n -> String
$cshow :: forall n. Show n => Ranges n -> String
showsPrec :: Int -> Ranges n -> ShowS
$cshowsPrec :: forall n. Show n => Int -> Ranges n -> ShowS
Show)
instance Ord n => Semigroup (Ranges n) where
Ranges n
Everything <> :: Ranges n -> Ranges n -> Ranges n
<> Ranges n
_ = forall n. Ranges n
Everything
Ranges n
_ <> Ranges n
Everything = forall n. Ranges n
Everything
Ranges [(n, n)]
r1 <> Ranges [(n, n)]
r2 = forall n. [(n, n)] -> Ranges n
Ranges (forall n. Ord n => [(n, n)] -> [(n, n)] -> [(n, n)]
merge [(n, n)]
r1 [(n, n)]
r2)
instance Ord n => Monoid (Ranges n) where
mempty :: Ranges n
mempty = forall n. [(n, n)] -> Ranges n
Ranges []
mappend :: Ranges n -> Ranges n -> Ranges n
mappend = forall a. Semigroup a => a -> a -> a
(<>)
instance Pretty.Pretty n => Pretty.Pretty (Ranges n) where
format :: Ranges n -> Doc
format (Ranges [(n, n)]
rs) = [Text] -> Doc
Pretty.textList (forall a b. (a -> b) -> [a] -> [b]
map forall {a} {a}. (Pretty a, Pretty a) => (a, a) -> Text
f [(n, n)]
rs)
where f :: (a, a) -> Text
f (a
s, a
e) = forall a. Pretty a => a -> Text
Pretty.pretty a
s forall a. Semigroup a => a -> a -> a
<> Text
"--" forall a. Semigroup a => a -> a -> a
<> forall a. Pretty a => a -> Text
Pretty.pretty a
e
format Ranges n
Everything = Text -> Doc
Pretty.text Text
"[*--*]"
instance DeepSeq.NFData n => DeepSeq.NFData (Ranges n) where
rnf :: Ranges n -> ()
rnf Ranges n
Everything = ()
rnf (Ranges [(n, n)]
xs) = forall a. NFData a => a -> ()
DeepSeq.rnf [(n, n)]
xs
extract :: Ranges n -> Maybe [(n, n)]
(Ranges [(n, n)]
pairs) = forall a. a -> Maybe a
Just [(n, n)]
pairs
extract Ranges n
Everything = forall a. Maybe a
Nothing
extract1 :: Ranges n -> Maybe (Maybe (n, n))
(Ranges [(n, n)]
pairs) = case (forall a. [a] -> Maybe a
Lists.head [(n, n)]
pairs, forall a. [a] -> Maybe a
Lists.last [(n, n)]
pairs) of
(Just (n
s, n
_), Just (n
_, n
e)) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just (n
s, n
e)
(Maybe (n, n), Maybe (n, n))
_ -> forall a. Maybe a
Nothing
extract1 Ranges n
Everything = forall a. a -> Maybe a
Just forall a. Maybe a
Nothing
pair_map :: Ord b => ((a, a) -> (b, b)) -> Ranges a -> Ranges b
pair_map :: forall b a. Ord b => ((a, a) -> (b, b)) -> Ranges a -> Ranges b
pair_map (a, a) -> (b, b)
f Ranges a
r = case forall n. Ranges n -> Maybe [(n, n)]
extract Ranges a
r of
Maybe [(a, a)]
Nothing -> forall n. Ranges n
everything
Just [(a, a)]
pairs -> forall n. Ord n => [(n, n)] -> Ranges n
sorted_ranges (forall a b. (a -> b) -> [a] -> [b]
map (a, a) -> (b, b)
f [(a, a)]
pairs)
ranges :: Ord n => [(n, n)] -> Ranges n
ranges :: forall n. Ord n => [(n, n)] -> Ranges n
ranges = forall n. Ord n => [(n, n)] -> Ranges n
sorted_ranges forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Ord a => [a] -> [a]
List.sort
sorted_ranges :: Ord n => [(n, n)] -> Ranges n
sorted_ranges :: forall n. Ord n => [(n, n)] -> Ranges n
sorted_ranges = forall n. [(n, n)] -> Ranges n
Ranges forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall n. Ord n => [(n, n)] -> [(n, n)]
merge_sorted
merge_sorted :: Ord n => [(n, n)] -> [(n, n)]
merge_sorted :: forall n. Ord n => [(n, n)] -> [(n, n)]
merge_sorted [] = []
merge_sorted [(n, n)
x] = [(n, n)
x]
merge_sorted ((n
s1, n
e1) : (n
s2, n
e2) : [(n, n)]
rest)
| n
e1 forall a. Ord a => a -> a -> Bool
>= n
e2 = forall n. Ord n => [(n, n)] -> [(n, n)]
merge_sorted ((n
s1, n
e1) forall a. a -> [a] -> [a]
: [(n, n)]
rest)
| n
e1 forall a. Ord a => a -> a -> Bool
>= n
s2 = forall n. Ord n => [(n, n)] -> [(n, n)]
merge_sorted ((n
s1, n
e2) forall a. a -> [a] -> [a]
: [(n, n)]
rest)
| Bool
otherwise = (n
s1, n
e1) forall a. a -> [a] -> [a]
: forall n. Ord n => [(n, n)] -> [(n, n)]
merge_sorted ((n
s2, n
e2) forall a. a -> [a] -> [a]
: [(n, n)]
rest)
range :: n -> n -> Ranges n
range :: forall n. n -> n -> Ranges n
range n
s n
e = forall n. [(n, n)] -> Ranges n
Ranges [(n
s, n
e)]
point :: n -> Ranges n
point :: forall n. n -> Ranges n
point n
p = forall n. n -> n -> Ranges n
range n
p n
p
everything :: Ranges n
everything :: forall n. Ranges n
everything = forall n. Ranges n
Everything
nothing :: Ranges n
nothing :: forall n. Ranges n
nothing = forall n. [(n, n)] -> Ranges n
Ranges []
overlapping :: Ord n => Ranges n -> Ranges n -> Bool
overlapping :: forall n. Ord n => Ranges n -> Ranges n -> Bool
overlapping = forall n. Ord n => Bool -> Ranges n -> Ranges n -> Bool
check_overlapping Bool
False
overlapping_closed :: Ord n => Ranges n -> Ranges n -> Bool
overlapping_closed :: forall n. Ord n => Ranges n -> Ranges n -> Bool
overlapping_closed = forall n. Ord n => Bool -> Ranges n -> Ranges n -> Bool
check_overlapping Bool
True
check_overlapping :: Ord n => Bool -> Ranges n -> Ranges n -> Bool
check_overlapping :: forall n. Ord n => Bool -> Ranges n -> Ranges n -> Bool
check_overlapping Bool
_ Ranges n
Everything Ranges n
r2 = Ranges n
r2 forall a. Eq a => a -> a -> Bool
/= forall n. Ranges n
nothing
check_overlapping Bool
_ Ranges n
r1 Ranges n
Everything = Ranges n
r1 forall a. Eq a => a -> a -> Bool
/= forall n. Ranges n
nothing
check_overlapping Bool
closed (Ranges [(n, n)]
r1) (Ranges [(n, n)]
r2) = forall {a}. Ord a => [(a, a)] -> [(a, a)] -> Bool
go [(n, n)]
r1 [(n, n)]
r2
where
go :: [(a, a)] -> [(a, a)] -> Bool
go [] [(a, a)]
_ = Bool
False
go [(a, a)]
_ [] = Bool
False
go r1 :: [(a, a)]
r1@((a
s1, a
e1) : [(a, a)]
rest1) r2 :: [(a, a)]
r2@((a
s2, a
e2) : [(a, a)]
rest2)
| a
s1 forall a. Eq a => a -> a -> Bool
== a
s2 = Bool
True
| a
e1 a -> a -> Bool
`lt` a
s2 = [(a, a)] -> [(a, a)] -> Bool
go [(a, a)]
rest1 [(a, a)]
r2
| a
e2 a -> a -> Bool
`lt` a
s1 = [(a, a)] -> [(a, a)] -> Bool
go [(a, a)]
r1 [(a, a)]
rest2
| Bool
otherwise = Bool
True
where lt :: a -> a -> Bool
lt = if Bool
closed then forall a. Ord a => a -> a -> Bool
(<) else forall a. Ord a => a -> a -> Bool
(<=)
intersection :: Ord n => Ranges n -> Ranges n -> Ranges n
intersection :: forall n. Ord n => Ranges n -> Ranges n -> Ranges n
intersection Ranges n
Everything Ranges n
r2 = Ranges n
r2
intersection Ranges n
r1 Ranges n
Everything = Ranges n
r1
intersection (Ranges [(n, n)]
r1) (Ranges [(n, n)]
r2) = forall n. [(n, n)] -> Ranges n
Ranges (forall n. Ord n => [(n, n)] -> [(n, n)] -> [(n, n)]
go [(n, n)]
r1 [(n, n)]
r2)
where
go :: [(a, a)] -> [(a, a)] -> [(a, a)]
go [] [(a, a)]
_ = []
go [(a, a)]
_ [] = []
go r1 :: [(a, a)]
r1@((a
s1, a
e1) : [(a, a)]
rest1) r2 :: [(a, a)]
r2@((a
s2, a
e2) : [(a, a)]
rest2)
| a
s1 forall a. Eq a => a -> a -> Bool
== a
s2 = (a
s1, forall a. Ord a => a -> a -> a
min a
e1 a
e2) forall a. a -> [a] -> [a]
: [(a, a)]
rest
| a
e1 forall a. Ord a => a -> a -> Bool
<= a
s2 = [(a, a)] -> [(a, a)] -> [(a, a)]
go [(a, a)]
rest1 [(a, a)]
r2
| a
e2 forall a. Ord a => a -> a -> Bool
<= a
s1 = [(a, a)] -> [(a, a)] -> [(a, a)]
go [(a, a)]
r1 [(a, a)]
rest2
| Bool
otherwise = (forall a. Ord a => a -> a -> a
max a
s1 a
s2, forall a. Ord a => a -> a -> a
min a
e1 a
e2) forall a. a -> [a] -> [a]
: [(a, a)]
rest
where rest :: [(a, a)]
rest = if a
e1 forall a. Ord a => a -> a -> Bool
< a
e2 then [(a, a)] -> [(a, a)] -> [(a, a)]
go [(a, a)]
rest1 [(a, a)]
r2 else [(a, a)] -> [(a, a)] -> [(a, a)]
go [(a, a)]
r1 [(a, a)]
rest2
merge :: Ord n => [(n, n)] -> [(n, n)] -> [(n, n)]
merge :: forall n. Ord n => [(n, n)] -> [(n, n)] -> [(n, n)]
merge [(n, n)]
r1 [(n, n)]
r2 = forall n. Ord n => [(n, n)] -> [(n, n)]
merge_sorted (forall k a. Ord k => (a -> k) -> [a] -> [a] -> [a]
Lists.mergeOn forall a b. (a, b) -> a
fst [(n, n)]
r1 [(n, n)]
r2)
invert :: Ord n => (n, n) -> Ranges n -> Ranges n
invert :: forall n. Ord n => (n, n) -> Ranges n -> Ranges n
invert (n, n)
_ Ranges n
Everything = forall a. Monoid a => a
mempty
invert (n
start, n
end) (Ranges [(n, n)]
pairs) = forall n. [(n, n)] -> Ranges n
Ranges forall a b. (a -> b) -> a -> b
$ n -> [(n, n)] -> [(n, n)]
go n
start [(n, n)]
pairs
where
go :: n -> [(n, n)] -> [(n, n)]
go n
p ((n
s, n
e) : [(n, n)]
rs)
| n
s forall a. Ord a => a -> a -> Bool
> n
p = (n
p, n
s) forall a. a -> [a] -> [a]
: n -> [(n, n)] -> [(n, n)]
go n
e [(n, n)]
rs
| Bool
otherwise = n -> [(n, n)] -> [(n, n)]
go n
e [(n, n)]
rs
go n
p [] = if n
p forall a. Ord a => a -> a -> Bool
< n
end then [(n
p, n
end)] else []