(* Chris Okasaki School of Computer Science Carnegie Mellon University Pittsburgh, PA 15213 cokasaki@cs.cmu.edu *) functor HoodMelvilleQueue () : QUEUE = (* Alternative implementation of queues with O(1) worst-case *) (* performance. Provided for comparison. *) (* *) (* Taken from *) (* Hood and Melville *) (* "Real-time queue operations in pure Lisp" *) (* IPL 13(2) (Nov 1981), 50-53 *) (* *) (* Warning! Does not support insertf! *) struct datatype 'a Queue = Simple of {front : 'a list, rear : 'a list, diff : int} (* diff = length front - length rear *) | Copy1 of (* in process of reversing f and r *) {oldfront : 'a list, rear : 'a list, f : 'a list, r : 'a list, frev : 'a list, rrev : 'a list, (* the partial new front *) diff : int, (* diff = length rrev - length rear *) copy : int} (* copy = # of valid elements in frev *) | Copy2 of (* in process of reversing frev onto newfront *) {oldfront : 'a list, rear : 'a list, frev : 'a list, newfront : 'a list, diff : int, (* diff = length newfront - length rear *) copy : int} (* copy = # of valid elements in frev *) (* begin process of moving elements from rear to front *) fun rotate (front,rear) = (* length rear = length front + 1 *) Copy1 {oldfront = front, rear = [], f = front,r = rear,frev = [],rrev = [], diff = 0,copy = 0} (* do one step in process of moving elements from rear to front *) fun tick (Copy1 {oldfront,rear,f=x::f,r=y::r,frev,rrev,diff,copy}) = Copy1 {oldfront = oldfront,rear = rear, f = f,r = r,frev = x::frev,rrev = y::rrev, diff = diff + 1,copy = copy + 1} | tick (Copy1 {oldfront,rear,f=[],r=[y],frev,rrev,diff,copy}) = Copy2 {oldfront = oldfront,rear = rear, frev = frev,newfront = y::rrev, diff = diff + 1,copy = copy} | tick (Copy2 {oldfront,rear,newfront,diff,copy = 0,frev}) = Simple {front = newfront,rear = rear,diff = diff} | tick (Copy2 {oldfront,rear,newfront,diff,copy = 1,frev = x::_}) = Simple {front = x::newfront,rear = rear,diff = diff + 1} | tick (Copy2 {oldfront,rear,newfront,diff,copy,frev = x::frev}) = Copy2 {oldfront = oldfront,rear = rear, newfront = x::newfront,frev = frev, diff = diff + 1,copy = copy - 1} | tick simpleq = simpleq fun tick2 q = tick (tick q) exception Empty val empty = Simple {front=[],rear=[],diff=0} fun isempty (Simple {front=[],...}) = true | isempty _ = false fun size (Simple {rear,diff,...}) = 2 * length rear + diff | size (Copy1 {rear,diff,copy,f,r,...}) = 2 * length rear + diff + copy + length f + length r | size (Copy2 {rear,diff,copy,...}) = 2 * length rear + diff + copy fun insert (x, Simple {front,rear,diff = 0}) = tick2 (rotate (front,x::rear)) | insert (x, Simple {front,rear,diff}) = Simple {front=front,rear=x::rear,diff=diff-1} | insert (x, Copy1 {oldfront,rear,f,r,frev,rrev,diff,copy}) = tick2 (Copy1 {oldfront=oldfront,rear=x::rear, f=f,r=r,frev=frev,rrev=rrev, diff = diff-1,copy=copy}) | insert (x, Copy2 {oldfront,rear,frev,newfront,diff,copy}) = tick2 (Copy2 {oldfront=oldfront,rear=x::rear, frev=frev,newfront=newfront, diff = diff-1,copy=copy}) fun remove (Simple {front=[],...}) = raise Empty | remove (Simple {front=x::front,rear,diff=0}) = (x,tick2 (rotate (front,rear))) | remove (Simple {front=x::front,rear,diff}) = (x,Simple {front=front,rear=rear,diff=diff-1}) | remove (Copy1 {oldfront=x::oldfront,rear,f,r,frev,rrev,diff,copy})= (x,tick2 (Copy1 {oldfront=oldfront,rear=rear, f=f,r=r,frev=frev,rrev=rrev, diff=diff,copy=copy-1})) | remove (Copy2 {oldfront=x::oldfront,rear,frev,newfront,diff,copy})= (x,tick2 (Copy2 {oldfront=oldfront,rear=rear, frev=frev,newfront=newfront, diff=diff,copy=copy-1})) exception InsertfNotSupported fun insertf (_,_) = raise InsertfNotSupported end