{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveDataTypeable #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Data.Semiring.Tropical
( Tropical(Infinity,Tropical)
, Extrema(Minima,Maxima)
, Extremum(extremum)
, EProxy(EProxy)
) where
#if MIN_VERSION_base(4,7,0)
import Data.Data (Data)
#endif
import Data.Semiring (Semiring(..))
import Data.Star (Star(..))
#if MIN_VERSION_base(4,7,0)
import Data.Typeable (Typeable)
#endif
import qualified Data.Monoid as Monoid
data EProxy (e :: Extrema) = EProxy
data Extrema = Minima | Maxima
class Extremum (e :: Extrema) where
extremum :: EProxy e -> Extrema
instance Extremum 'Minima where
extremum :: EProxy 'Minima -> Extrema
extremum EProxy 'Minima
_ = Extrema
Minima
{-# INLINE extremum #-}
instance Extremum 'Maxima where
extremum :: EProxy 'Maxima -> Extrema
extremum EProxy 'Maxima
_ = Extrema
Maxima
{-# INLINE extremum #-}
data Tropical (e :: Extrema) a
= Infinity
| Tropical a
deriving
( Tropical e a -> Tropical e a -> Bool
(Tropical e a -> Tropical e a -> Bool)
-> (Tropical e a -> Tropical e a -> Bool) -> Eq (Tropical e a)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (e :: Extrema) a.
Eq a =>
Tropical e a -> Tropical e a -> Bool
/= :: Tropical e a -> Tropical e a -> Bool
$c/= :: forall (e :: Extrema) a.
Eq a =>
Tropical e a -> Tropical e a -> Bool
== :: Tropical e a -> Tropical e a -> Bool
$c== :: forall (e :: Extrema) a.
Eq a =>
Tropical e a -> Tropical e a -> Bool
Eq
, Int -> Tropical e a -> ShowS
[Tropical e a] -> ShowS
Tropical e a -> String
(Int -> Tropical e a -> ShowS)
-> (Tropical e a -> String)
-> ([Tropical e a] -> ShowS)
-> Show (Tropical e a)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (e :: Extrema) a. Show a => Int -> Tropical e a -> ShowS
forall (e :: Extrema) a. Show a => [Tropical e a] -> ShowS
forall (e :: Extrema) a. Show a => Tropical e a -> String
showList :: [Tropical e a] -> ShowS
$cshowList :: forall (e :: Extrema) a. Show a => [Tropical e a] -> ShowS
show :: Tropical e a -> String
$cshow :: forall (e :: Extrema) a. Show a => Tropical e a -> String
showsPrec :: Int -> Tropical e a -> ShowS
$cshowsPrec :: forall (e :: Extrema) a. Show a => Int -> Tropical e a -> ShowS
Show
, ReadPrec [Tropical e a]
ReadPrec (Tropical e a)
Int -> ReadS (Tropical e a)
ReadS [Tropical e a]
(Int -> ReadS (Tropical e a))
-> ReadS [Tropical e a]
-> ReadPrec (Tropical e a)
-> ReadPrec [Tropical e a]
-> Read (Tropical e a)
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
forall (e :: Extrema) a. Read a => ReadPrec [Tropical e a]
forall (e :: Extrema) a. Read a => ReadPrec (Tropical e a)
forall (e :: Extrema) a. Read a => Int -> ReadS (Tropical e a)
forall (e :: Extrema) a. Read a => ReadS [Tropical e a]
readListPrec :: ReadPrec [Tropical e a]
$creadListPrec :: forall (e :: Extrema) a. Read a => ReadPrec [Tropical e a]
readPrec :: ReadPrec (Tropical e a)
$creadPrec :: forall (e :: Extrema) a. Read a => ReadPrec (Tropical e a)
readList :: ReadS [Tropical e a]
$creadList :: forall (e :: Extrema) a. Read a => ReadS [Tropical e a]
readsPrec :: Int -> ReadS (Tropical e a)
$creadsPrec :: forall (e :: Extrema) a. Read a => Int -> ReadS (Tropical e a)
Read
#if MIN_VERSION_base(4,7,0)
, Typeable
, Typeable (Tropical e a)
DataType
Constr
Typeable (Tropical e a)
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Tropical e a -> c (Tropical e a))
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Tropical e a))
-> (Tropical e a -> Constr)
-> (Tropical e a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Tropical e a)))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Tropical e a)))
-> ((forall b. Data b => b -> b) -> Tropical e a -> Tropical e a)
-> (forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Tropical e a -> r)
-> (forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Tropical e a -> r)
-> (forall u. (forall d. Data d => d -> u) -> Tropical e a -> [u])
-> (forall u.
Int -> (forall d. Data d => d -> u) -> Tropical e a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a))
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a))
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a))
-> Data (Tropical e a)
Tropical e a -> DataType
Tropical e a -> Constr
(forall b. Data b => b -> b) -> Tropical e a -> Tropical e a
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Tropical e a -> c (Tropical e a)
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Tropical e a)
forall a.
Typeable a
-> (forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Tropical e a -> u
forall u. (forall d. Data d => d -> u) -> Tropical e a -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Tropical e a -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Tropical e a -> r
forall (e :: Extrema) a.
(Typeable e, Data a) =>
Typeable (Tropical e a)
forall (e :: Extrema) a.
(Typeable e, Data a) =>
Tropical e a -> DataType
forall (e :: Extrema) a.
(Typeable e, Data a) =>
Tropical e a -> Constr
forall (e :: Extrema) a.
(Typeable e, Data a) =>
(forall b. Data b => b -> b) -> Tropical e a -> Tropical e a
forall (e :: Extrema) a u.
(Typeable e, Data a) =>
Int -> (forall d. Data d => d -> u) -> Tropical e a -> u
forall (e :: Extrema) a u.
(Typeable e, Data a) =>
(forall d. Data d => d -> u) -> Tropical e a -> [u]
forall (e :: Extrema) a r r'.
(Typeable e, Data a) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Tropical e a -> r
forall (e :: Extrema) a r r'.
(Typeable e, Data a) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Tropical e a -> r
forall (e :: Extrema) a (m :: * -> *).
(Typeable e, Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a)
forall (e :: Extrema) a (m :: * -> *).
(Typeable e, Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a)
forall (e :: Extrema) a (c :: * -> *).
(Typeable e, Data a) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Tropical e a)
forall (e :: Extrema) a (c :: * -> *).
(Typeable e, Data a) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Tropical e a -> c (Tropical e a)
forall (e :: Extrema) a (t :: * -> *) (c :: * -> *).
(Typeable e, Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Tropical e a))
forall (e :: Extrema) a (t :: * -> * -> *) (c :: * -> *).
(Typeable e, Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Tropical e a))
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a)
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a)
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Tropical e a)
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Tropical e a -> c (Tropical e a)
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c (Tropical e a))
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Tropical e a))
$cTropical :: Constr
$cInfinity :: Constr
$tTropical :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a)
$cgmapMo :: forall (e :: Extrema) a (m :: * -> *).
(Typeable e, Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a)
gmapMp :: (forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a)
$cgmapMp :: forall (e :: Extrema) a (m :: * -> *).
(Typeable e, Data a, MonadPlus m) =>
(forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a)
gmapM :: (forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a)
$cgmapM :: forall (e :: Extrema) a (m :: * -> *).
(Typeable e, Data a, Monad m) =>
(forall d. Data d => d -> m d) -> Tropical e a -> m (Tropical e a)
gmapQi :: Int -> (forall d. Data d => d -> u) -> Tropical e a -> u
$cgmapQi :: forall (e :: Extrema) a u.
(Typeable e, Data a) =>
Int -> (forall d. Data d => d -> u) -> Tropical e a -> u
gmapQ :: (forall d. Data d => d -> u) -> Tropical e a -> [u]
$cgmapQ :: forall (e :: Extrema) a u.
(Typeable e, Data a) =>
(forall d. Data d => d -> u) -> Tropical e a -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Tropical e a -> r
$cgmapQr :: forall (e :: Extrema) a r r'.
(Typeable e, Data a) =>
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> Tropical e a -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Tropical e a -> r
$cgmapQl :: forall (e :: Extrema) a r r'.
(Typeable e, Data a) =>
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> Tropical e a -> r
gmapT :: (forall b. Data b => b -> b) -> Tropical e a -> Tropical e a
$cgmapT :: forall (e :: Extrema) a.
(Typeable e, Data a) =>
(forall b. Data b => b -> b) -> Tropical e a -> Tropical e a
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Tropical e a))
$cdataCast2 :: forall (e :: Extrema) a (t :: * -> * -> *) (c :: * -> *).
(Typeable e, Data a, Typeable t) =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c (Tropical e a))
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c (Tropical e a))
$cdataCast1 :: forall (e :: Extrema) a (t :: * -> *) (c :: * -> *).
(Typeable e, Data a, Typeable t) =>
(forall d. Data d => c (t d)) -> Maybe (c (Tropical e a))
dataTypeOf :: Tropical e a -> DataType
$cdataTypeOf :: forall (e :: Extrema) a.
(Typeable e, Data a) =>
Tropical e a -> DataType
toConstr :: Tropical e a -> Constr
$ctoConstr :: forall (e :: Extrema) a.
(Typeable e, Data a) =>
Tropical e a -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Tropical e a)
$cgunfold :: forall (e :: Extrema) a (c :: * -> *).
(Typeable e, Data a) =>
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c (Tropical e a)
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Tropical e a -> c (Tropical e a)
$cgfoldl :: forall (e :: Extrema) a (c :: * -> *).
(Typeable e, Data a) =>
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Tropical e a -> c (Tropical e a)
$cp1Data :: forall (e :: Extrema) a.
(Typeable e, Data a) =>
Typeable (Tropical e a)
Data
#endif
)
instance forall e a. (Ord a, Extremum e) => Ord (Tropical e a) where
compare :: Tropical e a -> Tropical e a -> Ordering
compare Tropical e a
Infinity Tropical e a
Infinity = Ordering
EQ
compare Tropical e a
Infinity Tropical e a
_ = case EProxy e -> Extrema
forall (e :: Extrema). Extremum e => EProxy e -> Extrema
extremum (EProxy e
forall (e :: Extrema). EProxy e
EProxy :: EProxy e) of
Extrema
Minima -> Ordering
GT
Extrema
Maxima -> Ordering
LT
compare Tropical e a
_ Tropical e a
Infinity = case EProxy e -> Extrema
forall (e :: Extrema). Extremum e => EProxy e -> Extrema
extremum (EProxy e
forall (e :: Extrema). EProxy e
EProxy :: EProxy e) of
Extrema
Minima -> Ordering
LT
Extrema
Maxima -> Ordering
GT
compare (Tropical a
x) (Tropical a
y) = a -> a -> Ordering
forall a. Ord a => a -> a -> Ordering
compare a
x a
y
instance forall e a. (Ord a, Monoid.Monoid a, Extremum e) => Semiring (Tropical e a) where
zero :: Tropical e a
zero = Tropical e a
forall (e :: Extrema) a. Tropical e a
Infinity
one :: Tropical e a
one = a -> Tropical e a
forall (e :: Extrema) a. a -> Tropical e a
Tropical a
forall a. Monoid a => a
Monoid.mempty
plus :: Tropical e a -> Tropical e a -> Tropical e a
plus Tropical e a
Infinity Tropical e a
y = Tropical e a
y
plus Tropical e a
x Tropical e a
Infinity = Tropical e a
x
plus (Tropical a
x) (Tropical a
y) = a -> Tropical e a
forall (e :: Extrema) a. a -> Tropical e a
Tropical
( case EProxy e -> Extrema
forall (e :: Extrema). Extremum e => EProxy e -> Extrema
extremum (EProxy e
forall (e :: Extrema). EProxy e
EProxy :: EProxy e) of
Extrema
Minima -> a -> a -> a
forall a. Ord a => a -> a -> a
min a
x a
y
Extrema
Maxima -> a -> a -> a
forall a. Ord a => a -> a -> a
max a
x a
y
)
times :: Tropical e a -> Tropical e a -> Tropical e a
times Tropical e a
Infinity Tropical e a
_ = Tropical e a
forall (e :: Extrema) a. Tropical e a
Infinity
times Tropical e a
_ Tropical e a
Infinity = Tropical e a
forall (e :: Extrema) a. Tropical e a
Infinity
times (Tropical a
x) (Tropical a
y) = a -> Tropical e a
forall (e :: Extrema) a. a -> Tropical e a
Tropical (a -> a -> a
forall a. Monoid a => a -> a -> a
Monoid.mappend a
x a
y)
fromNatural :: Natural -> Tropical e a
fromNatural Natural
0 = Tropical e a
forall a. Semiring a => a
zero
fromNatural Natural
_ = Tropical e a
forall a. Semiring a => a
one
instance forall e a. (Ord a, Monoid.Monoid a, Extremum e) => Star (Tropical e a) where
star :: Tropical e a -> Tropical e a
star Tropical e a
_ = Tropical e a
forall a. Semiring a => a
one