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,_))).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |