{-# LANGUAGE GADTs
           , UnboxedTuples #-}

module Radix.Common
  ( PartialOrdering (..)
  , order

  , S (..)
  , other
  , limit
  ) where



-- | Comparison of two sets, \(A\) and \(B\) respectively.
data PartialOrdering = Subset       -- ^ \(A \subset B\).
                     | Superset     -- ^ \(A \supset B\).
                     | Equal        -- ^ \(A = B\).
                     | Incomparable -- ^ \(A \parallel B\).
                       deriving (Int -> PartialOrdering -> ShowS
[PartialOrdering] -> ShowS
PartialOrdering -> String
(Int -> PartialOrdering -> ShowS)
-> (PartialOrdering -> String)
-> ([PartialOrdering] -> ShowS)
-> Show PartialOrdering
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> PartialOrdering -> ShowS
showsPrec :: Int -> PartialOrdering -> ShowS
$cshow :: PartialOrdering -> String
show :: PartialOrdering -> String
$cshowList :: [PartialOrdering] -> ShowS
showList :: [PartialOrdering] -> ShowS
Show, PartialOrdering -> PartialOrdering -> Bool
(PartialOrdering -> PartialOrdering -> Bool)
-> (PartialOrdering -> PartialOrdering -> Bool)
-> Eq PartialOrdering
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: PartialOrdering -> PartialOrdering -> Bool
== :: PartialOrdering -> PartialOrdering -> Bool
$c/= :: PartialOrdering -> PartialOrdering -> Bool
/= :: PartialOrdering -> PartialOrdering -> Bool
Eq)

-- | Comparison of two partial orderings.
order :: PartialOrdering -> PartialOrdering -> PartialOrdering
order :: PartialOrdering -> PartialOrdering -> PartialOrdering
order PartialOrdering
Subset   PartialOrdering
Subset   = PartialOrdering
Subset
order PartialOrdering
Subset   PartialOrdering
Equal    = PartialOrdering
Subset

order PartialOrdering
Superset PartialOrdering
Superset = PartialOrdering
Superset
order PartialOrdering
Superset PartialOrdering
Equal    = PartialOrdering
Superset

order PartialOrdering
Equal    PartialOrdering
o        = PartialOrdering
o

order PartialOrdering
_        PartialOrdering
_        = PartialOrdering
Incomparable



-- | Merge side.
data S a b x y where
  L :: S x y x y
  R :: S y x x y

-- | The other merge side.
other :: S a b x y -> (# S b a x y #)
other :: forall a b x y. S a b x y -> (# S b a x y #)
other S a b x y
L = (# S b a a b
S b a x y
forall y x. S y x x y
R #)
other S a b x y
R = (# S b a b a
S b a x y
forall x y. S x y x y
L #)

-- | Limits the left side to a 'Subset'.
limit :: S x y a b -> PartialOrdering -> PartialOrdering
limit :: forall x y a b. S x y a b -> PartialOrdering -> PartialOrdering
limit S x y a b
L PartialOrdering
Superset = PartialOrdering
Incomparable
limit S x y a b
R PartialOrdering
Subset   = PartialOrdering
Incomparable
limit S x y a b
s PartialOrdering
Equal    = case S x y a b
s of
                     S x y a b
L -> PartialOrdering
Subset
                     S x y a b
R -> PartialOrdering
Superset
limit S x y a b
_ PartialOrdering
o        = PartialOrdering
o