• Keine Ergebnisse gefunden

Built-In Prädikate Input/Output

N/A
N/A
Protected

Academic year: 2022

Aktie "Built-In Prädikate Input/Output"

Copied!
35
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Built-In Prädikate Input/Output

Nützliche Prädikate, die bereits in Prolog eingebaut sind Input/Output

Komplexere Programme: 8 Damen Problem in Lösungsvarianten

Nützliche Prädikate, die bereits in Prolog eingebaut sind Input/Output

Komplexere Programme: 8 Damen Problem in Lösungsvarianten

(2)

Acht Damen Problem

http://de.wikipedia.org/wiki/Damenproblem

Das Problem ist, acht Damen auf einem Schachbrett so anzuordnen, dass keine die andere bedroht.

solution(Pos). Pos repräsentiert eine Losung.

http://de.wikipedia.org/wiki/Damenproblem

Das Problem ist, acht Damen auf einem Schachbrett so anzuordnen, dass keine die andere bedroht.

solution(Pos). Pos repräsentiert eine Losung.

(3)

Acht Damen Problem

Repräsentation der acht Damen auf dem Brett:

Acht Objekte, wobei jedes eine Dame auf einem Feld des Schachbretts repräsentiert.

Jedes Feld kann durch ein Paar von Koordinaten X,Y dargestellt werden.

Die Koordinaten sind Integer zwischen 1 und 8.

Im Programm schreiben wir X/Y. '/' steht hier nicht für Division sondern kombiniert die Koordinaten eines Feldes.

Das Problem ist nun also, eine Liste zu finden wo keine Dame die andere bedroht

[X1/Y1,X2/Y2,X3/Y3,X4/Y4,X5/Y5,X6/Y6,X7/Y7,X8/Y8 ] Repräsentation der acht Damen auf dem Brett:

Acht Objekte, wobei jedes eine Dame auf einem Feld des Schachbretts repräsentiert.

Jedes Feld kann durch ein Paar von Koordinaten X,Y dargestellt werden.

Die Koordinaten sind Integer zwischen 1 und 8.

Im Programm schreiben wir X/Y. '/' steht hier nicht für Division sondern kombiniert die Koordinaten eines Feldes.

Das Problem ist nun also, eine Liste zu finden wo keine Dame die andere bedroht

[X1/Y1,X2/Y2,X3/Y3,X4/Y4,X5/Y5,X6/Y6,X7/Y7,X8/Y8 ]

(4)

Acht Damen Problem

Eine Dame bedroht die andere:

vertikal, horizontal, diagonal nach oben, diagonal nach unten.

Die Bedrohung ist symmetrisch wir können nach rechts auf dem Brett vorgehen.

Ein Teil der Lösung kann schon in der Repräsentation der Lösung formuliert werden. Alle Damen

müssen offensichtlich in verschiedenen Spalten sein, damit keine vertikale

Bedrohung eintritt. Wir halten in der Datenrepräsentation die X Koordinate fest.

[1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8 ]

Eine Dame bedroht die andere:

vertikal, horizontal, diagonal nach oben, diagonal nach unten.

Die Bedrohung ist symmetrisch wir können nach rechts auf dem Brett vorgehen.

Ein Teil der Lösung kann schon in der Repräsentation der Lösung formuliert werden. Alle Damen

müssen offensichtlich in verschiedenen Spalten sein, damit keine vertikale

Bedrohung eintritt. Wir halten in der Datenrepräsentation die X Koordinate fest.

[1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8 ]

(5)

Acht Damen Problem

Generalisierung zur Vereinfachung des Problems: finde die Lösung für 0-8 Damen. Das bedeutet die Liste der Damen kann 0 – 8

Objekte der Form X/Y enthalten.

Fall1: Die Liste der Damen ist leer. Dies ist eine Lösung, da hier keine Dame die andere bedroht.

Fall2: Die Liste ist nicht leer [X/Y|Others]. Die erste Dame steht also auf einem Feld X/Y und die anderen Damen stehen auf anderen

Feldern, die in Others spezifiziert sind. Bedingungen einer Lösung:

(a) Keine Bedrohung innerhalb der Liste Others, Others ist Lösung (b) X und Y sind integer zwischen 1 und 8

(c) Die Dame auf X/Y darf keine der Damen in Others bedrohen

Generalisierung zur Vereinfachung des Problems: finde die Lösung für 0-8 Damen. Das bedeutet die Liste der Damen kann 0 – 8

Objekte der Form X/Y enthalten.

Fall1: Die Liste der Damen ist leer. Dies ist eine Lösung, da hier keine Dame die andere bedroht.

Fall2: Die Liste ist nicht leer [X/Y|Others]. Die erste Dame steht also auf einem Feld X/Y und die anderen Damen stehen auf anderen

Feldern, die in Others spezifiziert sind. Bedingungen einer Lösung:

(a) Keine Bedrohung innerhalb der Liste Others, Others ist Lösung (b) X und Y sind integer zwischen 1 und 8

(c) Die Dame auf X/Y darf keine der Damen in Others bedrohen

(6)

Acht Damen Problem

Fall 1: solution([ ]).

Fall 2:

(a) Aufteilung des Problems durch rekursiven Aufruf.

(b) Y muss member von [1,2,3,4,5,6,7,8] sein. X wird dadurch

beschränkt, dass jede Lösung dem Template entsprechen muss, wo die X Koordinaten schon festgelegt sind.

(c) Nicht-Bedrohung wird durch ein Prädikat noattack implementiert

Fall 1: solution([ ]).

Fall 2:

(a) Aufteilung des Problems durch rekursiven Aufruf.

(b) Y muss member von [1,2,3,4,5,6,7,8] sein. X wird dadurch

beschränkt, dass jede Lösung dem Template entsprechen muss, wo die X Koordinaten schon festgelegt sind.

(c) Nicht-Bedrohung wird durch ein Prädikat noattack implementiert

(7)

Acht Damen Problem

Fall 2:

solution(X/Y|Others]) :-

solution(Others), member(Y,[1,2,3,4,5,6,7,8]),noattack(X/Y,Others).

Bleibt: noattack Prädikat noattack(Q,QList).

(1) Wenn QList leer ist, ist noattack erfüllt. Es gibt nur eine Dame auf dem Brett.

(2) Wenn QList nicht leer ist, hat sie die Form [Q1|Qlist1]

(a) Die Dame Q1 darf die Damen in QList1 nicht bedrohen (b) Die Dame Q darf nicht Q1 bedrohen und auch keine der Damen in Qlist1

Fall 2:

solution(X/Y|Others]) :-

solution(Others), member(Y,[1,2,3,4,5,6,7,8]),noattack(X/Y,Others).

Bleibt: noattack Prädikat noattack(Q,QList).

(1) Wenn QList leer ist, ist noattack erfüllt. Es gibt nur eine Dame auf dem Brett.

(2) Wenn QList nicht leer ist, hat sie die Form [Q1|Qlist1]

(a) Die Dame Q1 darf die Damen in QList1 nicht bedrohen (b) Die Dame Q darf nicht Q1 bedrohen und auch keine der Damen in Qlist1

(8)

Acht Damen Problem

Implementation der Nichtbedrohung der Damen: X/Y und X1/Y1 horizontal, vertikal, diagonal

vertikal: X Koordinaten müssen unterschiedlich sein, gewährleistet schon das Template

horizontal: Y Koordinaten müssen unterschiedlich sein Y = ⧵ = Y1

diagonal: weder aufwärts noch abwärts darf der Abstand der Felder in X Richtung gleich demjenigen in der Y Richtung sein.

Y1 – Y =⧵= X1 – X aufwärts (X1–X positiv) Y1 -Y =⧵= X -X1 abwärts (X-X1 negativ)

Implementation der Nichtbedrohung der Damen: X/Y und X1/Y1 horizontal, vertikal, diagonal

vertikal: X Koordinaten müssen unterschiedlich sein, gewährleistet schon das Template

horizontal: Y Koordinaten müssen unterschiedlich sein Y = ⧵ = Y1

diagonal: weder aufwärts noch abwärts darf der Abstand der Felder in X Richtung gleich demjenigen in der Y Richtung sein.

Y1 – Y =⧵= X1 – X aufwärts (X1–X positiv) Y1 -Y =⧵= X -X1 abwärts (X-X1 negativ)

(9)

Acht Damen Problem

Komplette Lösung Variante 1:

solution([]).

solution([X/Y|Others]):- solution(Others),

member(Y,[1,2,3,4,5,6,7,8]), noattack(X/Y,Others).

noattack(_,[]).

noattack(X/Y,[X1/Y1|RestOthers]):- Y=\Y1,

Y1-Y =\= X1-X, %aufwärts diagonal Y1-Y =\= X-X1, %abwärts

noattack(X/Y,RestOthers).

Komplette Lösung Variante 1:

solution([]).

solution([X/Y|Others]):- solution(Others),

member(Y,[1,2,3,4,5,6,7,8]), noattack(X/Y,Others).

noattack(_,[]).

noattack(X/Y,[X1/Y1|RestOthers]):- Y=\Y1,

Y1-Y =\= X1-X, %aufwärts diagonal Y1-Y =\= X-X1, %abwärts

noattack(X/Y,RestOthers).

(10)

Acht Damen Problem

Komplette Lösung Variante 1:

Hilfsprädikat:

member(Item,[Item|Rest]).

member(Item,[First|Rest]):- member(Item,Rest).

Lösungstemplate:

template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]).

Aufruf: ?- template(S),solution(S).

S=[1/4,2/2,3/7,4/3,5/6,6/8,7/5,8/1]

Komplette Lösung Variante 1:

Hilfsprädikat:

member(Item,[Item|Rest]).

member(Item,[First|Rest]):- member(Item,Rest).

Lösungstemplate:

template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]).

Aufruf: ?- template(S),solution(S).

S=[1/4,2/2,3/7,4/3,5/6,6/8,7/5,8/1]

(11)

Einbauprädikate

Bestimmung des Termtyps:

var(Term): yes falls der Term eine freie Variable ist nonvar(Term): yes falls nicht

integer(Term): yes falls Term mit einer Integerzahl gebunden ist

float(Term): yes falls Term mit einer Floatingpointzahl gebunden ist number(Term): yes falls Term entweder Integer oder Float

atom(Term): yes falls Term ein Atom ist e.g. john 'John'

string(Term):yes falls Term ein String ist (sehr ähnlich Atom, schnellere Verarbeitung, nicht für Standardprolog)

atomic(Term): yes falls Term ein Atom, eine Zahl oder ein String ist

Bestimmung des Termtyps:

var(Term): yes falls der Term eine freie Variable ist nonvar(Term): yes falls nicht

integer(Term): yes falls Term mit einer Integerzahl gebunden ist

float(Term): yes falls Term mit einer Floatingpointzahl gebunden ist number(Term): yes falls Term entweder Integer oder Float

atom(Term): yes falls Term ein Atom ist e.g. john 'John'

string(Term):yes falls Term ein String ist (sehr ähnlich Atom, schnellere Verarbeitung, nicht für Standardprolog)

atomic(Term): yes falls Term ein Atom, eine Zahl oder ein String ist

(12)

Einbauprädikate

Termvergleich:

Term1 == Term2: yes falls Term1 gleich mit Term2 Term1 ⧵== Term2: falls ungleich

Term1 = Term2: yes falls Unifikation der Terme erfolgreich Term 1 ⧵= Term2: falls Unifikation nicht erfolgreich

Termvergleich:

Term1 == Term2: yes falls Term1 gleich mit Term2 Term1 ⧵== Term2: falls ungleich

Term1 = Term2: yes falls Unifikation der Terme erfolgreich Term 1 ⧵= Term2: falls Unifikation nicht erfolgreich

(13)

Einbauprädikate

Zahlenvergleich:

between(Low,High,Value):

Low und High sind ganze Zahlen und High >= Low. Wenn Value eine ganze Zahl ist wird getestet: Low =< Value =< High

?- between(1,3,X).

X = 1 ;X = 2 ;X = 3 ;

Wird High mit inf oder infinite angegeben, produziert das Prädikat Integerzahlen hochzählend von Low aus.

Zahlenvergleich:

between(Low,High,Value):

Low und High sind ganze Zahlen und High >= Low. Wenn Value eine ganze Zahl ist wird getestet: Low =< Value =< High

?- between(1,3,X).

X = 1 ;X = 2 ;X = 3 ;

Wird High mit inf oder infinite angegeben, produziert das Prädikat Integerzahlen hochzählend von Low aus.

(14)

Einbauprädikate

succ(Int1,Int2): true wenn Int2 = Int1 +1 und Int1 >= 0 plus(Int1,Int2,Int3): true wenn Int1+Int2 =:= Int3

Vergleichsoperatoren

<,>,=<,>=,=⧵=, =:=

Number is Expression: true wenn Number erfolgreich mit der ganzzahligen Auswertung von Expression unifiziert wird

(Ausprobieren mit float Zahl?? X is 3/2 X =:= 1 ???)

succ(Int1,Int2): true wenn Int2 = Int1 +1 und Int1 >= 0 plus(Int1,Int2,Int3): true wenn Int1+Int2 =:= Int3

Vergleichsoperatoren

<,>,=<,>=,=⧵=, =:=

Number is Expression: true wenn Number erfolgreich mit der ganzzahligen Auswertung von Expression unifiziert wird

(Ausprobieren mit float Zahl?? X is 3/2 X =:= 1 ???)

(15)

Einbauprädikate

Listenprädikate

append(List1,List2,List3) hängt an die erste Liste die zweite an member(Element, List) liefert yes falls Element in List ist

nextto(X,Y,List): yes falls Y hinter X in List kommt delete(List1, X, List2): alle X in List1 löschen

select(Element,List,Rest): Element in List löschen, Rest ausgeben kann als insert benutzt werden

nth0(Index,List,Element): yes wenn Element das Index-te in List ist Zählen startet bei 0

nth1(Index,List,Element): wie vorher, Zählen startet bei 1 reverse(List1,List2): Ordnung der Elemente umkehren permutation(List1,List2): Elemente anders anordnen flatten(List1,List2): flache Liste rekursiv anordnen sumlist(List,Sum): summieren der Elemente

numlist(Low,High,List): Integerliste zwischen Low und High

Listenprädikate

append(List1,List2,List3) hängt an die erste Liste die zweite an member(Element, List) liefert yes falls Element in List ist

nextto(X,Y,List): yes falls Y hinter X in List kommt delete(List1, X, List2): alle X in List1 löschen

select(Element,List,Rest): Element in List löschen, Rest ausgeben kann als insert benutzt werden

nth0(Index,List,Element): yes wenn Element das Index-te in List ist Zählen startet bei 0

nth1(Index,List,Element): wie vorher, Zählen startet bei 1 reverse(List1,List2): Ordnung der Elemente umkehren permutation(List1,List2): Elemente anders anordnen flatten(List1,List2): flache Liste rekursiv anordnen sumlist(List,Sum): summieren der Elemente

numlist(Low,High,List): Integerliste zwischen Low und High

(16)

Einbauprädikate

Mengenprädikate

is_set(List): yes wenn Liste ohne Duplikate ist

list_to_set(List): Duplikate werden gelöscht, nur das erste Auftreten wird behalten

intersection(Set1,Set2,Set3): Elemente, die sowohl in Menge1 als auch in Menge2 vorkommen

subtract(Set,Delete,Result): lösche aus Set alle Elemente aus Delete union(Set1,Set2,Set3): Set1,Set2 sind Listen ohne Duplikate Set3 ist die Vereinigung

subset(Subset, Set): Alle Elemente aus Subset sind in Set enthalten Mengenprädikate

is_set(List): yes wenn Liste ohne Duplikate ist

list_to_set(List): Duplikate werden gelöscht, nur das erste Auftreten wird behalten

intersection(Set1,Set2,Set3): Elemente, die sowohl in Menge1 als auch in Menge2 vorkommen

subtract(Set,Delete,Result): lösche aus Set alle Elemente aus Delete union(Set1,Set2,Set3): Set1,Set2 sind Listen ohne Duplikate Set3 ist die Vereinigung

subset(Subset, Set): Alle Elemente aus Subset sind in Set enthalten

(17)

Einbauprädikate

Stringmanipulation

In SWI Prolog sind single-quoted Zeichenketten Atome, double- quoted Zeichenketten dagegen Listen der Einzelbuchstaben

?-atom("abc"). no

?-atom('abc'). yes.

?- append("Max","moni",L). L=[77,97,120,109,111,105]

?- append('Max','moni',L). no.

Stringmanipulation

In SWI Prolog sind single-quoted Zeichenketten Atome, double- quoted Zeichenketten dagegen Listen der Einzelbuchstaben

?-atom("abc"). no

?-atom('abc'). yes.

?- append("Max","moni",L). L=[77,97,120,109,111,105]

?- append('Max','moni',L). no.

(18)

Einbauprädikate

Stringmanipulation

string_to_atom(String,Atom): eines der Argumente muss instantiert sein: ?- string_to_atom(X,abc). X = "abc"

string_to_list(String,List): Die einzelnen Buchstaben von String werden mit ihren Zeichencodes in List geschrieben

string_length(String,Length): gibt die Zeichenzahl eines Strings aber auch eines Atoms an.

string_concat(S1,S2,S3): Zusammenhängen zweier Strings

sub_string(String,Start,Length,After,Sub): Sub ist ein Substring von String, der bei Start anfängt mit einer Länge von Length, dann sind noch After Buchstaben übrig

Stringmanipulation

string_to_atom(String,Atom): eines der Argumente muss instantiert sein: ?- string_to_atom(X,abc). X = "abc"

string_to_list(String,List): Die einzelnen Buchstaben von String werden mit ihren Zeichencodes in List geschrieben

string_length(String,Length): gibt die Zeichenzahl eines Strings aber auch eines Atoms an.

string_concat(S1,S2,S3): Zusammenhängen zweier Strings

sub_string(String,Start,Length,After,Sub): Sub ist ein Substring von String, der bei Start anfängt mit einer Länge von Length, dann sind noch After Buchstaben übrig

(19)

Einbauprädikate

Sonstige

Term =.. List: zerlegt einen Term in eine Liste

?- f(1,2) =..X.

X= [f,1,2]

functor(Term,Functor,Arity): gibt den Funktor und die Stelligkeit aus

help(Prädikat): zeigt den Hilfstext an

listing(Prädikat): zeigt die Implementierung an

?- listing(member) lists:member(A,[A|_]).

lists:member(A,[_|B]):- member(A,B).

true.

Sonstige

Term =.. List: zerlegt einen Term in eine Liste

?- f(1,2) =..X.

X= [f,1,2]

functor(Term,Functor,Arity): gibt den Funktor und die Stelligkeit aus

help(Prädikat): zeigt den Hilfstext an

listing(Prädikat): zeigt die Implementierung an

?- listing(member) lists:member(A,[A|_]).

lists:member(A,[_|B]):- member(A,B).

true.

(20)

Acht Damen Problem 2

Variante der Implementierung

Idee: da die Damen in unterschiedlichen Spalten angeordnet werden müssen um das Problem zu lösen, gilt X1=1,X2=2...X8=8

Damit kann ohne Informationsverlust auf die X-Werte verzichtet werden: [Y1,Y2,...Y8] genügt als Datenstruktur

Vermeiden einer horizontalen Bedrohung: keine zwei Damen in derselben Reihe, Constraint für die Y-Koordinaten: alle Reihen müssen belegt sein 1,2,...,8

Übrig bleibt als Problem die Ordnung der Liste [1,2,3,4,5,6,7,8]

Idee: Jede Lösung ist eine Permutation die bestimmte Bedingungen erfüllt

Variante der Implementierung

Idee: da die Damen in unterschiedlichen Spalten angeordnet werden müssen um das Problem zu lösen, gilt X1=1,X2=2...X8=8

Damit kann ohne Informationsverlust auf die X-Werte verzichtet werden: [Y1,Y2,...Y8] genügt als Datenstruktur

Vermeiden einer horizontalen Bedrohung: keine zwei Damen in derselben Reihe, Constraint für die Y-Koordinaten: alle Reihen müssen belegt sein 1,2,...,8

Übrig bleibt als Problem die Ordnung der Liste [1,2,3,4,5,6,7,8]

Idee: Jede Lösung ist eine Permutation die bestimmte Bedingungen erfüllt

(21)

Acht Damen Problem 2

Jede Lösung ist eine Permutation:

solution(S):- permutation([1,2,3,4,5,6,7,8],S), safe(S).

Für safe(S) gilt

(1) S ist die leere Liste

(2) S hat die Struktur [Queen|Others] ist safe wenn Others safe und Queen bedroht niemanden in Others

safe([]).

safe([Queen|Others]):- safe(Others), noattack(Queen,Others).

Jede Lösung ist eine Permutation:

solution(S):- permutation([1,2,3,4,5,6,7,8],S), safe(S).

Für safe(S) gilt

(1) S ist die leere Liste

(2) S hat die Struktur [Queen|Others] ist safe wenn Others safe und Queen bedroht niemanden in Others

safe([]).

safe([Queen|Others]):- safe(Others), noattack(Queen,Others).

(22)

Acht Damen Problem 2

noattack: Schwierigkeit ist, dass im Gegensatz zur ersten Lösung die Positionen nur durch die Y Koordinaten repräsentiert werden. X

Koordinaten sind nicht explizit! Wir müssen noattack modifizieren!

Nach der Ordnung der Damen, implizit bei Aufruf, startet noattack mit einer X-Distanz von 1 zwischen Queen und dem Kopf von

Others. Die noattack Relation braucht ein Drittes Argument um die X-Distanz darzustellen, die bei Abarbeitung von Others je um 1 erhöht wird..

noattack(Queen,Others,Xdist)

→ Start von noattack in der safe Relation: noattack(Queen,Others,1) Reformulieren von noattack: Queen bedroht weder Head noch Tail von Others.

noattack: Schwierigkeit ist, dass im Gegensatz zur ersten Lösung die Positionen nur durch die Y Koordinaten repräsentiert werden. X

Koordinaten sind nicht explizit! Wir müssen noattack modifizieren!

Nach der Ordnung der Damen, implizit bei Aufruf, startet noattack mit einer X-Distanz von 1 zwischen Queen und dem Kopf von

Others. Die noattack Relation braucht ein Drittes Argument um die X-Distanz darzustellen, die bei Abarbeitung von Others je um 1 erhöht wird..

noattack(Queen,Others,Xdist)

→ Start von noattack in der safe Relation: noattack(Queen,Others,1) Reformulieren von noattack: Queen bedroht weder Head noch Tail von Others.

(23)

Acht Damen Problem 2

noattack(_,[],_).

noattack(Y,[Y1|YList],Xdist):- Y1-Y =\= Xdist,

Y-Y1 =\= Xdist, Dist1 is Xdist + 1,

noattack(Y,YList, Dist1).

noattack(_,[],_).

noattack(Y,[Y1|YList],Xdist):- Y1-Y =\= Xdist,

Y-Y1 =\= Xdist, Dist1 is Xdist + 1,

noattack(Y,YList, Dist1).

(24)

Acht Damen Problem 2

solution(Queens) :-

permutation([1,2,3,4,5,6,7,8], Queens), safe(Queens).

safe([]).

safe([Queen|Others]):- safe(Others),noattack(Queen,Others,1).

noattack(_,[],_).

noattack(Y,[Y1|YList],XDist):- Y1-Y =\= Xdist,

Y-Y1 =\= Xdist, Dist1 is Xdist +1,

noattack(Y,YList,Dist1).

solution(Queens) :-

permutation([1,2,3,4,5,6,7,8], Queens), safe(Queens).

safe([]).

safe([Queen|Others]):- safe(Others),noattack(Queen,Others,1).

noattack(_,[],_).

noattack(Y,[Y1|YList],XDist):- Y1-Y =\= Xdist,

Y-Y1 =\= Xdist, Dist1 is Xdist +1,

noattack(Y,YList,Dist1).

(25)

Acht Damen Problem 2

Hilfsprädikat Permutation:

permutation([],[]).

permutation([Head|Tail],PermList):-

permutation(Tail,PermTail), del(Head,PermList,PermTail).

del(Item,[Item|List],List).

del(Item,[First|List],[First|Rest]):- del(Item,List,Rest).

Hilfsprädikat Permutation:

permutation([],[]).

permutation([Head|Tail],PermList):-

permutation(Tail,PermTail), del(Head,PermList,PermTail).

del(Item,[Item|List],List).

del(Item,[First|List],[First|Rest]):- del(Item,List,Rest).

(26)

Ein- Ausgabe in PROLOG

Mit dem Benutzer wird über Ein- und Ausgabeströme kommuniziert.

Vom Eingabestrom wird gelesen, auf den Ausgabestrom geschrieben Dateien, Tastatur und Bildschirm

Der Benutzer liest und schreibt wenn nichts anderes vereinbart ist mit den Standard Ein/Ausgabe Routinen: stdin, stdout in Linux Lesen: read(Term)

Schreiben: write(Term)

Einen Buchstaben mit Code X auf den geöffneten Strom schreiben:

put(X)

Mit dem Benutzer wird über Ein- und Ausgabeströme kommuniziert.

Vom Eingabestrom wird gelesen, auf den Ausgabestrom geschrieben Dateien, Tastatur und Bildschirm

Der Benutzer liest und schreibt wenn nichts anderes vereinbart ist mit den Standard Ein/Ausgabe Routinen: stdin, stdout in Linux Lesen: read(Term)

Schreiben: write(Term)

Einen Buchstaben mit Code X auf den geöffneten Strom schreiben:

put(X)

(27)

Ein- Ausgabe in PROLOG

Buchstaben z.B. 'A' schreiben:

put_char('A').

Buchstaben lesen:

get_char(X).

Code Wert X eines Buchstabens lesen:

get0(X)

Buchstaben z.B. 'A' schreiben:

put_char('A').

Buchstaben lesen:

get_char(X).

Code Wert X eines Buchstabens lesen:

get0(X)

(28)

Ein- Ausgabe in PROLOG

Einfache Ein/Ausgabe read/1 und write/1

read(X): liest die nächste Eingabe vom Keyboard bis '.' eingegeben wird. Eingabe wird mit X unifiziert. Eingabe muss gültiger

Prologausdruck sein, ohne whitespace.

?- read(X).

|: [1,2,3]. X= [1,2,3] yes.

?-X='Hallo', write(X).

Hallo.

X='Hallo'

nl: schreibt ein Newline auf den Outputstrom tabl(X): schreibt X Tabs auf das Terminal

Einfache Ein/Ausgabe read/1 und write/1

read(X): liest die nächste Eingabe vom Keyboard bis '.' eingegeben wird. Eingabe wird mit X unifiziert. Eingabe muss gültiger

Prologausdruck sein, ohne whitespace.

?- read(X).

|: [1,2,3]. X= [1,2,3] yes.

?-X='Hallo', write(X).

Hallo.

X='Hallo'

nl: schreibt ein Newline auf den Outputstrom tabl(X): schreibt X Tabs auf das Terminal

(29)

Ein- Ausgabe in PROLOG

Zeichenorientiertes Einlesen/Ausgeben

?- get_char(X)

|: z.

X = z

?- X = 'z', put_char(X).

z X=z

X='Test', put_char(X). Error, character expected.

?- get(X).

|: a.

X=97

?- put(97).

a yes.

Zeichenorientiertes Einlesen/Ausgeben

?- get_char(X)

|: z.

X = z

?- X = 'z', put_char(X).

z X=z

X='Test', put_char(X). Error, character expected.

?- get(X).

|: a.

X=97

?- put(97).

a yes.

(30)

Ein- Ausgabe in PROLOG

Einlesen einer Zeile:

Um eine beliebige Zeile einzulesen muss man zeichenweise einlesen bis newline auftritt: lese(X) liest von der Tastatur und steckt die

Zeichen in eine Liste

lese(Zeile) :- lese(Zeile,[ ]).

lese(Zeile,Last):- get_char(C),restliche_zeile(Zeile,C,Last).

restliche_zeile(Zeile,'⧵n',Last):- reverse(Last,Zeile),!.

restliche_zeile(Zeile,C,Last):- lese(Zeile,[C|Last]).

Einlesen einer Zeile:

Um eine beliebige Zeile einzulesen muss man zeichenweise einlesen bis newline auftritt: lese(X) liest von der Tastatur und steckt die

Zeichen in eine Liste

lese(Zeile) :- lese(Zeile,[ ]).

lese(Zeile,Last):- get_char(C),restliche_zeile(Zeile,C,Last).

restliche_zeile(Zeile,'⧵n',Last):- reverse(Last,Zeile),!.

restliche_zeile(Zeile,C,Last):- lese(Zeile,[C|Last]).

(31)

Ein- Ausgabe in PROLOG

Lesen von Dateien:

von einer Datei lesen open/3

lese_datei :- open('indatei',read,IN), datei_lesen(IN).

Utf-8 Datei lesen open/4

lese_datei :- open('indatei',read,IN,[encoding(utf8)]), datei_lesen(IN).

Lesen von Dateien:

von einer Datei lesen open/3

lese_datei :- open('indatei',read,IN), datei_lesen(IN).

Utf-8 Datei lesen open/4

lese_datei :- open('indatei',read,IN,[encoding(utf8)]), datei_lesen(IN).

(32)

Ein- Ausgabe in PROLOG

Schreiben auf Dateien:

auf Datei schreiben open/3

schreibe_datei :- open('outdatei',write,OUT), datei_schreiben(OUT).

Utf-8 Datei schreiben open/4

schreibe_datei :- open('outdatei',write,OUT,[encoding(utf8)]), datei_schreiben(OUT).

Schreiben auf Dateien:

auf Datei schreiben open/3

schreibe_datei :- open('outdatei',write,OUT), datei_schreiben(OUT).

Utf-8 Datei schreiben open/4

schreibe_datei :- open('outdatei',write,OUT,[encoding(utf8)]), datei_schreiben(OUT).

(33)

Ein- Ausgabe in PROLOG

set_input: Eingabestrom umleiten

/* Datei Lesen, danach Strom wieder zurück */

lese_datei(Name):-

open(Name,read,X,[encoding(utf8)]),

current_input(USER), set_input(X), schreiben_und_ausgeben, set_input(USER),

close(X).

/*schreibfunktion*/

schreiben_und_ausgeben :- get_char(C), C \= end_of_file, write(C), schreiben_und_ausgeben.

set_input: Eingabestrom umleiten

/* Datei Lesen, danach Strom wieder zurück */

lese_datei(Name):-

open(Name,read,X,[encoding(utf8)]),

current_input(USER), set_input(X), schreiben_und_ausgeben, set_input(USER),

close(X).

/*schreibfunktion*/

schreiben_und_ausgeben :- get_char(C), C \= end_of_file, write(C), schreiben_und_ausgeben.

(34)

Ein- Ausgabe in PROLOG

set_ouput: Ausgabestrom umleiten

/* Auf Datei Schreiben, danach Strom wieder zurück */

schreibe_datei(Name):-

open(Name,write,X,[encoding(utf8)]),

current_output(TERMINAL), set_output(X), in_Datei_schreiben, set_output(TERMINAL),

close(X).

/*lesefunktion*/

in_Datei_schreiben :- get_char(C), C \= '\n', write(C), in_Datei_schreiben.

set_ouput: Ausgabestrom umleiten

/* Auf Datei Schreiben, danach Strom wieder zurück */

schreibe_datei(Name):-

open(Name,write,X,[encoding(utf8)]),

current_output(TERMINAL), set_output(X), in_Datei_schreiben, set_output(TERMINAL),

close(X).

/*lesefunktion*/

in_Datei_schreiben :- get_char(C), C \= '\n', write(C), in_Datei_schreiben.

(35)

Hausaufgabe

Acht Damen Problem nochmals anschauen und verstehen

Tokenizer im Leisskript anschauen, wird nächstes mal besprochen Acht Damen Problem nochmals anschauen und verstehen

Tokenizer im Leisskript anschauen, wird nächstes mal besprochen

Referenzen

ÄHNLICHE DOKUMENTE

It signals the central control or the processor (depending on the Medium Data Processing System) to au- tomatically translate EBCDIC to BCL informa- tion as it is

signal on this line indicates that the external equipment has accepted the word of information and will turn off the output data ready signal at the com- puter; this causes

The Data Read is delayed from Data Write and may be shifted into an external register by using the negative-going edge of the Data Read Shift Clocks or the

With a parallel printer port, three serial ports (one standard and two optional), and a game port, the Magic I/O packs more features and connectors on a true

In determining the priority of control units which operate multiple devices with different priority rules (for example, a 2821 that attaches both class 2 and class

The selector light pen feature supplies a hand-held, pen-like device that permits an operator of a display station to select fields of data from the display screen

Punching operations, speeds, internal controls, punching in data mode 2, and all other features related to punching are the same as those of the 1442 Card Read Punch Model Nl,

Input port lines and output port lines are accessed at 16-pin DIP sockets on the card.. A reset line is