(*
 * Heap -- binomial heaps
 * Copyright (C) 2011  Batteries Included Development Team
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version,
 * with the special exception on linking described in file LICENSE.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *)

(** Functional heaps over ordered types

    Ascribes to:

    [BatEnum.Enumerable with type 'a enumerable = 'a t]
*)

type +'a t
  (** Heap of elements that are compared with [Pervasives.compare]. *)

val size : 'a t -> int
  (** Number of elements in the heap. O(1) *)

(** {6 Construction} *)

val empty : 'a t
  (** The empty heap. *)

val insert : 'a t -> 'a -> 'a t
  (** Insert an element into the heap. Duplicates are kept. O(log m) *)

val add : 'a -> 'a t -> 'a t
  (** [add x h] is the same as [insert h x]. This function is intended
      to be used with [fold_right]. *)

(** {6 Operations} *)

val merge : 'a t -> 'a t -> 'a t
  (** Merge two heaps. O(log m) *)

val find_min : 'a t -> 'a
  (** Find the minimal element of the heap. O(1) *)

val del_min : 'a t -> 'a t
  (** Delete the minimal element of the heap. O(log n) *)

(** {6 Transformation} *)

val of_list : 'a list -> 'a t
  (** Build a heap from a given list. O(n log n) *)

val to_list : 'a t -> 'a list
  (** Enumerate the elements of the heap. O(n log n) *)

val elems : 'a t -> 'a list
  (** @deprecated Same as [to_list]. *)

val of_enum : 'a BatEnum.t -> 'a t
  (** Build a heap from an enumeration. Consumes the enumeration.
      O(n log n) *)

val enum : 'a t -> 'a BatEnum.t
  (** Enumerate the elements of the heap in heap order. O(log n) per
      {!BatEnum.get}. *)

(** {6 Printing} *)

val print :  ?first:string -> ?last:string -> ?sep:string
  -> ('a BatInnerIO.output -> 'b -> unit)
  -> 'a BatInnerIO.output -> 'b t -> unit
  (** Print the contents of the heap in heap order. O(n log n) *)

val t_printer : 'a BatValue_printer.t -> 'a t BatValue_printer.t
  (** See {!BatValue_printer}. *)

(** {6 Functorized version} *)

(** The result of {!Make} *)
module type H =
sig
  type elem
    (** Type of elements of the heap *)
  type t
    (** Type of the heap *)
  val empty     : t
    (** See {!BatHeap.empty}. *)
  val size      : t -> int
    (** See {!BatHeap.size}. *)
  val insert    : t -> elem -> t
    (** See {!BatHeap.add}. *)
  val add       : elem -> t -> t
    (** See {!BatHeap.insert}. *)
  val merge     : t -> t -> t
    (** See {!BatHeap.merge}. *)
  val find_min  : t -> elem
    (** See {!BatHeap.find_min}. *)
  val del_min   : t -> t
    (** See {!BatHeap.del_min}. *)
  val of_list   : elem list -> t
    (** See {!BatHeap.of_list}. *)
  val to_list   : t -> elem list
    (** See {!BatHeap.to_list}. *)
  val elems     : t -> elem list
    (** @deprecated Same as [to_list]. *)
  val of_enum   : elem BatEnum.t -> t
    (** See {!BatHeap.of_enum}. *)
  val enum      : t -> elem BatEnum.t
    (** See {!BatHeap.enum}. *)
  val print     :  ?first:string -> ?last:string -> ?sep:string
    -> ('a BatInnerIO.output -> elem -> unit)
    -> 'a BatInnerIO.output -> t -> unit
    (** See {!BatHeap.print}. *)
  val t_printer : elem BatValue_printer.t -> t BatValue_printer.t
    (** See {!BatHeap.t_printer}. *)
end

module Make (Ord : BatInterfaces.OrderedType) : H with type elem = Ord.t
  (** Functorized heaps over arbitrary orderings. All the functions have
      the same complexity as the non-functorized versions. *)
