module MyPrioQueue where

import Data.List(sortOn)
import qualified Data.Map as M
import qualified Data.Set as S

data MyPrioQueue = MyPrioQueue (M.Map (Int, Int) (Double, Double))
                               (S.Set (Int, Int))
                   deriving (Show)

{- A priority queue function that removes a state from the queue -}
remove :: (Int, Int) -> MyPrioQueue -> MyPrioQueue
remove s (MyPrioQueue m states) = MyPrioQueue (M.delete s m) (S.delete s states)

{- A priority queue function that adds a (state, prio) pair to the queue -}
insert :: (Int, Int) -> (Double, Double) -> MyPrioQueue -> MyPrioQueue
insert s p (MyPrioQueue m states) = MyPrioQueue (M.insert s p m)
                                                (S.insert s states)

{- A priority queue function that returns the (state, prio) pair with the
   minimum priority -}
findMin :: MyPrioQueue -> ((Int, Int), (Double, Double))
findMin (MyPrioQueue m _) = head $ sortOn snd $ M.toList m

{- A priority queue function that returns a boolean indicating whether a state
   is in the queue -}
member :: (Int, Int) -> MyPrioQueue -> Bool
member s (MyPrioQueue _ states) = s `S.member` states

{- A priority queue function that returns a boolean indicating whether the
   queue is empty -}
empty :: MyPrioQueue -> Bool
empty (MyPrioQueue _ s) = S.size s == 0
