{-# LANGUAGE Safe #-}
module Data.RangeSet.Internal.TestingUtils (module Data.RangeSet.Internal.TestingUtils) where

import Prelude

import Control.Applicative (liftA2)

import Data.RangeSet.Internal.Types

-- Testing Utilities
valid :: RangeSet a -> Bool
valid :: forall a. RangeSet a -> Bool
valid RangeSet a
t = forall a. RangeSet a -> Bool
balanced RangeSet a
t Bool -> Bool -> Bool
&& forall a. Bool -> RangeSet a -> Bool
orderedNonOverlappingAndCompressed Bool
True RangeSet a
t

balanced :: RangeSet a -> Bool
balanced :: forall a. RangeSet a -> Bool
balanced RangeSet a
Tip = Bool
True
balanced (Fork H
h E
_ E
_ RangeSet a
lt RangeSet a
rt) =
  H
h forall a. Eq a => a -> a -> Bool
== forall a. Ord a => a -> a -> a
max (forall a. RangeSet a -> H
height RangeSet a
lt) (forall a. RangeSet a -> H
height RangeSet a
rt) forall a. Num a => a -> a -> a
+ H
1 Bool -> Bool -> Bool
&&
  forall a. RangeSet a -> H
height RangeSet a
rt forall a. Ord a => a -> a -> Bool
< H
h Bool -> Bool -> Bool
&&
  H -> H -> H
absDiff (forall a. RangeSet a -> H
height RangeSet a
lt) (forall a. RangeSet a -> H
height RangeSet a
rt) forall a. Ord a => a -> a -> Bool
<= H
1 Bool -> Bool -> Bool
&&
  forall a. RangeSet a -> Bool
balanced RangeSet a
lt Bool -> Bool -> Bool
&&
  forall a. RangeSet a -> Bool
balanced RangeSet a
rt

orderedNonOverlappingAndCompressed :: Bool -> RangeSet a -> Bool
orderedNonOverlappingAndCompressed :: forall a. Bool -> RangeSet a -> Bool
orderedNonOverlappingAndCompressed Bool
checkCompressed = forall a. (E -> Bool) -> (E -> Bool) -> RangeSet a -> Bool
bounded (forall a b. a -> b -> a
const Bool
True) (forall a b. a -> b -> a
const Bool
True)
  where
    bounded :: (E -> Bool) -> (E -> Bool) -> RangeSet a -> Bool
    bounded :: forall a. (E -> Bool) -> (E -> Bool) -> RangeSet a -> Bool
bounded E -> Bool
_ E -> Bool
_ RangeSet a
Tip = Bool
True
    bounded E -> Bool
lo E -> Bool
hi (Fork H
_ E
l E
u RangeSet a
lt RangeSet a
rt) =
      E
l forall a. Ord a => a -> a -> Bool
<= E
u Bool -> Bool -> Bool
&&
      E -> Bool
lo E
l Bool -> Bool -> Bool
&&
      E -> Bool
hi E
u Bool -> Bool -> Bool
&&
      forall a. (E -> Bool) -> (E -> Bool) -> RangeSet a -> Bool
bounded E -> Bool
lo (E -> E -> Bool
boundAbove E
l) RangeSet a
lt Bool -> Bool -> Bool
&&
      forall a. (E -> Bool) -> (E -> Bool) -> RangeSet a -> Bool
bounded (E -> E -> Bool
boundBelow E
u) E -> Bool
hi RangeSet a
rt

    boundAbove :: E -> E -> Bool
    boundAbove :: E -> E -> Bool
boundAbove E
l | Bool
checkCompressed = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (forall a. Ord a => a -> a -> Bool
< E
l) (forall a. Ord a => a -> a -> Bool
< forall a. Enum a => a -> a
pred E
l)
                 | Bool
otherwise = (forall a. Ord a => a -> a -> Bool
< E
l)

    boundBelow :: E -> E -> Bool
    boundBelow :: E -> E -> Bool
boundBelow E
u | Bool
checkCompressed = forall (f :: * -> *) a b c.
Applicative f =>
(a -> b -> c) -> f a -> f b -> f c
liftA2 Bool -> Bool -> Bool
(&&) (forall a. Ord a => a -> a -> Bool
> E
u) (forall a. Ord a => a -> a -> Bool
> forall a. Enum a => a -> a
succ E
u)
                 | Bool
otherwise = (forall a. Ord a => a -> a -> Bool
> E
u)