123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)(*s Heaps *)moduletypeOrdered=sigtypetvalcompare:t->t->intendmoduletypeS=sig(* Type of functional heaps *)typet(* Type of elements *)typeelt(* The empty heap *)valempty:t(* [add x h] returns a new heap containing the elements of [h], plus [x];
complexity $O(log(n))$ *)valadd:elt->t->t(* [maximum h] returns the maximum element of [h]; raises [EmptyHeap]
when [h] is empty; complexity $O(1)$ *)valmaximum:t->elt(* [remove h] returns a new heap containing the elements of [h], except
the maximum of [h]; raises [EmptyHeap] when [h] is empty;
complexity $O(log(n))$ *)valremove:t->t(* usual iterators and combinators; elements are presented in
arbitrary order *)valiter:(elt->unit)->t->unitvalfold:(elt->'a->'a)->t->'a->'aendexceptionEmptyHeap(*s Functional implementation *)moduleFunctional(X:Ordered)=struct(* Heaps are encoded as Braun trees, that are binary trees
where size r <= size l <= size r + 1 for each node Node (l, x, r) *)typet=|Leaf|Nodeoft*X.t*ttypeelt=X.tletempty=Leafletrecaddx=function|Leaf->Node(Leaf,x,Leaf)|Node(l,y,r)->ifX.comparexy>=0thenNode(addyr,x,l)elseNode(addxr,y,l)letrecextract=function|Leaf->assertfalse|Node(Leaf,y,r)->assert(r=Leaf);y,Leaf|Node(l,y,r)->letx,l=extractlinx,Node(r,y,l)letis_abovex=function|Leaf->true|Node(_,y,_)->X.comparexy>=0letrecreplace_minx=function|Node(l,_,r)whenis_abovexl&&is_abovexr->Node(l,x,r)|Node((Node(_,lx,_)asl),_,r)whenis_abovelxr->(* lx <= x, rx necessarily *)Node(replace_minxl,lx,r)|Node(l,_,(Node(_,rx,_)asr))->(* rx <= x, lx necessarily *)Node(l,rx,replace_minxr)|Leaf|Node(Leaf,_,_)|Node(_,_,Leaf)->assertfalse(* merges two Braun trees [l] and [r],
with the assumption that [size r <= size l <= size r + 1] *)letrecmergelr=matchl,rwith|_,Leaf->l|Node(ll,lx,lr),Node(_,ly,_)->ifX.comparelxly>=0thenNode(r,lx,mergelllr)elseletx,l=extractlinNode(replace_minxr,ly,l)|Leaf,_->assertfalse(* contradicts the assumption *)letmaximum=function|Leaf->raiseEmptyHeap|Node(_,x,_)->xletremove=function|Leaf->raiseEmptyHeap|Node(l,_,r)->mergelrletreciterf=function|Leaf->()|Node(l,x,r)->iterfl;fx;iterfrletrecfoldfhx0=matchhwith|Leaf->x0|Node(l,x,r)->foldfl(foldfr(fxx0))end