Kurz: Eine Liste ist entweder leer [] oder [Kopf|Rest]:
Teil des Kurses Prolog
Listen und Kopf|Rest
Eine Liste ist entweder leer [] oder [Kopf|Rest]:
main :-
L = [1, 2, 3, 4, 5],
L = [Kopf|Rest], writeln(Kopf), writeln(Rest),
length(L, N), writeln(N),
nth0(0, L, E0), nth1(1, L, E1), writeln(E0-E1),
last(L, Letztes), writeln(Letztes),
reverse(L, R), writeln(R),
append([1, 2], [3], A), writeln(A),
msort([c, a, b, a], M), writeln(M),
sort([c, a, b, a], S), writeln(S),
sort(0, @>=, [3, 1, 2, 3], Absteigend), writeln(Absteigend),
sumlist(L, Summe), writeln(Summe),
max_list(L, Max), min_list(L, Min), writeln(Min-Max),
numlist(1, 5, NL), writeln(NL),
sum_list([1.5, 2.5], FS), writeln(FS).Ausgabe:
1
[2,3,4,5]
5
1-1
5
[5,4,3,2,1]
[1,2,3]
[a,a,b,c]
[a,b,c]
[3,3,2,1]
15
1-5
[1,2,3,4,5]
4.0member, append und select: rückwärts nutzbar
Prolog-Prädikate sind relational: Dasselbe Prädikat prüft, erzeugt oder zerlegt.
main :-
( member(2, [1, 2, 3]) -> writeln('2 ist enthalten') ; true ),
findall(X, member(X, [a, b, c]), Alle), writeln(Alle),
findall(A-B, append(A, B, [1, 2]), Zerlegungen), writeln(Zerlegungen),
append(Vorne, [3], [1, 2, 3]), writeln(Vorne),
select(b, [a, b, c], Ohne), writeln(Ohne),
findall(P, permutation([1, 2, 3], P), Perms), writeln(Perms),
exclude([X1]>>(X1 mod 2 =:= 0), [1, 2, 3, 4, 5, 6], Ungerade), writeln(Ungerade),
subtract([1, 2, 3, 4], [2, 4], Diff), writeln(Diff),
delete([a, b, a, c], a, OhneA), writeln(OhneA),
list_to_set([a, b, a, c, b], Menge), writeln(Menge).Ausgabe:
2 ist enthalten
[a,b,c]
[[]-[1,2],[1]-[2],[1,2]-[]]
[1,2]
[a,c]
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
[1,3,5]
[1,3]
[b,c]
[a,b,c]Eigene Listenprädikate
mein_laenge([], 0).
mein_laenge([_|T], N) :- mein_laenge(T, N1), N is N1 + 1.
mein_append([], L, L).
mein_append([K|T], L, [K|R]) :- mein_append(T, L, R).
mein_reverse(L, R) :- rev_akk(L, [], R).
rev_akk([], A, A).
rev_akk([K|T], A, R) :- rev_akk(T, [K|A], R).
summe([], 0).
summe([K|T], S) :- summe(T, S1), S is S1 + K.
enthalten(X, [X|_]).
enthalten(X, [_|T]) :- enthalten(X, T).
verdopple([], []).
verdopple([K|T], [D|R]) :- D is K * 2, verdopple(T, R).
main :-
mein_laenge([a, b, c], N), writeln(N),
mein_append([1], [2, 3], A), writeln(A),
mein_reverse([1, 2, 3], R), writeln(R),
summe([1, 2, 3, 4], S), writeln(S),
( enthalten(b, [a, b]) -> writeln(ja) ; writeln(nein) ),
verdopple([1, 2, 3], V), writeln(V).Ausgabe:
3
[1,2,3]
[3,2,1]
10
ja
[2,4,6]Higher-Order: maplist, foldl, include
quadrat(X, Y) :- Y is X * X.
addiere(X, A0, A) :- A is A0 + X.
main :-
maplist(quadrat, [1, 2, 3, 4], Q), writeln(Q),
maplist([X, Y]>>(Y is X + 10), [1, 2, 3], Plus10), writeln(Plus10),
foldl(addiere, [1, 2, 3, 4], 0, Summe), writeln(Summe),
include([X]>>(X > 2), [1, 2, 3, 4], Gross), writeln(Gross),
exclude([X]>>(X > 2), [1, 2, 3, 4], Klein), writeln(Klein),
maplist([A, B, C]>>(C is A * B), [1, 2, 3], [4, 5, 6], Produkte), writeln(Produkte),
sumlist(Produkte, Skalarprodukt), writeln(Skalarprodukt),
pairs_keys_values(Paare, [a, b, c], [1, 2, 3]), writeln(Paare),
nb_setval(zaehler, 0),
forall(member(_, [x, y, z]), (nb_getval(zaehler, V), V1 is V + 1, nb_setval(zaehler, V1))),
nb_getval(zaehler, Z), writeln(Z).Ausgabe:
[1,4,9,16]
[11,12,13]
10
[3,4]
[1,2]
[4,10,18]
32
[a-1,b-2,c-3]
3Strings und Atome
main :-
atom_length(hallo, L), writeln(L),
atom_concat(hal, lo, A), writeln(A),
atom_chars(abc, Zeichen), writeln(Zeichen),
atom_codes(ab, Codes), writeln(Codes),
upcase_atom(hallo, Gross), writeln(Gross),
atom_string(At, "text"), writeln(At),
string_concat("Hallo ", "Welt", S), writeln(S),
string_length(S, SL), writeln(SL),
split_string("a,b,c", ",", "", Teile), writeln(Teile),
atomic_list_concat([a, b, c], '-', Verbunden), writeln(Verbunden),
atomic_list_concat(Zerlegt, '-', 'x-y-z'), writeln(Zerlegt),
sub_atom(hallo, 1, 3, _, Teil), writeln(Teil),
number_codes(N, "42"), N2 is N + 1, writeln(N2),
format("~s~n", [[72, 105]]),
format("~a|~t~w~10||~n", [ab, 12]),
format("~e ~3f ~q~n", [1234.5, 2.0, 'Hallo Welt']).Ausgabe:
5
hallo
[a,b,c]
[97,98]
HALLO
text
Hallo Welt
10
[a,b,c]
a-b-c
[x,y,z]
all
43
Hi
ab| 12|
1.234500e+03 2.000 'Hallo Welt'Merke
- Listen sind
[]oder[Kopf|Rest]; viele Bibliotheksprädikate (append,member,select) arbeiten in beide Richtungen - Eigene Prädikate: Basisfall plus rekursiver Fall, oft mit Akkumulator
maplist,foldl,include,excludemit Lambda ([X]>>...) für Funktionen höherer Ordnung- Atome, Strings und Zeichenlisten lassen sich mit eingebauten Prädikaten umwandeln
Übungsaufgabe
Schreibe duplikate_entfernen/2 mit eigenen Regeln und vergleiche es mit list_to_set/2.
Quiz zur Selbstkontrolle
Wie zerlegt man eine Liste?
- [Kopf|Rest] (richtig)
- L.head
- L[0]
- first(L)
Wofür steht maplist?
- Wendet ein Prädikat auf alle Elemente an (richtig)
- Zeichnet Karten
- Sortiert Listen
- Löscht Listen
Warum kann append rückwärts genutzt werden?
- Prolog-Prädikate sind relational, nicht gerichtet (richtig)
- Wegen einer Compileroption
- Nur in SWI-Prolog 9
- Gar nicht
Weiter im Kurs
Zurück: Arithmetik und Vergleiche
Weiter: Backtracking, Cut und Kontrolle
Alle Kapitel: Prolog im Überblick