-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Pure priority search queues
--   
--   The psqueues package provides <a>Priority Search Queues</a> in three
--   different flavors.
--   
--   <ul>
--   <li><tt>OrdPSQ k p v</tt>, which uses the <tt>Ord k</tt> instance to
--   provide fast insertion, deletion and lookup. This implementation is
--   based on Ralf Hinze's <a>A Simple Implementation Technique for
--   Priority Search Queues</a>. Hence, it is similar to the <a>PSQueue</a>
--   library, although it is considerably faster and provides a slightly
--   different API.</li>
--   <li><tt>IntPSQ p v</tt> is a far more efficient implementation. It
--   fixes the key type to <tt>Int</tt> and uses a <a>radix tree</a> (like
--   <tt>IntMap</tt>) with an additional min-heap property.</li>
--   <li><tt>HashPSQ k p v</tt> is a fairly straightforward extension of
--   <tt>IntPSQ</tt>: it simply uses the keys' hashes as indices in the
--   <tt>IntPSQ</tt>. If there are any hash collisions, it uses an
--   <tt>OrdPSQ</tt> to resolve those. The performance of this
--   implementation is comparable to that of <tt>IntPSQ</tt>, but it is
--   more widely applicable since the keys are not restricted to
--   <tt>Int</tt>, but rather to any <tt>Hashable</tt> datatype.</li>
--   </ul>
--   
--   Each of the three implementations provides the same API, so they can
--   be used interchangeably. The benchmarks show how they perform relative
--   to one another, and also compared to the other Priority Search Queue
--   implementations on Hackage: <a>PSQueue</a> and
--   <a>fingertree-psqueue</a>.
--   
--   
--   
--   Typical applications of Priority Search Queues include:
--   
--   <ul>
--   <li>Caches, and more specifically LRU Caches;</li>
--   <li>Schedulers;</li>
--   <li>Pathfinding algorithms, such as Dijkstra's and A*.</li>
--   </ul>
@package psqueues
@version 0.2.2.0


-- | An <a>OrdPSQ</a> uses the <a>Ord</a> instance of the key type to build
--   a priority search queue.
--   
--   It is based on Ralf Hinze's work.
--   
--   <ul>
--   <li>Hinze, R., A Simple Implementation Technique for Priority Search
--   Queues, ICFP 2001, pp. 110-121</li>
--   </ul>
--   
--   <a>http://citeseer.ist.psu.edu/hinze01simple.html</a>
--   
--   This means it is similar to the <a>PSQueue</a> package but our
--   benchmarks showed it perform quite a bit faster.
module Data.OrdPSQ

-- | A mapping from keys <tt>k</tt> to priorites <tt>p</tt> and values
--   <tt>v</tt>. It is strict in keys, priorities and values.
data OrdPSQ k p v

-- | <i>O(1)</i> True if the queue is empty.
null :: OrdPSQ k p v -> Bool

-- | <i>O(1)</i> The number of elements in a queue.
size :: OrdPSQ k p v -> Int

-- | <i>O(log n)</i> Check if a key is present in the the queue.
member :: Ord k => k -> OrdPSQ k p v -> Bool

-- | <i>O(log n)</i> The priority and value of a given key, or
--   <a>Nothing</a> if the key is not bound.
lookup :: (Ord k) => k -> OrdPSQ k p v -> Maybe (p, v)

-- | <i>O(1)</i> The element with the lowest priority.
findMin :: OrdPSQ k p v -> Maybe (k, p, v)

-- | <i>O(1)</i> The empty queue.
empty :: OrdPSQ k p v

-- | <i>O(1)</i> Build a queue with one element.
singleton :: k -> p -> v -> OrdPSQ k p v

-- | <i>O(log n)</i> Insert a new key, priority and value into the queue.
--   If the key is already present in the queue, the associated priority
--   and value are replaced with the supplied priority and value.
insert :: (Ord k, Ord p) => k -> p -> v -> OrdPSQ k p v -> OrdPSQ k p v

-- | <i>O(log n)</i> Delete a key and its priority and value from the
--   queue. When the key is not a member of the queue, the original queue
--   is returned.
delete :: (Ord k, Ord p) => k -> OrdPSQ k p v -> OrdPSQ k p v

-- | <i>O(log n)</i> Delete the binding with the least priority, and return
--   the rest of the queue stripped of that binding. In case the queue is
--   empty, the empty queue is returned again.
deleteMin :: (Ord k, Ord p) => OrdPSQ k p v -> OrdPSQ k p v

-- | <i>O(log n)</i> The expression <tt>alter f k queue</tt> alters the
--   value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a> can
--   be used to insert, delete, or update a value in a queue. It also
--   allows you to calculate an additional value <tt>b</tt>.
alter :: (Ord k, Ord p) => (Maybe (p, v) -> (b, Maybe (p, v))) -> k -> OrdPSQ k p v -> (b, OrdPSQ k p v)

-- | <i>O(log n)</i> A variant of <a>alter</a> which works on the element
--   with the minimum priority. Unlike <a>alter</a>, this variant also
--   allows you to change the key of the element.
alterMin :: (Ord k, Ord p) => (Maybe (k, p, v) -> (b, Maybe (k, p, v))) -> OrdPSQ k p v -> (b, OrdPSQ k p v)

-- | <i>O(n*log n)</i> Build a queue from a list of (key, priority, value)
--   tuples. If the list contains more than one priority and value for the
--   same key, the last priority and value for the key is retained.
fromList :: (Ord k, Ord p) => [(k, p, v)] -> OrdPSQ k p v

-- | <i>O(n)</i> Convert a queue to a list of (key, priority, value)
--   tuples. The order of the list is not specified.
toList :: OrdPSQ k p v -> [(k, p, v)]

-- | <i>O(n)</i> Convert to an ascending list.
toAscList :: OrdPSQ k p v -> [(k, p, v)]

-- | <i>O(n)</i> Obtain the list of present keys in the queue.
keys :: OrdPSQ k p v -> [k]

-- | <i>O(log n)</i> Insert a new key, priority and value into the queue.
--   If the key is already present in the queue, then the evicted priority
--   and value can be found the first element of the returned tuple.
insertView :: (Ord k, Ord p) => k -> p -> v -> OrdPSQ k p v -> (Maybe (p, v), OrdPSQ k p v)

-- | <i>O(log n)</i> Delete a key and its priority and value from the
--   queue. If the key was present, the associated priority and value are
--   returned in addition to the updated queue.
deleteView :: (Ord k, Ord p) => k -> OrdPSQ k p v -> Maybe (p, v, OrdPSQ k p v)

-- | <i>O(log n)</i> Retrieve the binding with the least priority, and the
--   rest of the queue stripped of that binding.
minView :: (Ord k, Ord p) => OrdPSQ k p v -> Maybe (k, p, v, OrdPSQ k p v)

-- | <i>O(n)</i> Modify every value in the queue.
map :: (k -> p -> v -> w) -> OrdPSQ k p v -> OrdPSQ k p w

-- | <i>O(n)</i> Strict fold over every key, priority and value in the
--   queue. The order in which the fold is performed is not specified.
fold' :: (k -> p -> v -> a -> a) -> a -> OrdPSQ k p v -> a

-- | <i>O(n^2)</i> Internal function to check if the <a>OrdPSQ</a> is
--   valid, i.e. if all invariants hold. This should always be the case.
valid :: (Ord k, Ord p) => OrdPSQ k p v -> Bool


-- | <a>IntPSQ</a> fixes the key type to <a>Int</a>. It is generally much
--   faster than an <tt>OrdPSQ</tt>.
--   
--   Many operations have a worst-case complexity of O(min(n,W)). This
--   means that the operation can -- become linear in the number of
--   elements with a maximum of W -- the number of bits in an Int (32 or
--   64).
module Data.IntPSQ

-- | A priority search queue with <tt>Int</tt> keys and priorities of type
--   <tt>p</tt> and values of type <tt>v</tt>. It is strict in keys,
--   priorities and values.
data IntPSQ p v

-- | <i>O(1)</i> True if the queue is empty.
null :: IntPSQ p v -> Bool

-- | <i>O(n)</i> The number of elements stored in the queue.
size :: IntPSQ p v -> Int

-- | <i>O(min(n,W))</i> Check if a key is present in the the queue.
member :: Int -> IntPSQ p v -> Bool

-- | <i>O(min(n,W))</i> The priority and value of a given key, or
--   <a>Nothing</a> if the key is not bound.
lookup :: Int -> IntPSQ p v -> Maybe (p, v)

-- | <i>O(1)</i> The element with the lowest priority.
findMin :: Ord p => IntPSQ p v -> Maybe (Int, p, v)

-- | <i>O(1)</i> The empty queue.
empty :: IntPSQ p v

-- | <i>O(1)</i> Build a queue with one element.
singleton :: Ord p => Int -> p -> v -> IntPSQ p v

-- | <i>O(min(n,W))</i> Insert a new key, priority and value into the
--   queue. If the key is already present in the queue, the associated
--   priority and value are replaced with the supplied priority and value.
insert :: Ord p => Int -> p -> v -> IntPSQ p v -> IntPSQ p v

-- | <i>O(min(n,W))</i> Delete a key and its priority and value from the
--   queue. When the key is not a member of the queue, the original queue
--   is returned.
delete :: Ord p => Int -> IntPSQ p v -> IntPSQ p v

-- | <i>O(min(n,W))</i> Delete the binding with the least priority, and
--   return the rest of the queue stripped of that binding. In case the
--   queue is empty, the empty queue is returned again.
deleteMin :: Ord p => IntPSQ p v -> IntPSQ p v

-- | <i>O(min(n,W))</i> The expression <tt>alter f k queue</tt> alters the
--   value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a> can
--   be used to insert, delete, or update a value in a queue. It also
--   allows you to calculate an additional value <tt>b</tt>.
alter :: Ord p => (Maybe (p, v) -> (b, Maybe (p, v))) -> Int -> IntPSQ p v -> (b, IntPSQ p v)

-- | <i>O(min(n,W))</i> A variant of <a>alter</a> which works on the
--   element with the minimum priority. Unlike <a>alter</a>, this variant
--   also allows you to change the key of the element.
alterMin :: Ord p => (Maybe (Int, p, v) -> (b, Maybe (Int, p, v))) -> IntPSQ p v -> (b, IntPSQ p v)

-- | <i>O(n*min(n,W))</i> Build a queue from a list of (key, priority,
--   value) tuples. If the list contains more than one priority and value
--   for the same key, the last priority and value for the key is retained.
fromList :: Ord p => [(Int, p, v)] -> IntPSQ p v

-- | <i>O(n)</i> Convert a queue to a list of (key, priority, value)
--   tuples. The order of the list is not specified.
toList :: IntPSQ p v -> [(Int, p, v)]

-- | <i>O(n)</i> Obtain the list of present keys in the queue.
keys :: IntPSQ p v -> [Int]

-- | <i>O(min(n,W))</i> Insert a new key, priority and value into the
--   queue. If the key is already present in the queue, then the evicted
--   priority and value can be found the first element of the returned
--   tuple.
insertView :: Ord p => Int -> p -> v -> IntPSQ p v -> (Maybe (p, v), IntPSQ p v)

-- | <i>O(min(n,W))</i> Delete a key and its priority and value from the
--   queue. If the key was present, the associated priority and value are
--   returned in addition to the updated queue.
deleteView :: Ord p => Int -> IntPSQ p v -> Maybe (p, v, IntPSQ p v)

-- | <i>O(min(n,W))</i> Retrieve the binding with the least priority, and
--   the rest of the queue stripped of that binding.
minView :: Ord p => IntPSQ p v -> Maybe (Int, p, v, IntPSQ p v)

-- | <i>O(n)</i> Modify every value in the queue.
map :: (Int -> p -> v -> w) -> IntPSQ p v -> IntPSQ p w

-- | <i>O(n)</i> Strict fold over every key, priority and value in the
--   queue. The order in which the fold is performed is not specified.
fold' :: (Int -> p -> v -> a -> a) -> a -> IntPSQ p v -> a

-- | <i>O(n^2)</i> Internal function to check if the <a>IntPSQ</a> is
--   valid, i.e. if all invariants hold. This should always be the case.
valid :: Ord p => IntPSQ p v -> Bool


-- | A <a>HashPSQ</a> offers very similar performance to <tt>IntPSQ</tt>.
--   In case of collisions, it uses an <tt>OrdPSQ</tt> locally to solve
--   those.
--   
--   This means worst case complexity is usually given by <i>O(min(n,W),
--   log n)</i>, where <i>W</i> is the number of bits in an <a>Int</a>.
--   This simplifies to <i>O(min(n,W))</i> since <i>log n</i> is always
--   smaller than <i>W</i> on current machines.
module Data.HashPSQ

-- | A priority search queue with keys of type <tt>k</tt> and priorities of
--   type <tt>p</tt> and values of type <tt>v</tt>. It is strict in keys,
--   priorities and values.
data HashPSQ k p v

-- | <i>O(1)</i> True if the queue is empty.
null :: HashPSQ k p v -> Bool

-- | <i>O(n)</i> The number of elements stored in the PSQ.
size :: HashPSQ k p v -> Int

-- | <i>O(min(n,W))</i> Check if a key is present in the the queue.
member :: (Hashable k, Ord k, Ord p) => k -> HashPSQ k p v -> Bool

-- | <i>O(min(n,W))</i> The priority and value of a given key, or
--   <a>Nothing</a> if the key is not bound.
lookup :: (Ord k, Hashable k, Ord p) => k -> HashPSQ k p v -> Maybe (p, v)

-- | <i>O(1)</i> The element with the lowest priority.
findMin :: (Hashable k, Ord k, Ord p) => HashPSQ k p v -> Maybe (k, p, v)

-- | <i>O(1)</i> The empty queue.
empty :: HashPSQ k p v

-- | <i>O(1)</i> Build a queue with one element.
singleton :: (Hashable k, Ord k, Ord p) => k -> p -> v -> HashPSQ k p v

-- | <i>O(min(n,W))</i> Insert a new key, priority and value into the
--   queue. If the key is already present in the queue, the associated
--   priority and value are replaced with the supplied priority and value.
insert :: (Ord k, Hashable k, Ord p) => k -> p -> v -> HashPSQ k p v -> HashPSQ k p v

-- | <i>O(min(n,W))</i> Delete a key and its priority and value from the
--   queue. When the key is not a member of the queue, the original queue
--   is returned.
delete :: (Hashable k, Ord k, Ord p) => k -> HashPSQ k p v -> HashPSQ k p v

-- | <i>O(min(n,W))</i> Delete the binding with the least priority, and
--   return the rest of the queue stripped of that binding. In case the
--   queue is empty, the empty queue is returned again.
deleteMin :: (Hashable k, Ord k, Ord p) => HashPSQ k p v -> HashPSQ k p v

-- | <i>O(min(n,W))</i> The expression <tt>alter f k queue</tt> alters the
--   value <tt>x</tt> at <tt>k</tt>, or absence thereof. <a>alter</a> can
--   be used to insert, delete, or update a value in a queue. It also
--   allows you to calculate an additional value <tt>b</tt>.
alter :: (Hashable k, Ord k, Ord p) => (Maybe (p, v) -> (b, Maybe (p, v))) -> k -> HashPSQ k p v -> (b, HashPSQ k p v)

-- | <i>O(min(n,W))</i> A variant of <a>alter</a> which works on the
--   element with the minimum priority. Unlike <a>alter</a>, this variant
--   also allows you to change the key of the element.
alterMin :: (Hashable k, Ord k, Ord p) => (Maybe (k, p, v) -> (b, Maybe (k, p, v))) -> HashPSQ k p v -> (b, HashPSQ k p v)

-- | <i>O(n*min(n,W))</i> Build a queue from a list of (key, priority,
--   value) tuples. If the list contains more than one priority and value
--   for the same key, the last priority and value for the key is retained.
fromList :: (Hashable k, Ord k, Ord p) => [(k, p, v)] -> HashPSQ k p v

-- | <i>O(n)</i> Convert a queue to a list of (key, priority, value)
--   tuples. The order of the list is not specified.
toList :: (Hashable k, Ord k, Ord p) => HashPSQ k p v -> [(k, p, v)]

-- | <i>O(n)</i> Obtain the list of present keys in the queue.
keys :: (Hashable k, Ord k, Ord p) => HashPSQ k p v -> [k]

-- | <i>O(min(n,W))</i> Insert a new key, priority and value into the
--   queue. If the key is already present in the queue, then the evicted
--   priority and value can be found the first element of the returned
--   tuple.
insertView :: (Hashable k, Ord k, Ord p) => k -> p -> v -> HashPSQ k p v -> (Maybe (p, v), HashPSQ k p v)

-- | <i>O(min(n,W))</i> Delete a key and its priority and value from the
--   queue. If the key was present, the associated priority and value are
--   returned in addition to the updated queue.
deleteView :: (Hashable k, Ord k, Ord p) => k -> HashPSQ k p v -> Maybe (p, v, HashPSQ k p v)

-- | <i>O(min(n,W))</i> Retrieve the binding with the least priority, and
--   the rest of the queue stripped of that binding.
minView :: (Hashable k, Ord k, Ord p) => HashPSQ k p v -> Maybe (k, p, v, HashPSQ k p v)

-- | <i>O(n)</i> Modify every value in the queue.
map :: (k -> p -> v -> w) -> HashPSQ k p v -> HashPSQ k p w

-- | <i>O(n)</i> Strict fold over every key, priority and value in the
--   queue. The order in which the fold is performed is not specified.
fold' :: (k -> p -> v -> a -> a) -> a -> HashPSQ k p v -> a

-- | <i>O(n^2)</i> Internal function to check if the <a>HashPSQ</a> is
--   valid, i.e. if all invariants hold. This should always be the case.
valid :: (Hashable k, Ord k, Ord p) => HashPSQ k p v -> Bool
