Listen

Listen

Listen †bersicht Listen allgemein Listen in Prolog Schreibweise Listen als rekursive Datenstruktur Unifikation Programmiertechniken mit Listen rekurs...

399KB Sizes 0 Downloads 5 Views

Listen †bersicht Listen allgemein Listen in Prolog Schreibweise Listen als rekursive Datenstruktur Unifikation

Programmiertechniken mit Listen rekursive Suche Abbilden

Zweck Erstellen von Prolog-Programmen mit Listen Listen Ð 1

Listen Listen treten hŠufig auf: Teilnehmer eines Kurses Einzelstationen eines Weges Mitglieder einer Familie Wšrter in einem Satz Buchstaben eines Wortes É

Listen Ð 2

Eigenschaften Listen besitzen bestimmte Eigenschaften Die einzelnen Elemente sind geordnet Dasselbe Element kann mehrmals vorkommen Beispielliste: Wšrter im Satz ÈWenn Fliegen hinter Fliegen fliegen, fliegen Fliegen Fliegen nachÇ

Listen kšnnen beliebig lang werden Listen kšnnen auch leer sein (sog. leere Liste)

Listen Ð 3

Listen in Prolog FŸr Listen gibt es in Prolog eine eigene Schreibweise Elemente zwischen eckigen Klammern eingeschlossen durch Kommata getrennt Elemente = beliebige Terme

[apfel, Frucht]

[kiwi] Ein Element

Zwei Elemente (ein Atom und eine Variable)

[] leere Liste Listen Ð 4

Listen in Prolog Eigentlich sind Listen ganz normale Terme die Schreibweise mit [ und ] ist eine AbkŸrzung fŸr eine etwas kompliziertere Struktur → spŠter im Semester

die einzelnen Elemente einer Liste kšnnen selber Listen sein

[ [d,a,t,t,e,l], [ ], [k,o,k,o,s] ] Listen als Elemente von Listen Listen Ð 5

Unifikation von Listen Zwei Listen kšnnen miteinander unifiziert werden: die einzelnen Elemente werden paarweise unifiziert die LŠnge beider Listen muss Ÿbereinstimmen frisst(fido, [gulasch, Gemuese]) frisst(fido, [Fleisch, gurke ]) Fleisch/gulasch

frisst(fido, [gulasch, Gemuese]) frisst(fido, [gulasch, gurke ]) Gemuese/gurke

frisst(fido, [gulasch, frisst(fido, [gulasch,

gurke ]) gurke ])

Listen Ð 6

Listen: Eine rekursive Datenstruktur Eine nicht-leere Liste besteht aus zwei Teilen: einem Anfang (Head, First Element) das erste Element kann ein beliebiger Term sein

einem Rest (Rest, Tail) der Rest ist eine Liste (nicht-leer oder leer)

g

n Anfa

[kaffee, tee, cola]

Listen Ð 7

Rest

kaffee [tee, cola]

Listen: Eine rekursive Datenstruktur [kaffee, tee, cola] g n a f n A

kaffee

Rest

[tee, cola] g Anfan

Rest

tee

[cola] g n a f n A

cola Listen Ð 8

Rest

[]

Listen in Prolog: | Mit | ist der Rest einer Liste erreichbar. Dies wird oft im Rahmen einer Unifikation benutzt ?- [a, b, c, d] = [a, b | Rest]. Rest = [c, d] ?- [a, b, c, d] = [a, b, c, d | Rest]. Rest = [] ?- [Anfang | Rest] = [a, b | [c, d]]. Anfang = a, Rest = [b, c, d]

Listen Ð 9

Rekursive Suche Schreibe ein Prolog-PrŠdikat member/2, das bestimmt, ob ein Term in einer Liste enthalten ist. Beispiele fŸr die Anwendung: ?- member(dackel, [spitz, dackel, terrier]). yes ?- member(sittich, [spitz, dackel, terrier]). no ?- member(X, [spitz, dackel, terrier]). X = spitz ; X = dackel ; X = terrier ; no more solutions Listen Ð 10

Rekursive Suche Die Lšsung geht rekursiv vor, indem jeweils das vorderste Element der Liste mit dem gesuchten Term verglichen wird. Abbruchbedingung: Das vorderste Element ist mit dem gesuchten Term unifizierbar. Rekursiver Fall: Suche im Rest der Liste (d.h. ohne das vorderste Element) weiter. member(dackel, [spitz, mops, dackel, terrier]) member(dackel, [mops, dackel, terrier]) member(dackel, [dackel, terrier]) Listen Ð 11

Rekursive Suche: Abbruchbedingung Wie bei allen rekursiven Problemen steht die Abbruchbedingung zuerst im Programm. X ist Element der Liste, wenn X das erste Element in der Liste ist. member(X, Liste) :Liste = [X | IrgendeinRest]. Einfacher geschrieben: member(X, [X | IrgendeinRest]). Eigentlich interessiert uns der Rest gar nicht. member(X, [X | _]).

Beispiel: member(dackel, [dackel, terrier]). Listen Ð 12

Rekursive Suche: Rekursiver Fall Zweite Mšglichkeit: X kšnnte im Rest enthalten sein. Nimm den Rest der Liste und prŸfe, ob X im Rest enthalten ist. member(X, [Anfang | Rest]) :member(X, Rest). Eigentlich interessiert uns der Anfang gar nicht. member(X, [_ | Rest]) :member(X, Rest).

Beispiel: member(dackel, [spitz, mops, dackel, terrier]). member(dackel, [mops, dackel, terrier]). Listen Ð 13

Rekursive Suche: member / 2

member(X, [X | _]). member(X, [_ | Rest]) :member(X, Rest).

Listen Ð 14

Abbilden (Mapping) Eingabe: Eine rekursive Prolog-Struktur (z. B. Liste). Ausgabe: €hnliche Struktur, jedoch in bestimmter Weise verŠndert. Beispiel:

[du, bist, nett] ⇒ [ich, bin, nett] [ich, bin, schšn] ⇒ [du, bist, schšn] [sie, sagt, du, seist, klug] ⇒ [sie, sagt, ich, sei, klug] Im Beispiel ist die Ausgabe gleich der Eingabe, ausser fŸr die Listenelemente du, bist, ich, bin, seist. Listen Ð 15

Abbilden (Mapping) Vorgehen: Rekursion Gehe schrittweise durch die Liste (ÈtraversierenÇ) Bilde jedes einzelne Element auf das entsprechende Ergebnis ab .

. .

sie

.

sagt

.

sie

.

sagt .

du seist

klug

.

ich .

.

sei []

klug Listen Ð 16

[]

Abbilden: change/2 Zum Abbilden der einzelnen Listenelemente definieren wir uns ein HilfsprŠdikat change/2.

change(du, ich). change(ich, du). change(bist, bin). change(bin, bist). change(seist, sei). change(X, X). Listen Ð 17

du

ich

ich

du

bist

bin

bin

bist

seist

sei

klug

klug

sie

sie

Abbilden: Abbruchbedingung Das PrŠdikat papagei/2 bildet eine Liste in eine andere ab, wobei es sich change/2 bedient. Wie bei allen Rekursionen steht die Abbruchbedingung vor dem rekursiven Fall. Abbruchbedingung: Eine leere Liste wird auf eine leere Liste abgebildet.

[]

papagei([], []).

Listen Ð 18

[]

Abbilden: Rekursiver Fall Der rekursive Fall É benutzt change/2, um ein einzelnes Listenelement abzubilden ruft papagei/2 rekursiv auf, um den Rest der Liste abzubilden gibt als Resultat eine Liste zurŸck, die besteht aus: einem erstes Element: die Abbildung des ersten Elements einem Rest: die Abbildung des Rests

. ich

papagei([E|Rest], [AbbE|AbbRest]) :change(E, AbbE), papagei(Rest, AbbRest). Listen Ð 19

. du

Abbilden: papagei/2 % Abbildung bestimmter Terme. change(du, ich). change(bist, bin). change(ich, du). change(bin, bist). change(seist, sei). % Wenn es keiner der obigen Terme ist, ist % die Abbildung gleich dem Original. change(X, X). % Die Abbildung einer leeren Liste ergibt % eine leere Liste. papagei([], []). % Die Abbildung eines Terms, gefolgt von einer Rest-Liste % ist die Abbildung des Terms, gefolgt von der Abbildung % der Rest-Liste. papagei([E | Rest], [AbbE | AbbRest]) :change(E, AbbE), papagei(Rest, AbbRest). Listen Ð 20