426 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Perl
		
	
	
	
	
	
		
		
			
		
	
	
			426 lines
		
	
	
		
			9.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.
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								% author: Tom Schrijvers
							 | 
						||
| 
								 | 
							
								% email:  Tom.Schrijvers@cs.kuleuven.be
							 | 
						||
| 
								 | 
							
								% copyright: K.U.Leuven, 2004
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%% @addtogroup CHR_in_YAP_Programs
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								% CHR error handling
							 | 
						||
| 
								 | 
							
								%
							 | 
						||
| 
								 | 
							
								:- module(chr_hashtable_store,
							 | 
						||
| 
								 | 
							
									[ new_ht/1,
							 | 
						||
| 
								 | 
							
									  lookup_ht/3,
							 | 
						||
| 
								 | 
							
									  lookup_ht1/4,
							 | 
						||
| 
								 | 
							
									  lookup_ht2/4,
							 | 
						||
| 
								 | 
							
									  insert_ht/3,
							 | 
						||
| 
								 | 
							
									  insert_ht1/4,
							 | 
						||
| 
								 | 
							
									  insert_ht/4,
							 | 
						||
| 
								 | 
							
									  delete_ht/3,
							 | 
						||
| 
								 | 
							
									  delete_ht1/4,
							 | 
						||
| 
								 | 
							
									  delete_first_ht/3,
							 | 
						||
| 
								 | 
							
									  value_ht/2,
							 | 
						||
| 
								 | 
							
									  stats_ht/1,
							 | 
						||
| 
								 | 
							
									  stats_ht/1
							 | 
						||
| 
								 | 
							
									]).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- use_module(pairlist).
							 | 
						||
| 
								 | 
							
								:- use_module(library(dialect/hprolog)).
							 | 
						||
| 
								 | 
							
								:- use_module(library(lists)).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								:- multifile user:goal_expansion/2.
							 | 
						||
| 
								 | 
							
								:- dynamic user:goal_expansion/2.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								initial_capacity(89).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								new_ht(HT) :-
							 | 
						||
| 
								 | 
							
									initial_capacity(Capacity),
							 | 
						||
| 
								 | 
							
									new_ht(Capacity,HT).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								new_ht(Capacity,HT) :-
							 | 
						||
| 
								 | 
							
									functor(T1,t,Capacity),
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity,0,Table),
							 | 
						||
| 
								 | 
							
									Table = T1.
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								lookup_ht(HT,Key,Values) :-
							 | 
						||
| 
								 | 
							
									term_hash(Key,Hash),
							 | 
						||
| 
								 | 
							
									lookup_ht1(HT,Hash,Key,Values).
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity,_,Table),
							 | 
						||
| 
								 | 
							
									Index is (Hash mod Capacity) + 1,
							 | 
						||
| 
								 | 
							
									arg(Index,Table,Bucket),
							 | 
						||
| 
								 | 
							
									nonvar(Bucket),
							 | 
						||
| 
								 | 
							
									( Bucket = K-Vs ->
							 | 
						||
| 
								 | 
							
									    K == Key,
							 | 
						||
| 
								 | 
							
									    Values = Vs
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
									    lookup(Bucket,Key,Values)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								% :- load_foreign_library(chr_support).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								lookup_ht1(HT,Hash,Key,Values) :-
							 | 
						||
| 
								 | 
							
									( lookup_ht1_(HT,Hash,Key,Values) ->
							 | 
						||
| 
								 | 
							
										true
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										( lookup_ht1__(HT,Hash,Key,Values) ->
							 | 
						||
| 
								 | 
							
											writeln(lookup_ht1(HT,Hash,Key,Values)),
							 | 
						||
| 
								 | 
							
											throw(error)
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											fail
							 | 
						||
| 
								 | 
							
										)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								*/
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								lookup_ht1(HT,Hash,Key,Values) :-
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity,_,Table),
							 | 
						||
| 
								 | 
							
									Index is (Hash mod Capacity) + 1,
							 | 
						||
| 
								 | 
							
									arg(Index,Table,Bucket),
							 | 
						||
| 
								 | 
							
									nonvar(Bucket),
							 | 
						||
| 
								 | 
							
									( Bucket = K-Vs ->
							 | 
						||
| 
								 | 
							
									    K == Key,
							 | 
						||
| 
								 | 
							
									    Values = Vs
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
									    lookup(Bucket,Key,Values)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								lookup_ht2(HT,Key,Values,Index) :-
							 | 
						||
| 
								 | 
							
									term_hash(Key,Hash),
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity,_,Table),
							 | 
						||
| 
								 | 
							
									Index is (Hash mod Capacity) + 1,
							 | 
						||
| 
								 | 
							
									arg(Index,Table,Bucket),
							 | 
						||
| 
								 | 
							
									nonvar(Bucket),
							 | 
						||
| 
								 | 
							
									( Bucket = K-Vs ->
							 | 
						||
| 
								 | 
							
									    K == Key,
							 | 
						||
| 
								 | 
							
									    Values = Vs
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
									    lookup(Bucket,Key,Values)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								lookup_pair_eq([P | KVs],Key,Pair) :-
							 | 
						||
| 
								 | 
							
									P = K-_,
							 | 
						||
| 
								 | 
							
									( K == Key ->
							 | 
						||
| 
								 | 
							
										P = Pair
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										lookup_pair_eq(KVs,Key,Pair)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								insert_ht(HT,Key,Value) :-
							 | 
						||
| 
								 | 
							
									term_hash(Key,Hash),
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity0,Load,Table0),
							 | 
						||
| 
								 | 
							
									LookupIndex is (Hash mod Capacity0) + 1,
							 | 
						||
| 
								 | 
							
									arg(LookupIndex,Table0,LookupBucket),
							 | 
						||
| 
								 | 
							
									( var(LookupBucket) ->
							 | 
						||
| 
								 | 
							
										LookupBucket = Key - [Value]
							 | 
						||
| 
								 | 
							
									; LookupBucket = K-Values ->
							 | 
						||
| 
								 | 
							
										( K == Key ->
							 | 
						||
| 
								 | 
							
											setarg(2,LookupBucket,[Value|Values])
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											setarg(LookupIndex,Table0,[Key-[Value],LookupBucket])
							 | 
						||
| 
								 | 
							
										)
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										( lookup_pair_eq(LookupBucket,Key,Pair) ->
							 | 
						||
| 
								 | 
							
											Pair = _-Values,
							 | 
						||
| 
								 | 
							
											setarg(2,Pair,[Value|Values])
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											setarg(LookupIndex,Table0,[Key-[Value]|LookupBucket])
							 | 
						||
| 
								 | 
							
										)
							 | 
						||
| 
								 | 
							
									),
							 | 
						||
| 
								 | 
							
									NLoad is Load + 1,
							 | 
						||
| 
								 | 
							
									setarg(2,HT,NLoad),
							 | 
						||
| 
								 | 
							
									( Load == Capacity0 ->
							 | 
						||
| 
								 | 
							
										expand_ht(HT,_Capacity)
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										true
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								insert_ht1(HT,Key,Hash,Value) :-
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity0,Load,Table0),
							 | 
						||
| 
								 | 
							
									LookupIndex is (Hash mod Capacity0) + 1,
							 | 
						||
| 
								 | 
							
									arg(LookupIndex,Table0,LookupBucket),
							 | 
						||
| 
								 | 
							
									( var(LookupBucket) ->
							 | 
						||
| 
								 | 
							
										LookupBucket = Key - [Value]
							 | 
						||
| 
								 | 
							
									; LookupBucket = K-Values ->
							 | 
						||
| 
								 | 
							
										( K == Key ->
							 | 
						||
| 
								 | 
							
											setarg(2,LookupBucket,[Value|Values])
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											setarg(LookupIndex,Table0,[Key-[Value],LookupBucket])
							 | 
						||
| 
								 | 
							
										)
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										( lookup_pair_eq(LookupBucket,Key,Pair) ->
							 | 
						||
| 
								 | 
							
											Pair = _-Values,
							 | 
						||
| 
								 | 
							
											setarg(2,Pair,[Value|Values])
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											setarg(LookupIndex,Table0,[Key-[Value]|LookupBucket])
							 | 
						||
| 
								 | 
							
										)
							 | 
						||
| 
								 | 
							
									),
							 | 
						||
| 
								 | 
							
									NLoad is Load + 1,
							 | 
						||
| 
								 | 
							
									setarg(2,HT,NLoad),
							 | 
						||
| 
								 | 
							
									( Load == Capacity0 ->
							 | 
						||
| 
								 | 
							
										expand_ht(HT,_Capacity)
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										true
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								% LDK: insert version with extra argument denoting result
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								insert_ht(HT,Key,Value,Result) :-
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity,Load,Table),
							 | 
						||
| 
								 | 
							
									term_hash(Key,Hash),
							 | 
						||
| 
								 | 
							
									LookupIndex is (Hash mod Capacity) + 1,
							 | 
						||
| 
								 | 
							
									arg(LookupIndex,Table,LookupBucket),
							 | 
						||
| 
								 | 
							
									(   var(LookupBucket)
							 | 
						||
| 
								 | 
							
									->  Result = [Value],
							 | 
						||
| 
								 | 
							
									    LookupBucket = Key - Result,
							 | 
						||
| 
								 | 
							
									    NewLoad is Load + 1
							 | 
						||
| 
								 | 
							
									;   LookupBucket = K - V
							 | 
						||
| 
								 | 
							
									->  (   K = Key
							 | 
						||
| 
								 | 
							
									    ->  Result = [Value|V],
							 | 
						||
| 
								 | 
							
										setarg(2,LookupBucket,Result),
							 | 
						||
| 
								 | 
							
										NewLoad = Load
							 | 
						||
| 
								 | 
							
									    ;   Result = [Value],
							 | 
						||
| 
								 | 
							
										setarg(LookupIndex,Table,[Key - Result,LookupBucket]),
							 | 
						||
| 
								 | 
							
										NewLoad is Load + 1
							 | 
						||
| 
								 | 
							
									    )
							 | 
						||
| 
								 | 
							
									;   (   lookup_pair_eq(LookupBucket,Key,Pair)
							 | 
						||
| 
								 | 
							
									    ->  Pair = _-Values,
							 | 
						||
| 
								 | 
							
										Result = [Value|Values],
							 | 
						||
| 
								 | 
							
										setarg(2,Pair,Result),
							 | 
						||
| 
								 | 
							
										NewLoad = Load
							 | 
						||
| 
								 | 
							
									    ;   Result = [Value],
							 | 
						||
| 
								 | 
							
										setarg(LookupIndex,Table,[Key - Result|LookupBucket]),
							 | 
						||
| 
								 | 
							
										NewLoad is Load + 1
							 | 
						||
| 
								 | 
							
									    )
							 | 
						||
| 
								 | 
							
									),
							 | 
						||
| 
								 | 
							
									setarg(2,HT,NewLoad),
							 | 
						||
| 
								 | 
							
									(   NewLoad > Capacity
							 | 
						||
| 
								 | 
							
									->  expand_ht(HT,_)
							 | 
						||
| 
								 | 
							
									;   true
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								% LDK: deletion of the first element of a bucket
							 | 
						||
| 
								 | 
							
								delete_first_ht(HT,Key,Values) :-
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity,Load,Table),
							 | 
						||
| 
								 | 
							
									term_hash(Key,Hash),
							 | 
						||
| 
								 | 
							
									Index is (Hash mod Capacity) + 1,
							 | 
						||
| 
								 | 
							
									arg(Index,Table,Bucket),
							 | 
						||
| 
								 | 
							
									(   Bucket = _-[_|Values]
							 | 
						||
| 
								 | 
							
									->  (   Values = []
							 | 
						||
| 
								 | 
							
									    ->  setarg(Index,Table,_),
							 | 
						||
| 
								 | 
							
										NewLoad is Load - 1
							 | 
						||
| 
								 | 
							
									    ;   setarg(2,Bucket,Values),
							 | 
						||
| 
								 | 
							
										NewLoad = Load
							 | 
						||
| 
								 | 
							
									    )
							 | 
						||
| 
								 | 
							
									;   lookup_pair_eq(Bucket,Key,Pair)
							 | 
						||
| 
								 | 
							
									->  Pair = _-[_|Values],
							 | 
						||
| 
								 | 
							
									    (   Values = []
							 | 
						||
| 
								 | 
							
									    ->  pairlist_delete_eq(Bucket,Key,NewBucket),
							 | 
						||
| 
								 | 
							
										(   NewBucket = []
							 | 
						||
| 
								 | 
							
										->  setarg(Index,Table,_)
							 | 
						||
| 
								 | 
							
										;   NewBucket = [OtherPair]
							 | 
						||
| 
								 | 
							
										->  setarg(Index,Table,OtherPair)
							 | 
						||
| 
								 | 
							
										;   setarg(Index,Table,NewBucket)
							 | 
						||
| 
								 | 
							
										),
							 | 
						||
| 
								 | 
							
										NewLoad is Load - 1
							 | 
						||
| 
								 | 
							
									    ;   setarg(2,Pair,Values),
							 | 
						||
| 
								 | 
							
										NewLoad = Load
							 | 
						||
| 
								 | 
							
									    )
							 | 
						||
| 
								 | 
							
									),
							 | 
						||
| 
								 | 
							
									setarg(2,HT,NewLoad).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								delete_ht(HT,Key,Value) :-
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity,Load,Table),
							 | 
						||
| 
								 | 
							
									NLoad is Load - 1,
							 | 
						||
| 
								 | 
							
									term_hash(Key,Hash),
							 | 
						||
| 
								 | 
							
									Index is (Hash mod Capacity) + 1,
							 | 
						||
| 
								 | 
							
									arg(Index,Table,Bucket),
							 | 
						||
| 
								 | 
							
									( /* var(Bucket) ->
							 | 
						||
| 
								 | 
							
										true
							 | 
						||
| 
								 | 
							
									; */ Bucket = _K-Vs ->
							 | 
						||
| 
								 | 
							
										( /* _K == Key, */
							 | 
						||
| 
								 | 
							
										  delete_first_fail(Vs,Value,NVs) ->
							 | 
						||
| 
								 | 
							
											setarg(2,HT,NLoad),
							 | 
						||
| 
								 | 
							
											( NVs == [] ->
							 | 
						||
| 
								 | 
							
												setarg(Index,Table,_)
							 | 
						||
| 
								 | 
							
											;
							 | 
						||
| 
								 | 
							
												setarg(2,Bucket,NVs)
							 | 
						||
| 
								 | 
							
											)
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											true
							 | 
						||
| 
								 | 
							
										)
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										( lookup_pair_eq(Bucket,Key,Pair),
							 | 
						||
| 
								 | 
							
										  Pair = _-Vs,
							 | 
						||
| 
								 | 
							
										  delete_first_fail(Vs,Value,NVs) ->
							 | 
						||
| 
								 | 
							
											setarg(2,HT,NLoad),
							 | 
						||
| 
								 | 
							
											( NVs == [] ->
							 | 
						||
| 
								 | 
							
												pairlist_delete_eq(Bucket,Key,NBucket),
							 | 
						||
| 
								 | 
							
												( NBucket = [Singleton] ->
							 | 
						||
| 
								 | 
							
													setarg(Index,Table,Singleton)
							 | 
						||
| 
								 | 
							
												;
							 | 
						||
| 
								 | 
							
													setarg(Index,Table,NBucket)
							 | 
						||
| 
								 | 
							
												)
							 | 
						||
| 
								 | 
							
											;
							 | 
						||
| 
								 | 
							
												setarg(2,Pair,NVs)
							 | 
						||
| 
								 | 
							
											)
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											true
							 | 
						||
| 
								 | 
							
										)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								delete_first_fail([X | Xs], Y, Zs) :-
							 | 
						||
| 
								 | 
							
									( X == Y ->
							 | 
						||
| 
								 | 
							
										Zs = Xs
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										Zs = [X | Zs1],
							 | 
						||
| 
								 | 
							
										delete_first_fail(Xs, Y, Zs1)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								delete_ht1(HT,Key,Value,Index) :-
							 | 
						||
| 
								 | 
							
									HT = ht(_Capacity,Load,Table),
							 | 
						||
| 
								 | 
							
									NLoad is Load - 1,
							 | 
						||
| 
								 | 
							
									% term_hash(Key,Hash),
							 | 
						||
| 
								 | 
							
									% Index is (Hash mod _Capacity) + 1,
							 | 
						||
| 
								 | 
							
									arg(Index,Table,Bucket),
							 | 
						||
| 
								 | 
							
									( /* var(Bucket) ->
							 | 
						||
| 
								 | 
							
										true
							 | 
						||
| 
								 | 
							
									; */ Bucket = _K-Vs ->
							 | 
						||
| 
								 | 
							
										( /* _K == Key, */
							 | 
						||
| 
								 | 
							
										  delete_first_fail(Vs,Value,NVs) ->
							 | 
						||
| 
								 | 
							
											setarg(2,HT,NLoad),
							 | 
						||
| 
								 | 
							
											( NVs == [] ->
							 | 
						||
| 
								 | 
							
												setarg(Index,Table,_)
							 | 
						||
| 
								 | 
							
											;
							 | 
						||
| 
								 | 
							
												setarg(2,Bucket,NVs)
							 | 
						||
| 
								 | 
							
											)
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											true
							 | 
						||
| 
								 | 
							
										)
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										( lookup_pair_eq(Bucket,Key,Pair),
							 | 
						||
| 
								 | 
							
										  Pair = _-Vs,
							 | 
						||
| 
								 | 
							
										  delete_first_fail(Vs,Value,NVs) ->
							 | 
						||
| 
								 | 
							
											setarg(2,HT,NLoad),
							 | 
						||
| 
								 | 
							
											( NVs == [] ->
							 | 
						||
| 
								 | 
							
												pairlist_delete_eq(Bucket,Key,NBucket),
							 | 
						||
| 
								 | 
							
												( NBucket = [Singleton] ->
							 | 
						||
| 
								 | 
							
													setarg(Index,Table,Singleton)
							 | 
						||
| 
								 | 
							
												;
							 | 
						||
| 
								 | 
							
													setarg(Index,Table,NBucket)
							 | 
						||
| 
								 | 
							
												)
							 | 
						||
| 
								 | 
							
											;
							 | 
						||
| 
								 | 
							
												setarg(2,Pair,NVs)
							 | 
						||
| 
								 | 
							
											)
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											true
							 | 
						||
| 
								 | 
							
										)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
							 | 
						||
| 
								 | 
							
								value_ht(HT,Value) :-
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity,_,Table),
							 | 
						||
| 
								 | 
							
									value_ht(1,Capacity,Table,Value).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								value_ht(I,N,Table,Value) :-
							 | 
						||
| 
								 | 
							
									I =< N,
							 | 
						||
| 
								 | 
							
									arg(I,Table,Bucket),
							 | 
						||
| 
								 | 
							
									(
							 | 
						||
| 
								 | 
							
										nonvar(Bucket),
							 | 
						||
| 
								 | 
							
										( Bucket = _-Vs ->
							 | 
						||
| 
								 | 
							
											true
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											member(_-Vs,Bucket)
							 | 
						||
| 
								 | 
							
										),
							 | 
						||
| 
								 | 
							
										member(Value,Vs)
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										J is I + 1,
							 | 
						||
| 
								 | 
							
										value_ht(J,N,Table,Value)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								expand_ht(HT,NewCapacity) :-
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity,_,Table),
							 | 
						||
| 
								 | 
							
									NewCapacity is Capacity * 2 + 1,
							 | 
						||
| 
								 | 
							
									functor(NewTable,t,NewCapacity),
							 | 
						||
| 
								 | 
							
									setarg(1,HT,NewCapacity),
							 | 
						||
| 
								 | 
							
									setarg(3,HT,NewTable),
							 | 
						||
| 
								 | 
							
									expand_copy(Table,1,Capacity,NewTable,NewCapacity).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								expand_copy(Table,I,N,NewTable,NewCapacity) :-
							 | 
						||
| 
								 | 
							
									( I > N ->
							 | 
						||
| 
								 | 
							
										true
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										arg(I,Table,Bucket),
							 | 
						||
| 
								 | 
							
										( var(Bucket) ->
							 | 
						||
| 
								 | 
							
											true
							 | 
						||
| 
								 | 
							
										; Bucket = Key - Value ->
							 | 
						||
| 
								 | 
							
											expand_insert(NewTable,NewCapacity,Key,Value)
							 | 
						||
| 
								 | 
							
										;
							 | 
						||
| 
								 | 
							
											expand_inserts(Bucket,NewTable,NewCapacity)
							 | 
						||
| 
								 | 
							
										),
							 | 
						||
| 
								 | 
							
										J is I + 1,
							 | 
						||
| 
								 | 
							
										expand_copy(Table,J,N,NewTable,NewCapacity)
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								expand_inserts([],_,_).
							 | 
						||
| 
								 | 
							
								expand_inserts([K-V|R],Table,Capacity) :-
							 | 
						||
| 
								 | 
							
									expand_insert(Table,Capacity,K,V),
							 | 
						||
| 
								 | 
							
									expand_inserts(R,Table,Capacity).
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								expand_insert(Table,Capacity,K,V) :-
							 | 
						||
| 
								 | 
							
									term_hash(K,Hash),
							 | 
						||
| 
								 | 
							
									Index is (Hash mod Capacity) + 1,
							 | 
						||
| 
								 | 
							
									arg(Index,Table,Bucket),
							 | 
						||
| 
								 | 
							
									( var(Bucket) ->
							 | 
						||
| 
								 | 
							
										Bucket = K - V
							 | 
						||
| 
								 | 
							
									; Bucket = _-_ ->
							 | 
						||
| 
								 | 
							
										setarg(Index,Table,[K-V,Bucket])
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										setarg(Index,Table,[K-V|Bucket])
							 | 
						||
| 
								 | 
							
									).
							 | 
						||
| 
								 | 
							
								%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
							 | 
						||
| 
								 | 
							
								stats_ht(HT) :-
							 | 
						||
| 
								 | 
							
									HT = ht(Capacity,Load,Table),
							 | 
						||
| 
								 | 
							
									format('HT load = ~w / ~w\n',[Load,Capacity]),
							 | 
						||
| 
								 | 
							
									( between(1,Capacity,Index),
							 | 
						||
| 
								 | 
							
										arg(Index,Table,Entry),
							 | 
						||
| 
								 | 
							
										( var(Entry)  -> Size = 0
							 | 
						||
| 
								 | 
							
										; Entry = _-_ -> Size = 1
							 | 
						||
| 
								 | 
							
										; length(Entry,Size)
							 | 
						||
| 
								 | 
							
										),
							 | 
						||
| 
								 | 
							
										format('~w : ~w\n',[Index,Size]),
							 | 
						||
| 
								 | 
							
										fail
							 | 
						||
| 
								 | 
							
									;
							 | 
						||
| 
								 | 
							
										true
							 | 
						||
| 
								 | 
							
									).
							 |