This file is indexed.

/usr/lib/swi-prolog/library/heaps.pl is in swi-prolog-nox 5.10.4-3ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
/*  Part of SWI-Prolog

    Author:        Lars Buitinck
    E-mail:        larsmans@gmail.com
    WWW:           http://www.swi-prolog.org
    Copyright (C): 2010-2011, Lars Buitinck

    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 General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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.
*/

:- module(heaps,
          [ add_to_heap/4,		% +Heap0, +Priority, ?Key, -Heap
	    delete_from_heap/4,		% +Heap0, -Priority, +Key, -Heap
	    empty_heap/1,		% +Heap
	    get_from_heap/4,		% ?Heap0, ?Priority, ?Key, -Heap
	    heap_size/2,		% +Heap, -Size:int
	    heap_to_list/2,		% +Heap, -List:list
	    is_heap/1,			% +Term
	    list_to_heap/2,		% +List:list, -Heap
	    merge_heaps/3,		% +Heap0, +Heap1, -Heap
	    min_of_heap/3,		% +Heap, ?Priority, ?Key
	    min_of_heap/5,		% +Heap, ?Priority1, ?Key1,
	    				%        ?Priority2, ?Key2
	    singleton_heap/3		% ?Heap, ?Priority, ?Key
          ]).

/** <module> heaps/priority queues
 *
 * Heaps are data structures that return the entries inserted into them in an
 * ordered fashion, based on a priority. This makes them the data structure of
 * choice for implementing priority queues, a central element of algorithms
 * such as best-first/A* search and Kruskal's minimum-spanning-tree algorithm.
 *
 * This module implements min-heaps, meaning that items are retrieved in
 * ascending order of key/priority. It was designed to be compatible with
 * the SICStus Prolog library module of the same name. merge_heaps/3 and
 * singleton_heap/3 are SWI-specific extension. The portray_heap/1 predicate
 * is not implemented.
 *
 * Although the data items can be arbitrary Prolog data, keys/priorities must
 * be ordered by @=</2. Be careful when using variables as keys, since binding
 * them in between heap operations may change the ordering.
 *
 * The current version implements pairing heaps. All operations can be
 * performed in at most O(lg n) amortized time, except for delete_from_heap/4,
 * heap_to_list/2, is_heap/1 and list_to_heap/2.
 *
 * (The actual time complexity of pairing heaps is complicated and not yet
 * determined conclusively; see, e.g. S. Pettie (2005), Towards a final
 * analysis of pairing heaps, Proc. FOCS'05.)
 *
 * @author Lars Buitinck
 *
 * @bug The "decrease key" operation is not implemented.
 */

/*
 * Heaps are represented as heap(H,Size) terms, where H is a pairing heap and
 * Size is an integer. A pairing heap is either nil or a term
 * t(X,PrioX,Sub) where Sub is a list of pairing heaps t(Y,PrioY,Sub) s.t.
 * PrioX @< PrioY. See predicate is_heap/2, below.
 */

%%	add_to_heap(+Heap0, +Priority, ?Key, -Heap) is semidet.
%
%	Adds Key with priority Priority  to   Heap0,  constructing a new
%	heap in Heap.

add_to_heap(heap(Q0,M),P,X,heap(Q1,N)) :-
	meld(Q0,t(X,P,[]),Q1),
	N is M+1.

%%	delete_from_heap(+Heap0, -Priority, +Key, -Heap) is semidet.
%
%	Deletes Key from Heap0, leaving its priority in Priority and the
%	resulting data structure in Heap.   Fails if Key is not found in
%	Heap0.
%
%	@bug This predicate is extremely inefficient and exists only for
%	     SICStus compatibility.

delete_from_heap(Q0,P,X,Q) :-
	get_from_heap(Q0,P,X,Q), !.
delete_from_heap(Q0,Px,X,Q) :-
	get_from_heap(Q0,Py,Y,Q1),
	delete_from_heap(Q1,Px,X,Q2),
	add_to_heap(Q2,Py,Y,Q).

%%	empty_heap(?Heap) is semidet.
%
%       True if Heap is an empty heap.

empty_heap(heap(nil,0)).

%%	singleton_heap(?Heap, ?Priority, ?Key) is semidet.
%
%	True if Heap is a heap with the single element Priority-Key.

singleton_heap(heap(t(X,P,[]), 1), X, P).

%%	get_from_heap(?Heap0, ?Priority, ?Key, -Heap) is semidet.
%
%	Retrieves the minimum-priority  pair   Priority-Key  from Heap0.
%	Heap is Heap0 with that pair removed.

get_from_heap(heap(t(X,P,Sub),M), P, X, heap(Q,N)) :-
	pairing(Sub,Q),
	N is M-1.

%%	heap_size(+Heap, -Size:int) is det.
%
%	Determines the number of elements in Heap.

heap_size(heap(_,N),N).

%%	heap_to_list(+Heap, -List:list) is det.
%
%	Constructs a list List  of   Priority-Element  terms, ordered by
%	(ascending) priority.

heap_to_list(Q,L) :-
	to_list(Q,L).
to_list(heap(nil,0),[]) :- !.
to_list(Q0,[P-X|Xs]) :-
	get_from_heap(Q0,P,X,Q),
	heap_to_list(Q,Xs).

%%	is_heap(+X) is semidet.
%
%	Returns true is X is a heap.
%
%	@bug May return false positives.

is_heap(V) :-
	var(V), !, fail.
is_heap(heap(Q,N)) :-
	integer(N),
	\+ var(Q),
	(   Q == nil
	->  N == 0
	;   N > 0,
	    Q = t(_,MinP,Sub),
	    are_pairing_heaps(Sub, MinP)
	).

% True iff 1st arg is a pairing heap with min key @=< 2nd arg,
% where min key of nil is logically @> any term.
is_pairing_heap(V, _) :-
	var(V), !,
	fail.
is_pairing_heap(nil, _).
is_pairing_heap(t(_,P,Sub), MinP) :-
	P @=< MinP,
	are_pairing_heaps(Sub, P).

% True iff 1st arg is a list of pairing heaps, each with min key @=< 2nd arg.
are_pairing_heaps(V, _) :-
	var(V), !,
	fail.
are_pairing_heaps([], _).
are_pairing_heaps([Q|Qs], MinP) :-
	is_pairing_heap(Q, MinP),
	are_pairing_heaps(Qs, MinP).

%%	list_to_heap(+List:list, -Heap) is det.
%
%	If List is a list of  Priority-Element  terms, constructs a heap
%	out of List.

list_to_heap(Xs,Q) :-
	empty_heap(Empty),
	list_to_heap(Xs,Empty,Q).

list_to_heap([],Q,Q).
list_to_heap([P-X|Xs],Q0,Q) :-
	add_to_heap(Q0,P,X,Q1),
	list_to_heap(Xs,Q1,Q).

%%	min_of_heap(+Heap, ?Priority, ?Key) is semidet.
%
%	Unifies Key with  the  minimum-priority   element  of  Heap  and
%	Priority with its priority value.

min_of_heap(heap(t(X,P,_),_), P, X).

%%	min_of_heap(+Heap, ?Priority1, ?Key1, ?Priority2, ?Key2) is semidet.
%
%	Gets the two minimum-priority elements from Heap.

min_of_heap(Q,Px,X,Py,Y) :-
	get_from_heap(Q,Px,X,Q0),
	min_of_heap(Q0,Py,Y).

%%	merge_heaps(+Heap0, +Heap1, -Heap) is det.
%
%	Merge the two heaps Heap0 and Heap1 in Heap.

merge_heaps(heap(L,K),heap(R,M),heap(Q,N)) :-
	meld(L,R,Q),
	N is K+M.


% Merge two pairing heaps according to the pairing heap definition.
meld(nil,Q,Q) :- !.
meld(Q,nil,Q) :- !.
meld(L,R,Q) :-
	L = t(X,Px,SubL),
	R = t(Y,Py,SubR),
	(   Px @< Py
	->  Q = t(X,Px,[R|SubL])
	;   Q = t(Y,Py,[L|SubR])
	).

% "Pair up" (recursively meld) a list of pairing heaps.
pairing([], nil).
pairing([Q], Q) :- !.
pairing([Q0,Q1|Qs], Q) :-
	meld(Q0, Q1, Q2),
	pairing([Q2|Qs], Q).