caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Norman Ramsey <nr@cs.tufts.edu>
To: caml-list@inria.fr
Subject: Re: [Caml-list] Priority queues, reloaded
Date: Fri, 01 Jul 2011 21:49:22 -0400	[thread overview]
Message-ID: <20110702014925.DFB9D601DAF4C@labrador.cs.tufts.edu> (raw)
In-Reply-To: <4E0CAEC3.7010804@gmail.com> (sfid-j-20110630-131704-+2.76-1@multi.osbf.lua)

[-- Attachment #1: Type: text/plain, Size: 435 bytes --]

 > Since the previous discussion regarding priority queues pretty much
 > concluded that they weren't available in OCaml, could you point to the most
 > compact implementation that you know of? 

Attached find a transliteration of some Standard ML code I wrote last
summer.  The SML was tested; the transliteration is not.  But it does
compile, and I've put it under CC BY license: attribution required,
all uses permitted.


Norman



[-- Attachment #2: leftistheap.ml --]
[-- Type: text/plain, Size: 2603 bytes --]

(* Leftist heap (priority queue) by Norman Ramsey *)
(* Copyright 2011, licensed Creative Commons Attribution (BY),
   i.e., attribution required, but all uses permitted 
*)

module type PQUEUE = sig
  type t
  type elem
  val empty  : t
  val insert : elem * t -> t
  val is_empty : t -> bool
  exception Empty
  val deletemin : t -> elem * t  (* raises Empty *)
  val ok : t -> bool (* satisfies invariant *)

  val merges : int ref
end


module MkTreePQ (Elem : sig
                           type t
                           val compare : t * t -> int
                         end) :
  PQUEUE with type elem = Elem.t
=
struct
  type elem = Elem.t
  type height = int
  type t = EMPTY
         | NODE of elem * height * t * t
    (* invariant:
         elem in a node is not greater than the elems in its nonempty children
         left child is at least as high as right child
         height represents true height
     *)

  let le (x1, x2) = Elem.compare (x1, x2) <= 0

  let rec height = function
    | EMPTY -> 0
    | (NODE (_, h, _, _)) -> h

  let merges = ref 0

  let rec merge = function
    | (EMPTY, q) -> q
    | (q, EMPTY) -> q
    | ((NODE (x1, _, l1, r1) as q1), (NODE (x2, _, _, _) as q2)) ->
        if le (x1, x2) then
                let (to_merge, to_stand) =
                  if height l1 > height q2 then (q2, l1) else (l1, q2) in
                let newq1 = merge (r1, to_merge) in
                let newq2 = to_stand in
                let h1 = height newq1 in
                let h2 = height newq2 in
                let h = max h1 h2 + 1 in
                let (l, r) = if h1 > h2 then (newq1, newq2) else (newq2, newq1) in
                let _ = merges := !merges + 1 in
                NODE (x1, h, l, r)
        else
            merge (q2, q1)
            
  let empty = EMPTY
  let rec insert = function
    | (x, EMPTY) -> NODE (x, 1, EMPTY, EMPTY)
    | (x, q) -> merge (insert(x, empty), q)

  let is_empty = function
    | EMPTY -> true
    | (NODE _) -> false

  exception Empty
  let deletemin = function
    | EMPTY -> raise Empty
    | (NODE (x, _, q, q')) -> (x, merge (q, q'))


  let rec ok_h_le h x q =
       (* q satisfies invariant, has height h, each elem at least x *)
    match q with
    | EMPTY -> h = 0
    | NODE (x', h', l, r) ->
                 h = h' && le(x, x') &&
                 (h = height l + 1 || h = height r + 1) &&
                 h > height l && h > height r &&
                 ok_h_le (height l) x' l && ok_h_le (height r) x' r

  let ok = function
    | EMPTY -> true
    | (NODE (x, h, _, _) as q) -> ok_h_le h x q

end

  parent reply	other threads:[~2011-07-02  1:49 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <sfid-j-20110630-131704-+2.76-1@multi.osbf.lua>
2011-06-30 17:13 ` Andrew
2011-06-30 17:26   ` Gabriel Scherer
2011-06-30 18:14     ` Jean-Christophe Filliâtre
2011-06-30 18:36     ` Jean-Christophe Filliâtre
2011-07-09  9:02       ` Jon Harrop
2011-07-09 19:22         ` Jean-Christophe Filliâtre
2011-07-10 18:04           ` Jon Harrop
2011-06-30 19:13     ` Andrew
2011-06-30 22:17     ` Wojciech Meyer
2011-07-02  1:49   ` Norman Ramsey [this message]
2011-07-09  9:05   ` Jon Harrop
     [not found] <848371343.3424870.1309454037170.JavaMail.root@zmbs3.inria.fr>
2011-06-30 18:03 ` Daniel de Rauglaudre
     [not found] <fa.V8myB/rA6OKILQg+GW40f8c1BGo@ifi.uio.no>
2011-07-02 12:24 ` Radu Grigore
2011-07-02 19:05   ` Andrew
2011-07-02 22:42   ` Radu Grigore
2011-07-10 17:55     ` Jon Harrop
2011-07-09 18:45 james woodyatt
     [not found] ` <14B0DF03-EF83-4568-AB34-6B51BCE4B574@recoil.org>
2011-07-09 18:56   ` james woodyatt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110702014925.DFB9D601DAF4C@labrador.cs.tufts.edu \
    --to=nr@cs.tufts.edu \
    --cc=caml-list@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).