Files
mercury/library/pqueue.m
Zoltan Somogyi 6554ef7daa Replace "is" with "=".
Estimated hours taken: 2
Branches: main

Replace "is" with "=".
Add field names where relevant.
Replace integers with counters where relevant.
2003-05-26 09:01:46 +00:00

179 lines
5.4 KiB
Mathematica

%---------------------------------------------------------------------------%
% Copyright (C) 1994-1995, 1997, 1999, 2003 The University of Melbourne.
% This file may only be copied under the terms of the GNU Library General
% Public License - see the file COPYING.LIB in the Mercury distribution.
%---------------------------------------------------------------------------%
%
% file pqueue.m - implements a priority queue ADT.
% main author: conway.
% stability: high.
%
% A pqueue is a priority queue. A priority queue holds a collection
% of key-value pairs; the interface provides operations to create
% an empty priority queue, to insert a key-value pair into a priority
% queue, and to remove the element with the lowest key.
%
% Insertion/removal is not guaranteed to be "stable"; that is,
% if you insert two values with the same key, the order in which
% they will be removed is unspecified.
%
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
:- module pqueue.
:- interface.
:- import_module assoc_list.
:- type pqueue(_K, _V).
% Create an empty priority queue
:- pred pqueue__init(pqueue(_K, _V)).
:- mode pqueue__init(out) is det.
:- func pqueue__init = pqueue(_K, _V).
% Insert a value V with key K into a priority queue
% and return the new priority queue.
:- pred pqueue__insert(pqueue(K, V), K, V, pqueue(K, V)).
:- mode pqueue__insert(in, in, in, out) is det.
:- func pqueue__insert(pqueue(K, V), K, V) = pqueue(K, V).
% Remove the smallest item from the priority queue.
:- pred pqueue__remove(pqueue(K, V), K, V, pqueue(K, V)).
:- mode pqueue__remove(in, out, out, out) is semidet.
% Extract all the items from a priority queue by
% repeated removal, and place them in an association
% list.
:- pred pqueue__to_assoc_list(pqueue(K, V), assoc_list(K, V)).
:- mode pqueue__to_assoc_list(in, out) is det.
:- func pqueue__to_assoc_list(pqueue(K, V)) = assoc_list(K, V).
% Insert all the key-value pairs in an association list
% into a priority queue.
:- pred pqueue__assoc_list_to_pqueue(assoc_list(K, V), pqueue(K, V)).
:- mode pqueue__assoc_list_to_pqueue(in, out) is det.
:- func pqueue__assoc_list_to_pqueue(assoc_list(K, V)) = pqueue(K, V).
%---------------------------------------------------------------------------%
:- implementation.
:- import_module int, list, std_util.
:- type pqueue(K, V) ---> empty
; pqueue(int, K, V, pqueue(K, V), pqueue(K, V)).
%---------------------------------------------------------------------------%
pqueue__init(empty).
%---------------------------------------------------------------------------%
pqueue__insert(empty, K, V, pqueue(0, K, V, empty, empty)).
pqueue__insert(pqueue(D0, K0, V0, L0, R0), K, V, PQ) :-
D = D0 + 1,
compare(CMP, K, K0),
(
CMP = (<)
->
K1 = K,
V1 = V,
pqueue__insert_2(K0, V0, L0, R0, L, R)
;
K1 = K0,
V1 = V0,
pqueue__insert_2(K, V, L0, R0, L, R)
),
PQ = pqueue(D, K1 ,V1, L, R).
:- pred pqueue__insert_2(K, V, pqueue(K, V), pqueue(K, V),
pqueue(K, V), pqueue(K, V)).
:- mode pqueue__insert_2(in, in, in, in, out, out) is det.
pqueue__insert_2(K, V, empty, empty, pqueue(0, K, V, empty, empty), empty).
pqueue__insert_2(K, V, pqueue(D0, K0, V0, L0, R0), empty,
pqueue(D0, K0, V0, L0, R0), pqueue(0, K, V, empty, empty)).
pqueue__insert_2(K, V, empty, pqueue(D0, K0, V0, L0, R0),
pqueue(0, K, V, empty, empty), pqueue(D0, K0, V0, L0, R0)).
pqueue__insert_2(K, V, pqueue(D0, K0, V0, L0, R0), pqueue(D1, K1, V1, L1, R1),
PQ1, PQ2) :-
(
D0 > D1
->
pqueue__insert(pqueue(D1, K1, V1, L1, R1), K, V, PQ2),
PQ1 = pqueue(D0, K0, V0, L0, R0)
;
pqueue__insert(pqueue(D0, K0, V0, L0, R0), K, V, PQ1),
PQ2 = pqueue(D1, K1, V1, L1, R1)
).
%---------------------------------------------------------------------------%
pqueue__remove(pqueue(_, K, V, L0, R0), K, V, PQ) :-
pqueue__remove_2(L0, R0, PQ).
:- pred pqueue__remove_2(pqueue(K, V), pqueue(K, V), pqueue(K, V)).
:- mode pqueue__remove_2(in, in, out) is det.
pqueue__remove_2(empty, empty, empty).
pqueue__remove_2(empty, pqueue(D, K, V, L, R), pqueue(D, K, V, L, R)).
pqueue__remove_2(pqueue(D, K, V, L, R), empty, pqueue(D, K, V, L, R)).
pqueue__remove_2(pqueue(D0, K0, V0, L0, R0), pqueue(D1, K1, V1, L1, R1), PQ) :-
compare(CMP, K0, K1),
(
CMP = (<)
->
D0M1 = D0 - 1,
int__max(D0M1, D1, D),
pqueue__remove_2(L0, R0, PQ0),
PQ = pqueue(D, K0, V0, PQ0, pqueue(D1, K1, V1, L1, R1))
;
D1M1 = D0 - 1,
int__max(D1M1, D1, D),
pqueue__remove_2(L1, R1, PQ1),
PQ = pqueue(D, K1, V1, PQ1, pqueue(D0, K0, V0, L0, R0))
).
%---------------------------------------------------------------------------%
pqueue__to_assoc_list(Q0, L) :-
(
pqueue__remove(Q0, K, V, Q1)
->
pqueue__to_assoc_list(Q1, L0),
L = [K - V | L0]
;
L = []
).
pqueue__assoc_list_to_pqueue([], Q) :-
pqueue__init(Q).
pqueue__assoc_list_to_pqueue([K - V | L], Q) :-
pqueue__assoc_list_to_pqueue(L, Q0),
pqueue__insert(Q0, K, V, Q).
%---------------------------------------------------------------------------%
%---------------------------------------------------------------------------%
% Ralph Becket <rwab1@cl.cam.ac.uk> 29/04/99
% Functional forms added.
pqueue__init = PQ :-
pqueue__init(PQ).
pqueue__insert(PQ1, K, V) = PQ2 :-
pqueue__insert(PQ1, K, V, PQ2).
pqueue__to_assoc_list(PQ) = AL :-
pqueue__to_assoc_list(PQ, AL).
pqueue__assoc_list_to_pqueue(AL) = PQ2 :-
pqueue__assoc_list_to_pqueue(AL, PQ2).