4. Ein rekursiver Datentyp: die Liste
In PROLOG wird das Funktionssymbol .
besonders unterstützt,
das sogenannte Listenfunktionsymbol.
Eine PROLOG-Liste besteht entweder aus der leeren Liste []
, oder
aus einem Paar der Gestalt .(Kopf, Rumpf)
wobei Rumpf
eine Liste ist. Die Liste
.(a, .(b, .(c, [])))
kann der Einfachheit halber auch
[a, b, c]
dargestellt werden.
Ein Listenpaar .(Kopf, Rumpf)
kann auch
[Kopf | Rumpf]
dargestellt werden.
Die folgende Sitzung gibt einen Überblick über die Nutzung von Listen
in PROLOG:
:- atom([]).
yes.
:- X = .(a, []).
X = [a]
yes.
:- X = .(a, .(b, .(c, []))) .
X = [a, b, c]
yes.
:- X = .(a, R).
X = [a | R]
R = R
yes.
:- X = .(a, .(b, .(c, R))) .
X = [a, b, c | R]
R = R
yes.
:- [a, b, c] = [K | R].
K = a
R = [b, c]
yes.
:- [a, b, c, d, e] = [K1, K2 | R].
K1 = a
K2 = b
R = [c, d, e]
yes.
:- [H | T] = .(K, R).
H = K
T = R
K = K
R = R
yes.
:- [] = [K | R].
no (more) solution.
:-
Listen können wie folgt spezifiziert werden.
Dabei tritt ein häufiges Problem
der Darstellung von Variablen in Beweisen auf.
tahiti(bry): % eclipse
ECRC Common Logic Programming System [sepia opium megalog]
Version 3.4.5, Copyright ECRC GmbH, Thu Jun 16 11:08 1994
[eclipse 1]: [user].
liste([]).
liste([K | R]) :- liste(R).
*** Warning: Singleton variables in clause 2 of liste/1: K
user compiled traceable 168 bytes in 0.00 seconds
yes.
[eclipse 2]: liste([a, b, c]).
yes.
[eclipse 3]: liste(L).
L = [] More? (;) ;
L = [K] More? (;) ;
L = [K, K] More? (;) ;
L = [K, K, K] More? (;)
yes.
[eclipse 4]:
Es folgen einige nützliche PROLOG-Programme zur Listenbehandlung:
31
member(M, [M | _]).
member(M, [_ | T]) :- member(M, T).
append([], L, L).
append([K|R], L1, [K|L2]) :- append(R, L1, L2).
:- append([a,b,c], [d, e], L).
L = [a, b, c, d, e]
yes.
:- append(L1, [d, e], [a, b, c, d, e]).
L1 = [a, b, c] More? (;) ;
no (more) solution.
:- append([a, b, c], L2, [a, b, c, d, e]).
L2 = [d, e]
yes.
:- append(L1, L2, [a, b, c, d, e]).
L1 = []
L2 = [a, b, c, d, e] More? (;) ;
L1 = [a]
L2 = [b, c, d, e] More? (;) ;
L1 = [a, b]
L2 = [c, d, e] More? (;) ;
L1 = [a, b, c]
L2 = [d, e] More? (;) ;
L1 = [a, b, c, d]
L2 = [e] More? (;) ;
L1 = [a, b, c, d, e]
L2 = []
yes.
:-
32
praefix(P, L) :- append(P, _, L).
suffix(S, L) :- append(_, S, L).
subliste_1(Sub, L) :- praefix(P, L), suffix(Sub, P).
subliste_2(Sub, L) :- suffix(S, L), praefix(Sub, S).
subliste_3(Sub, L) :- praefix(Sub, L).
subliste_3(Sub, [_|R]) :- subliste_3(Sub, R).
member_1(X, L) :- subliste([X], L).
33
naive_reverse([], []).
naive_reverse([K|L], R_K) :- naive_reverse(L,R), append(R, [K], R_K).
34a
reverse(L, RL) :- hilfsreverse(L, [], RL).
hilfsreverse([K|R], Akk, L) :- hilfsreverse(R, [K|Akk], L).
hilfsreverse([], L, L).
Der folgende Beweis illustriert die Arbeitsweise
des nichtnaiven
reverse
< reverse([a, b, c, d], RL) >
< hilfsreverse([a, b, c, d], [], RL) >
< hilfsreverse([b, c, d], [a], RL) >
< hilfsreverse([c, d], [b, a], RL) >
< hilfsreverse([d], [c, b, a], RL) >
< hilfsreverse([], [d, c, b, a], RL) >
< hilfsreverse([], [d, c, b, a], [d, c, b, a]) >
34b
length([], 0).
length([K|R], L1) :- length(R, L), L1 is L + 1.
zum Seitenanfang