Wissenschaft
Copyright © 2024 Jiri Kriz, www.nosco.ch

6Eingebaute Prädikate

Lösungen

6.1Prädikate höherer Ordnung

Implementieren Sie die Prädikate:

abolish( F, A)
/* löscht alle Prädikate mit Hauptfunktor F und Arität A */ 

filter( P, X, Y)
/* filtriert Liste X in Y gemäss Prädikat P */

Beispiele:

pos( X) :- X > 0.
neg( X) :- X < 0.
?- filter( pos, [ 1, -1, 2, -2], Y).  ⇒  [ 1, 2]
?- filter( neg, [ 1, -1, 2, -2], Y).  ⇒  Y = [ -1, -2]

Lösung 6.1

6.2Memorisieren

Fibonacci Zahlen F(N) können wie folgt berechnet werden:

fibo( 1, 1).
fibo( 2, 1).
fibo( N, F) :- 
    N > 2, 
    N1 is N-1, 
    N2 is N-2,
    fibo( N1, F1),  
    fibo( N2, F2), 
    F is F1 + F2.

Dies ist extrem ineffizient, da die Zwischenresultate mehrfach berechnet werden. Beheben Sie diesen Mangel, indem Sie die Zwischenresultate mit assert speichern.

Bemerkung: Eine elegantere Methode ist die Iteration (durch Rekursion implementiert). Dazu werden zwei zusätzliche Argumente für die Werte F(N-1) und F(N-2) eingeführt.

Lösung 6.2

6.3Interaktion mit dem Benützer

Schreiben Sie ein Programm für interaktive Abfragen nach der Distanz zwischen zwei Städten:

d( Stadt1, Stadt2).

Gehen Sie von einer Datenbank mit Distanzen zwischen Städten aus, z.B. :

distanz( zuerich, baden, 22).
distanz( baden, basel, 83).
...

Berücksichtigen Sie die Symmetrie. Wenn eine Distanz nicht bekannt ist, sollte das System nicht mit NO antworten, sondern die Distanz vom Benutzer verlangen und sie sich merken.

So könnte eine Session aussehen

?- d( zuerich, baden) 
 ⇒  Distanz zwischen zuerich und baden ist 22.

?- d( zuerich, bern).
 ⇒  Ist mir leider unbekannt. Bitte sagen Sie sie mir: 110
Danke. Ich bestätige: Distanz zwischen zuerich und bern ist 110.

?- d( zuerich, bern).
 ⇒  Distanz zwischen zuerich und bern ist 110.

Sie können diese Interaktion weiter benutzerfreundlich ausbauen.

Lösung 6.3

6.4Zähler

Implementieren Sie das Konzept des Zählers. Ein Zähler hat einen Namen und einen Wert, und wird mit den folgenden Operationen manipuliert:

init( C, V)
/* Zähler C wird installiert und auf Wert V gesetzt */

get( C, V)
/* Unifiziert den Wert des Zählers C mit V */

inc( C)
/* Erhöht den Zähler C um 1. */

dec( C) 
/* Erniedrigt den Zähler C um 1. */

del( C)
/* Der Zähler C wird aus der Datenbank entfernt */

Beispiel.:

?- init( z, 0), inc( z), inc( z), get( z, V). 
 ⇒  V = 2

Lösung 6.4

6.5Umwandlung von Fakten in Listenargumente

Implementieren Sie bagof und setof. Das Prädikat bagof( X, P, B) berechnet B ("bag") als eine Liste solcher Elemente X, für die P(X) erfüllt ist. Beispiel:

a(1).
a(2).
a(2).
a(3).
?- bagof ( X, a(X), B).  ⇒  B = [ 1, 2, 2, 3]
?- bagof( b(c,X), a(X), B).  ⇒  B = [ b(c,1), b(c,2), b(c,2), b(c,3)]
?- bagof( X, (a(X), X>2), B).  ⇒  B = [ 3]
In der Liste B können gleiche Elemente mehrfach vorkommen und die Reihenfolge spielt keine Rolle. Das Prädikat setof(X, P, S) ist ähnlich zu bagof, nur dass die Liste S eine echte Menge ohne mehrfache Elemente ist. Asserdem ist die Liste S gemäss der Relation < sortiert.

Lösung 6.5