140 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			140 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
|   | /*  $Id$ | ||
|  | 
 | ||
|  |     Part of CHR (Constraint Handling Rules) | ||
|  | 
 | ||
|  |     Author:        Tom Schrijvers | ||
|  |     E-mail:        Tom.Schrijvers@cs.kuleuven.be | ||
|  |     WWW:           http://www.swi-prolog.org | ||
|  |     Copyright (C): 2003-2004, K.U. Leuven | ||
|  | 
 | ||
|  |     This program is free software; you can redistribute it and/or | ||
|  |     modify it under the terms of the GNU General Public License | ||
|  |     as published by the Free Software Foundation; either version 2 | ||
|  |     of the License, or (at your option) any later version. | ||
|  | 
 | ||
|  |     This program 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 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA | ||
|  | 
 | ||
|  |     As a special exception, if you link this library with other files, | ||
|  |     compiled with a Free Software compiler, to produce an executable, this | ||
|  |     library does not by itself cause the resulting executable to be covered | ||
|  |     by the GNU General Public License. This exception does not however | ||
|  |     invalidate any other reasons why the executable file might be covered by | ||
|  |     the GNU General Public License. | ||
|  | */ | ||
|  | 
 | ||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
|  | % Binomial Heap imlementation based on | ||
|  | % | ||
|  | %	Functional Binomial Queues | ||
|  | %	James F. King | ||
|  | %	University of Glasgow | ||
|  | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
|  | 
 | ||
|  | :- module(binomialheap, | ||
|  | 	[ | ||
|  | 		empty_q/1, | ||
|  | 		insert_q/3, | ||
|  | 		insert_list_q/3, | ||
|  | 		delete_min_q/3, | ||
|  | 		find_min_q/2 | ||
|  | 	]). | ||
|  | 
 | ||
|  | :- use_module(library(lists),[reverse/2]). | ||
|  | 
 | ||
|  | % data Tree a = Node a [Tree a] | ||
|  | % type BinQueue a = [Maybe (Tree a)] | ||
|  | % data Maybe a = Zero | One a | ||
|  | % type Item = (Entry,Key) | ||
|  | 
 | ||
|  | key(_-Key,Key). | ||
|  | 
 | ||
|  | empty_q([]). | ||
|  | 
 | ||
|  | meld_q(P,Q,R) :- | ||
|  | 	meld_qc(P,Q,zero,R). | ||
|  | 
 | ||
|  | meld_qc([],Q,zero,Q) :- !. | ||
|  | meld_qc([],Q,C,R) :- !, | ||
|  | 	meld_q(Q,[C],R). | ||
|  | meld_qc(P,[],C,R) :- !, | ||
|  | 	meld_qc([],P,C,R). | ||
|  | meld_qc([zero|Ps],[zero|Qs],C,R) :- !, | ||
|  | 	R = [C | Rs], | ||
|  | 	meld_q(Ps,Qs,Rs). | ||
|  | meld_qc([one(node(X,Xs))|Ps],[one(node(Y,Ys))|Qs],C,R) :- !, | ||
|  | 	key(X,KX), | ||
|  | 	key(Y,KY), | ||
|  | 	( KX < KY -> | ||
|  | 		T = node(X,[node(Y,Ys)|Xs]) | ||
|  | 	; | ||
|  | 		T = node(Y,[node(X,Xs)|Ys]) | ||
|  | 	), | ||
|  | 	R = [C|Rs], | ||
|  | 	meld_qc(Ps,Qs,one(T),Rs). | ||
|  | meld_qc([P|Ps],[Q|Qs],C,Rs) :- | ||
|  | 	meld_qc([Q|Ps],[C|Qs],P,Rs). | ||
|  | 
 | ||
|  | insert_q(Q,I,NQ) :- | ||
|  | 	meld_q([one(node(I,[]))],Q,NQ). | ||
|  | 
 | ||
|  | insert_list_q([],Q,Q). | ||
|  | insert_list_q([I|Is],Q,NQ) :- | ||
|  | 	insert_q(Q,I,Q1), | ||
|  | 	insert_list_q(Is,Q1,NQ). | ||
|  | 
 | ||
|  | min_tree([T|Ts],MT) :- | ||
|  | 	min_tree_acc(Ts,T,MT). | ||
|  | 
 | ||
|  | min_tree_acc([],MT,MT). | ||
|  | min_tree_acc([T|Ts],Acc,MT) :- | ||
|  | 	least(T,Acc,NAcc), | ||
|  | 	min_tree_acc(Ts,NAcc,MT). | ||
|  | 
 | ||
|  | least(zero,T,T) :- !. | ||
|  | least(T,zero,T) :- !. | ||
|  | least(one(node(X,Xs)),one(node(Y,Ys)),T) :- | ||
|  | 	key(X,KX), | ||
|  | 	key(Y,KY), | ||
|  | 	( KX < KY -> | ||
|  | 		T = one(node(X,Xs)) | ||
|  | 	; | ||
|  | 		T = one(node(Y,Ys)) | ||
|  | 	). | ||
|  | 
 | ||
|  | remove_tree([],_,[]). | ||
|  | remove_tree([T|Ts],I,[NT|NTs]) :- | ||
|  | 	( T == zero -> | ||
|  | 		NT = T | ||
|  | 	; | ||
|  | 		T = one(node(X,_)), | ||
|  | 		( X == I -> | ||
|  | 			NT = zero | ||
|  | 		; | ||
|  | 			NT = T | ||
|  | 		) | ||
|  | 	), | ||
|  | 	remove_tree(Ts,I,NTs). | ||
|  | 
 | ||
|  | delete_min_q(Q,NQ,Min) :- | ||
|  | 	min_tree(Q,one(node(Min,Ts))), | ||
|  | 	remove_tree(Q,Min,Q1), | ||
|  | 	reverse(Ts,RTs), | ||
|  | 	make_ones(RTs,Q2), | ||
|  | 	meld_q(Q2,Q1,NQ). | ||
|  | 
 | ||
|  | make_ones([],[]). | ||
|  | make_ones([N|Ns],[one(N)|RQ]) :- | ||
|  | 	make_ones(Ns,RQ). | ||
|  | 
 | ||
|  | find_min_q(Q,I) :- | ||
|  | 	min_tree(Q,one(node(I,_))). | ||
|  | 
 | ||
|  | 
 |