[comp.lang.prolog] Doubly-linked list package

philip@mulga.oz (Philip Dart) (11/03/87)

% Following the comments about Fortran as an AI language,
% Melbourne University Department of Artificial Intelligence
% has decided to convert all of its Fortran AI programs to NU-Prolog.
% This package has been written as an aid to this conversion.

% For non-NU-Prolog users, simply comment out the when declarations.

% Doubly-linked list package.
%	Why use boring old single-linked lists when doubly-linked
%	list could make your list processing applications
%	run as never before.

% ?- dAdj(L, R) when L and R.		% Are these adjacent nodes?
% ?- dPrev(D, _) when D.			% Get previous node.
% ?- dNext(D, _) when D.			% Get next node.
% ?- dHead(D, _) when D.			% Get head of list
% ?- dTail(D, _) when D.			% Get tail of list
% ?- isD(D) when D.			% Is this a doubly-linked list?
% ?- portray(D) when ever.		% Portray doubly-linked list
% ?- dAppend(X, Y, Z) when X or Z.	% Append for doubly-linked lists

test :-
	L1 = [1, 2, 3],
	listToD(L1, D1),
	write(L1), write(' <=> '), portray(D1), nl,
	L2 = [4, 5, 6, 7],
	listToD(L2, D2),
	write(L2), write(' <=> '), portray(D2), nl,
	dAppend(D1, D2, D3),
	listToD(L3, D3),
	isD(D3),
	write(L3), write(' <=> '), portray(D3), nl.

?- dAdj(L, R) when L and R.		% Are these adjacent nodes?
dAdj(L, R) :-
	L = d(_, _, R),
	R = d(L, _, _).

?- dPrev(D, _) when D.			% Get previous node.
dPrev(d(L, _, _), L).

?- dNext(D, _) when D.			% Get next node.
dNext(d(_, _, R), R).

?- dHead(D, _) when D.			% Get head of list
dHead([], []).
dHead(d([], D, R), d([], D, R)).
dHead(d(d(L, D, R), _, _), H) :-
	dHead(d(L, D, R), H).

?- dTail(D, _) when D.			% Get tail of list
dTail([], []).
dTail(d(L, D, []), d(L, D, [])).
dTail(d(_, _, d(L, D, R)), T) :-
	dTail(d(L, D, R), T).

?- listToD(List, D) when List or D.	% Convert single to doubly-linked list
listToD([], []).
listToD(H.T, D) :-
	D = d([], H, R),
	$listToD(T, D, R).

?- $listToD(List, _, D) when List or D.
$listToD([], _, []).
$listToD(H.T, L, D) :-
	D = d(L, H, R),
	$listToD(T, D, R).

?- isD(D) when D.			% Is this a doubly-linked list?
isD([]).
isD(D) :-
	D = d([], _, R),
	$isD(D, R).

?- $isD(_, D) when D.
$isD(_, []).
$isD(L, D) :-
	D = d(L, V, R),
	$isD(D, R).

?- portray(D) when ever.		% Portray doubly-linked list
portray(D) :-
	nonvar(D),
	D = d([], _, _),
	display('[]:'),
	$dPrint(D).

?- $dPrint(D) when D.
$dPrint([]) :-
	display('[]').
$dPrint(d(_, V, R)) :-
	display(V),
	display(':'),
	$dPrint(R).

?- dAppend(X, Y, Z) when X or Z.	% Append for doubly-linked lists
dAppend(X, [], X).
dAppend([], d([], D, R), d([], D, R)).
dAppend(d(L, X, R), d([], Y, RY), Z) :-
	$dAppend([], d(L, X, R), Y, RY, Z).

?- $dAppend(X, _, _, Z) when X or Z.
$dAppend(L, d(_, X, []), Y, R, Z) :-
	Z = d(L, X, H),
	H = d(Z, Y, R1),
	$dAppend1(H, R, R1).
$dAppend(L, d(_, X, d(L1, X1, R1)), Y, RY, d(L, X, RZ)) :-
	Z = d(L, X, RZ),
	$dAppend(Z, d(L1, X1, R1), Y, RY, RZ).

?- $dAppend(_, Y, Z) when Y or Z.
$dAppend1(_, [], []).
$dAppend1(L, d(_, D, R), Z) :-
	Z = d(L, D, R1),
	$dAppend1(Z, R, R1).

% P.S. Don't forget to turn off the occur-check in your version of Prolog!