3 Part of CHR
(Constraint Handling Rules
)
6 E
-mail
: Tom
.Schrijvers
@cs.kuleuven
.be
7 WWW
: http
://www
.swi
-prolog
.org
8 Copyright
(C
): 2003-2004, K
.U
. Leuven
10 This program is free software
; you can redistribute it
and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation
; either version
2
13 of the License
, or (at your option
) any later version
.
15 This program is distributed
in the hope that it will be useful
,
16 but WITHOUT ANY WARRANTY
; without even the implied warranty of
17 MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE
. See the
18 GNU General Public License
for more details
.
20 You should have received a copy of the GNU Lesser General Public
21 License along with this library
; if not, write to the Free Software
22 Foundation
, Inc
., 59 Temple Place
, Suite
330, Boston
, MA
02111-1307 USA
24 As a special exception
, if you
link this library with other files
,
25 compiled with a Free Software compiler
, to produce an executable
, this
26 library does
not by itself cause the resulting executable to be covered
27 by the GNU General Public License
. This exception does
not however
28 invalidate any other reasons why the executable file might be covered by
29 the GNU General Public License
.
31 % author
: Tom Schrijvers
32 % email
: Tom
.Schrijvers
@cs.kuleuven
.be
33 % copyright
: K
.U
.Leuven
, 2004
35 :- module
(chr_hashtable_store
,
50 :- use_module
(pairlist
).
51 :- use_module
(hprolog
).
52 :- use_module
(library
(lists
)).
54 :- multifile user
:goal_expansion
/2.
55 :- dynamic user
:goal_expansion
/2.
60 initial_capacity
(Capacity
),
63 new_ht
(Capacity
,HT
) :-
64 functor
(T1
,t
,Capacity
),
65 HT
= ht
(Capacity
,0,Table
),
68 lookup_ht
(HT
,Key
,Values
) :-
70 lookup_ht1
(HT
,Hash
,Key
,Values
).
72 HT
= ht
(Capacity
,_
,Table
),
73 Index is
(Hash mod Capacity
) + 1,
74 arg
(Index
,Table
,Bucket
),
80 lookup
(Bucket
,Key
,Values
)
84 % :- load_foreign_library
(chr_support
).
87 lookup_ht1
(HT
,Hash
,Key
,Values
) :-
88 ( lookup_ht1_
(HT
,Hash
,Key
,Values
) ->
91 ( lookup_ht1__
(HT
,Hash
,Key
,Values
) ->
92 writeln
(lookup_ht1
(HT
,Hash
,Key
,Values
)),
100 lookup_ht1
(HT
,Hash
,Key
,Values
) :-
101 HT
= ht
(Capacity
,_
,Table
),
102 Index is
(Hash mod Capacity
) + 1,
103 arg
(Index
,Table
,Bucket
),
109 lookup
(Bucket
,Key
,Values
)
112 lookup_ht2
(HT
,Key
,Values
,Index
) :-
114 HT
= ht
(Capacity
,_
,Table
),
115 Index is
(Hash mod Capacity
) + 1,
116 arg
(Index
,Table
,Bucket
),
122 lookup
(Bucket
,Key
,Values
)
125 lookup_pair_eq
([P
| KVs
],Key
,Pair
) :-
130 lookup_pair_eq
(KVs
,Key
,Pair
)
133 insert_ht
(HT
,Key
,Value
) :-
135 HT
= ht
(Capacity0
,Load
,Table0
),
136 LookupIndex is
(Hash mod Capacity0
) + 1,
137 arg
(LookupIndex
,Table0
,LookupBucket
),
138 ( var
(LookupBucket
) ->
139 LookupBucket
= Key
- [Value
]
140 ; LookupBucket
= K
-Values
->
142 setarg
(2,LookupBucket
,[Value
|Values
])
144 setarg
(LookupIndex
,Table0
,[Key
-[Value
],LookupBucket
])
147 ( lookup_pair_eq
(LookupBucket
,Key
,Pair
) ->
149 setarg
(2,Pair
,[Value
|Values
])
151 setarg
(LookupIndex
,Table0
,[Key
-[Value
]|LookupBucket
])
156 ( Load
== Capacity0
->
157 expand_ht
(HT
,_Capacity
)
162 insert_ht1
(HT
,Key
,Hash
,Value
) :-
163 HT
= ht
(Capacity0
,Load
,Table0
),
164 LookupIndex is
(Hash mod Capacity0
) + 1,
165 arg
(LookupIndex
,Table0
,LookupBucket
),
166 ( var
(LookupBucket
) ->
167 LookupBucket
= Key
- [Value
]
168 ; LookupBucket
= K
-Values
->
170 setarg
(2,LookupBucket
,[Value
|Values
])
172 setarg
(LookupIndex
,Table0
,[Key
-[Value
],LookupBucket
])
175 ( lookup_pair_eq
(LookupBucket
,Key
,Pair
) ->
177 setarg
(2,Pair
,[Value
|Values
])
179 setarg
(LookupIndex
,Table0
,[Key
-[Value
]|LookupBucket
])
184 ( Load
== Capacity0
->
185 expand_ht
(HT
,_Capacity
)
190 % LDK
: insert version with extra argument denoting result
192 insert_ht
(HT
,Key
,Value
,Result
) :-
193 HT
= ht
(Capacity
,Load
,Table
),
195 LookupIndex is
(Hash mod Capacity
) + 1,
196 arg
(LookupIndex
,Table
,LookupBucket
),
199 LookupBucket
= Key
- Result
,
201 ; LookupBucket
= K
- V
203 -> Result
= [Value
|V
],
204 setarg
(2,LookupBucket
,Result
),
207 setarg
(LookupIndex
,Table
,[Key
- Result
,LookupBucket
]),
210 ; ( lookup_pair_eq
(LookupBucket
,Key
,Pair
)
212 Result
= [Value
|Values
],
213 setarg
(2,Pair
,Result
),
216 setarg
(LookupIndex
,Table
,[Key
- Result
|LookupBucket
]),
220 setarg
(2,HT
,NewLoad
),
226 % LDK
: deletion of the first element of a bucket
227 delete_first_ht
(HT
,Key
,Values
) :-
228 HT
= ht
(Capacity
,Load
,Table
),
230 Index is
(Hash mod Capacity
) + 1,
231 arg
(Index
,Table
,Bucket
),
232 ( Bucket
= _
-[_
|Values
]
234 -> setarg
(Index
,Table
,_
),
236 ; setarg
(2,Bucket
,Values
),
239 ; lookup_pair_eq
(Bucket
,Key
,Pair
)
240 -> Pair
= _
-[_
|Values
],
242 -> pairlist_delete_eq
(Bucket
,Key
,NewBucket
),
244 -> setarg
(Index
,Table
,_
)
245 ; NewBucket
= [OtherPair
]
246 -> setarg
(Index
,Table
,OtherPair
)
247 ; setarg
(Index
,Table
,NewBucket
)
250 ; setarg
(2,Pair
,Values
),
255 delete_ht
(HT
,Key
,Value
) :-
256 HT
= ht
(Capacity
,Load
,Table
),
259 Index is
(Hash mod Capacity
) + 1,
260 arg
(Index
,Table
,Bucket
),
263 ; */ Bucket
= _K
-Vs
->
265 delete_first_fail
(Vs
,Value
,NVs
) ->
268 setarg
(Index
,Table
,_
)
276 ( lookup_pair_eq
(Bucket
,Key
,Pair
),
278 delete_first_fail
(Vs
,Value
,NVs
) ->
281 pairlist_delete_eq
(Bucket
,Key
,NBucket
),
282 ( NBucket
= [Singleton
] ->
283 setarg
(Index
,Table
,Singleton
)
285 setarg
(Index
,Table
,NBucket
)
295 delete_first_fail
([X
| Xs
], Y
, Zs
) :-
300 delete_first_fail
(Xs
, Y
, Zs1
)
303 delete_ht1
(HT
,Key
,Value
,Index
) :-
304 HT
= ht
(_Capacity
,Load
,Table
),
306 % term_hash
(Key
,Hash
),
307 % Index is
(Hash mod _Capacity
) + 1,
308 arg
(Index
,Table
,Bucket
),
311 ; */ Bucket
= _K
-Vs
->
313 delete_first_fail
(Vs
,Value
,NVs
) ->
316 setarg
(Index
,Table
,_
)
324 ( lookup_pair_eq
(Bucket
,Key
,Pair
),
326 delete_first_fail
(Vs
,Value
,NVs
) ->
329 pairlist_delete_eq
(Bucket
,Key
,NBucket
),
330 ( NBucket
= [Singleton
] ->
331 setarg
(Index
,Table
,Singleton
)
333 setarg
(Index
,Table
,NBucket
)
342 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
343 value_ht
(HT
,Value
) :-
344 HT
= ht
(Capacity
,_
,Table
),
345 value_ht
(1,Capacity
,Table
,Value
).
347 value_ht
(I
,N
,Table
,Value
) :-
360 value_ht
(J
,N
,Table
,Value
)
363 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
365 expand_ht
(HT
,NewCapacity
) :-
366 HT
= ht
(Capacity
,_
,Table
),
367 NewCapacity is Capacity
* 2 + 1,
368 functor
(NewTable
,t
,NewCapacity
),
369 setarg
(1,HT
,NewCapacity
),
370 setarg
(3,HT
,NewTable
),
371 expand_copy
(Table
,1,Capacity
,NewTable
,NewCapacity
).
373 expand_copy
(Table
,I
,N
,NewTable
,NewCapacity
) :-
380 ; Bucket
= Key
- Value
->
381 expand_insert
(NewTable
,NewCapacity
,Key
,Value
)
383 expand_inserts
(Bucket
,NewTable
,NewCapacity
)
386 expand_copy
(Table
,J
,N
,NewTable
,NewCapacity
)
389 expand_inserts
([],_
,_
).
390 expand_inserts
([K
-V
|R
],Table
,Capacity
) :-
391 expand_insert
(Table
,Capacity
,K
,V
),
392 expand_inserts
(R
,Table
,Capacity
).
394 expand_insert
(Table
,Capacity
,K
,V
) :-
396 Index is
(Hash mod Capacity
) + 1,
397 arg
(Index
,Table
,Bucket
),
401 setarg
(Index
,Table
,[K
-V
,Bucket
])
403 setarg
(Index
,Table
,[K
-V
|Bucket
])
405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
407 HT
= ht
(Capacity
,Load
,Table
),
408 format
('HT load = ~w / ~w\n',[Load
,Capacity
]),
409 ( between
(1,Capacity
,Index
),
410 arg
(Index
,Table
,Entry
),
411 ( var
(Entry
) -> Size
= 0
412 ; Entry
= _
-_
-> Size
= 1
415 format
('~w : ~w\n',[Index
,Size
]),