123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133moduletypePARTIAL_ORD=sigtypetvalleq:t->t->bool(** [leq x y] shall return [true] iff [x] is lower or equal to [y]. *)endmoduletypeS=sigtypeelttypetvalempty:t(** [empty] returns the empty heap. *)valis_empty:t->bool(** [is_empty h] returns [true] if the heap [h] is empty. *)exceptionEmptyvalmerge:t->t->t(** [merge h1 h2] merges the two heaps [h1] and [h2]. *)valinsert:elt->t->t(** [insert x h] inserts an element [x] into the heap [h]. *)valfind_min:t->eltoption(** [find_min h] find the minimal element of the heap [h]. *)valfind_min_exn:t->elt(** [find_min_exn h] is like {!find_min} but can fail.
@raise Empty if the heap is empty. *)valtake:t->(t*elt)option(** [take h] extracts and returns the minimum element, and the new heap (without
this element), or [None] if the heap [h] is empty. *)valtake_exn:t->t*elt(** [take_exn h] is like {!take}, but can fail.
@raise Empty if the heap is empty. *)valdelete_one:(elt->elt->bool)->elt->t->t(** [delete_one eq x h] uses [eq] to find one occurrence of a value [x]
if it exist in the heap [h], and delete it.
If [h] do not contain [x] then it return [h]. *)valsize:t->intendmoduleMake(E:PARTIAL_ORD):Swithtypeelt=E.t=structtypeelt=E.ttypet=|E|Nofint*elt*t*tletempty=Eletis_empty=function|E->true|N_->falseexceptionEmpty(* Rank of the tree *)let_rank=function|E->0|N(r,_,_,_)->r(* Make a balanced node labelled with [x], and subtrees [a] and [b].
We ensure that the right child's rank is ≤ to the rank of the
left child (leftist property). The rank of the resulting node
is the length of the rightmost path. *)let_make_nodexab=if_ranka>=_rankbthenN(_rankb+1,x,a,b)elseN(_ranka+1,x,b,a)letrecmerget1t2=matcht1,t2with|t,E->t|E,t->t|N(_,x,a1,b1),N(_,y,a2,b2)->ifE.leqxythen_make_nodexa1(mergeb1t2)else_make_nodeya2(merget1b2)letinsertxh=merge(N(1,x,E,E))hletfind_min_exn=function|E->raiseEmpty|N(_,x,_,_)->xletfind_min=function|E->None|N(_,x,_,_)->Somexlettake=function|E->None|N(_,x,l,r)->Some(mergelr,x)lettake_exn=function|E->raiseEmpty|N(_,x,l,r)->mergelr,xletdelete_oneeqxh=letrecaux=function|E->false,E|N(_,y,l,r)ash->ifeqxythentrue,mergelrelseifE.leqyxthen(letfound_left,l1=auxlinletfound,r1=iffound_leftthentrue,relseauxriniffoundthentrue,_make_nodeyl1r1elsefalse,h)elsefalse,hinsnd(auxh)letrecsize=function|E->0|N(_,_,l,r)->1+sizel+sizerend