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.
57 user
:goal_expansion
(term_hash
(Term
,Hash
),hash_term
(Term
,Hash
)).
59 % term_hash
(Term
,Hash
) :-
60 % hash_term
(Term
,Hash
).
64 initial_capacity
(Capacity
),
67 new_ht
(Capacity
,HT
) :-
68 functor
(T1
,t
,Capacity
),
69 HT
= ht
(Capacity
,0,Table
),
72 lookup_ht
(HT
,Key
,Values
) :-
74 lookup_ht1
(HT
,Hash
,Key
,Values
).
76 HT
= ht
(Capacity
,_
,Table
),
77 Index is
(Hash mod Capacity
) + 1,
78 arg
(Index
,Table
,Bucket
),
84 lookup
(Bucket
,Key
,Values
)
88 % :- load_foreign_library
(chr_support
).
91 lookup_ht1
(HT
,Hash
,Key
,Values
) :-
92 ( lookup_ht1_
(HT
,Hash
,Key
,Values
) ->
95 ( lookup_ht1__
(HT
,Hash
,Key
,Values
) ->
96 writeln
(lookup_ht1
(HT
,Hash
,Key
,Values
)),
104 lookup_ht1
(HT
,Hash
,Key
,Values
) :-
105 HT
= ht
(Capacity
,_
,Table
),
106 Index is
(Hash mod Capacity
) + 1,
107 arg
(Index
,Table
,Bucket
),
113 lookup
(Bucket
,Key
,Values
)
116 lookup_ht2
(HT
,Key
,Values
,Index
) :-
118 HT
= ht
(Capacity
,_
,Table
),
119 Index is
(Hash mod Capacity
) + 1,
120 arg
(Index
,Table
,Bucket
),
126 lookup
(Bucket
,Key
,Values
)
129 lookup_pair_eq
([P
| KVs
],Key
,Pair
) :-
134 lookup_pair_eq
(KVs
,Key
,Pair
)
137 insert_ht
(HT
,Key
,Value
) :-
139 HT
= ht
(Capacity0
,Load
,Table0
),
140 LookupIndex is
(Hash mod Capacity0
) + 1,
141 arg
(LookupIndex
,Table0
,LookupBucket
),
142 ( var
(LookupBucket
) ->
143 LookupBucket
= Key
- [Value
]
144 ; LookupBucket
= K
-Values
->
146 setarg
(2,LookupBucket
,[Value
|Values
])
148 setarg
(LookupIndex
,Table0
,[Key
-[Value
],LookupBucket
])
151 ( lookup_pair_eq
(LookupBucket
,Key
,Pair
) ->
153 setarg
(2,Pair
,[Value
|Values
])
155 setarg
(LookupIndex
,Table0
,[Key
-[Value
]|LookupBucket
])
160 ( Load
== Capacity0
->
161 expand_ht
(HT
,_Capacity
)
166 insert_ht1
(HT
,Key
,Hash
,Value
) :-
167 HT
= ht
(Capacity0
,Load
,Table0
),
168 LookupIndex is
(Hash mod Capacity0
) + 1,
169 arg
(LookupIndex
,Table0
,LookupBucket
),
170 ( var
(LookupBucket
) ->
171 LookupBucket
= Key
- [Value
]
172 ; LookupBucket
= K
-Values
->
174 setarg
(2,LookupBucket
,[Value
|Values
])
176 setarg
(LookupIndex
,Table0
,[Key
-[Value
],LookupBucket
])
179 ( lookup_pair_eq
(LookupBucket
,Key
,Pair
) ->
181 setarg
(2,Pair
,[Value
|Values
])
183 setarg
(LookupIndex
,Table0
,[Key
-[Value
]|LookupBucket
])
188 ( Load
== Capacity0
->
189 expand_ht
(HT
,_Capacity
)
194 % LDK
: insert version with extra argument denoting result
196 insert_ht
(HT
,Key
,Value
,Result
) :-
197 HT
= ht
(Capacity
,Load
,Table
),
199 LookupIndex is
(Hash mod Capacity
) + 1,
200 arg
(LookupIndex
,Table
,LookupBucket
),
203 LookupBucket
= Key
- Result
,
205 ; LookupBucket
= K
- V
207 -> Result
= [Value
|V
],
208 setarg
(2,LookupBucket
,Result
),
211 setarg
(LookupIndex
,Table
,[Key
- Result
,LookupBucket
]),
214 ; ( lookup_pair_eq
(LookupBucket
,Key
,Pair
)
216 Result
= [Value
|Values
],
217 setarg
(2,Pair
,Result
),
220 setarg
(LookupIndex
,Table
,[Key
- Result
|LookupBucket
]),
224 setarg
(2,HT
,NewLoad
),
230 % LDK
: deletion of the first element of a bucket
231 delete_first_ht
(HT
,Key
,Values
) :-
232 HT
= ht
(Capacity
,Load
,Table
),
234 Index is
(Hash mod Capacity
) + 1,
235 arg
(Index
,Table
,Bucket
),
236 ( Bucket
= _
-[_
|Values
]
238 -> setarg
(Index
,Table
,_
),
240 ; setarg
(2,Bucket
,Values
),
243 ; lookup_pair_eq
(Bucket
,Key
,Pair
)
244 -> Pair
= _
-[_
|Values
],
246 -> pairlist_delete_eq
(Bucket
,Key
,NewBucket
),
248 -> setarg
(Index
,Table
,_
)
249 ; NewBucket
= [OtherPair
]
250 -> setarg
(Index
,Table
,OtherPair
)
251 ; setarg
(Index
,Table
,NewBucket
)
254 ; setarg
(2,Pair
,Values
),
259 delete_ht
(HT
,Key
,Value
) :-
260 HT
= ht
(Capacity
,Load
,Table
),
263 Index is
(Hash mod Capacity
) + 1,
264 arg
(Index
,Table
,Bucket
),
267 ; */ Bucket
= _K
-Vs
->
269 delete_first_fail
(Vs
,Value
,NVs
) ->
272 setarg
(Index
,Table
,_
)
280 ( lookup_pair_eq
(Bucket
,Key
,Pair
),
282 delete_first_fail
(Vs
,Value
,NVs
) ->
285 pairlist_delete_eq
(Bucket
,Key
,NBucket
),
286 ( NBucket
= [Singleton
] ->
287 setarg
(Index
,Table
,Singleton
)
289 setarg
(Index
,Table
,NBucket
)
299 delete_first_fail
([X
| Xs
], Y
, Zs
) :-
304 delete_first_fail
(Xs
, Y
, Zs1
)
307 delete_ht1
(HT
,Key
,Value
,Index
) :-
308 HT
= ht
(_Capacity
,Load
,Table
),
310 % term_hash
(Key
,Hash
),
311 % Index is
(Hash mod _Capacity
) + 1,
312 arg
(Index
,Table
,Bucket
),
315 ; */ Bucket
= _K
-Vs
->
317 delete_first_fail
(Vs
,Value
,NVs
) ->
320 setarg
(Index
,Table
,_
)
328 ( lookup_pair_eq
(Bucket
,Key
,Pair
),
330 delete_first_fail
(Vs
,Value
,NVs
) ->
333 pairlist_delete_eq
(Bucket
,Key
,NBucket
),
334 ( NBucket
= [Singleton
] ->
335 setarg
(Index
,Table
,Singleton
)
337 setarg
(Index
,Table
,NBucket
)
346 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
347 value_ht
(HT
,Value
) :-
348 HT
= ht
(Capacity
,_
,Table
),
349 value_ht
(1,Capacity
,Table
,Value
).
351 value_ht
(I
,N
,Table
,Value
) :-
364 value_ht
(J
,N
,Table
,Value
)
367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
369 expand_ht
(HT
,NewCapacity
) :-
370 HT
= ht
(Capacity
,_
,Table
),
371 NewCapacity is Capacity
* 2 + 1,
372 functor
(NewTable
,t
,NewCapacity
),
373 setarg
(1,HT
,NewCapacity
),
374 setarg
(3,HT
,NewTable
),
375 expand_copy
(Table
,1,Capacity
,NewTable
,NewCapacity
).
377 expand_copy
(Table
,I
,N
,NewTable
,NewCapacity
) :-
384 ; Bucket
= Key
- Value
->
385 expand_insert
(NewTable
,NewCapacity
,Key
,Value
)
387 expand_inserts
(Bucket
,NewTable
,NewCapacity
)
390 expand_copy
(Table
,J
,N
,NewTable
,NewCapacity
)
393 expand_inserts
([],_
,_
).
394 expand_inserts
([K
-V
|R
],Table
,Capacity
) :-
395 expand_insert
(Table
,Capacity
,K
,V
),
396 expand_inserts
(R
,Table
,Capacity
).
398 expand_insert
(Table
,Capacity
,K
,V
) :-
400 Index is
(Hash mod Capacity
) + 1,
401 arg
(Index
,Table
,Bucket
),
405 setarg
(Index
,Table
,[K
-V
,Bucket
])
407 setarg
(Index
,Table
,[K
-V
|Bucket
])
409 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
411 HT
= ht
(Capacity
,Load
,Table
),
412 format
('HT load = ~w / ~w\n',[Load
,Capacity
]),
413 ( between
(1,Capacity
,Index
),
414 arg
(Index
,Table
,Entry
),
415 ( var
(Entry
) -> Size
= 0
416 ; Entry
= _
-_
-> Size
= 1
419 format
('~w : ~w\n',[Index
,Size
]),