Computerlinguistik II, WS 2007/08 Aufgabenblatt 3 -------------------------------------------------------------- Ausgabe: Sa, 10.11.07 Abgabe: Do, 15.11.07 Aufgabe 4 --------- Schreiben sie mit Hilfe des Prolog-Prädikats functor(+Term,?Prädikatsname,?Stelligkeit) und der Termzusammensetzung durch =../2 ein Prädikat translate(+Term,-NeuerTerm), das die in Term verwendeten Funktionsnamen so ändert, daß die Stelligkeit an den Namen angefügt wird, wenn sie mindestens 2 ist. Beispiel: ?- translate(f(a,g(b),f(a,b)),f3(a,g(b),f2(a,b))). Punkte 5 Aufgabe 5 (Verwendung von Modulen) --------- Man kann Module verwenden, um nur die für den Anwender gedachten Prädikate sichtbar zu machen und Hilfsprädikate und die Darstellung der Daten zu verbergen (damit man die noch verbessern kann). Etwa: Eine Multimenge ist eine "Menge", in der ein Element mehrfach vorkommen kann. Man kann sie auf verschiedene Weisen darstellen, z.B. 1. Durch eine Liste [(,),...], sodaß [(a,3),(b,6)] besagt, daß a 3mal und b 6mal in der Multimenge vorkommt. 2. Durch eine Liste [Element1,Element2,...], sodaß in der Multimenge [a,b,b,a,b,b,b,a,b] das Element a 3mal und b 6mal vorkommt. Die für die Anwender gedachten Prädikate stehen in einem (Interface-) Modul und sind nur zusammen mit einem Implementierungsmodul (s.u.) benutzbar: % ----------------- Schnittstelle für Multimengen -------------------- :- module(multiset,[newset/1,insert/2,remove/2,member/3]). % Ein Implementierungsmodul ms muß geladen sein/werden! :- dynamic set/1. % Merkt sich die Namen vorhandener Multimengen. newset(M) :- % Legt eine leere Multimenge mit Namen M an. (set(M) -> true ; assert(set(M)), ms:newset(M)). ^^^^ % KORRIGIEREN: true durch ms:newset(M) ersetzen, damit der % Implementierungsmodul informiert wird, die Menge % zu leeren. % Danke an Angelika Berwein! insert(E,M) :- % Fügt E einmal in die Multimenge namens M ein. (set(M) -> ms:insert(E,M) ; error(M), fail). remove(E,M) :- % Entfernt E einmal aus der Multimenge namens M. (set(M) -> ms:remove(E,M) ; error(M), fail). member(E,M,N) :- % Nennt die Zahl N der Vorkommen von E in M. (set(M) -> ms:member(E,M,N) ; error(M), fail). error(M) :- format('\nEine Menge ``~w'' ist nicht bekannt.\n',M). % -------------------------------------------------------------------- Bem. Das Hilfsprädikat set/1 wird nicht exportiert, sodaß ein Anwender nicht weiß, wieviele Mengen angelegt wurden; auch error/1 wird nicht an den Anwender (user) exportiert. Die eigentliche Definition der Prädikate soll im Modul 'ms' erfolgen, der nichts exportiert. Je nach der Darstellungsweise werden dabei manche Definitionen einfach, andere schwieriger. a) Wählen Sie eine der unter 1) und 2) angegebenen Darstellungen für Multimengen und implementieren Sie dafür die Prädikate newset/1, insert/2, remove/2, member/3 in einem (Implementierungs-) Modul % -------------- Implementierung von Multimengen -------------------- :- module(ms,[]). :- dynamic multiset/2. % Merkt sich namentlich bekannte Multimengen. newset(M) :- ... % Punkte 2 insert(E,M) :- ... % Punkte 2 remove(E,M) :- ... % Punkte 2 member(E,M,N) :- ... % Punkte 2 % Hilfsfunktionen, die die mit M benannte Liste L manipulieren: ... % ins(+Elem,+Liste,-Liste). % Punkte 2 % rem(+Elem,+Liste,-Liste). % Punkte 2 % mem(+Elem,+Liste,-Number). % Punkte 2 % ------------------------------------------------------------------ Durch newset(+) soll die ggf. bestehende Multimenge (*) (*) multiset(,). beseitigt und eine leere Multimenge dieses Namens, also: multiset(,[]). angelegt werden (mit retract/1 und assert/1, siehe Prolog-Handbuch). Analog für die durch insert/2 und remove/2 zu ändernden Listen. b) Laden Sie die beiden Dateien und geben Sie an, was die folgenden Anfragen liefern: ?- newset(ma), newset(mb), insert(x,ma), insert(y,mb), insert(y,ma), member(x,ma,XA), member(x,mb,XB), member(y,ma,YA), member(y,mb,YB). XA = XB = YA = YB = Machen Sie jetzt noch ?- newset(ma), insert(x,ma), insert(x,mb), member(x,ma,XA), member(x,mb,XB). XA = XB = c) Stellen Sie sich vor, jemand hat für beide Darstellungsweisen 1),2) von oben je einen Implementierungsmodul module(ms1,[]) und module(ms2,[]) geschrieben (vielleicht noch weitere mit anderen Modulnamen) und möchte bei einer Anwendung die Wahl durch ein Faktum implementierung(multiset,-Modulname) steuern, das nicht in den Dateien festgelegt wird, sondern durch die Benutzereingabe. c1) Wie muß man die Prädikate im Schnittstellenmodul ändern, damit nicht der Modulname 'ms' wie bei insert(E,M) :- (set(M) -> ms:insert(E,M) ; error(M), fail). verwendet wird, sondern der in implementierung/2 angegebene? Punkte 3 c2) Wie kann der Benutzer (mit retract/1 und assert/1) interaktiv zwischen den Darstellungsweisen wählen? ?- ... Punkte 2 Bem.: Die Multimengen in verschiedenen Implementationsmodulen haben nichts miteinander zu tun, auch wenn sie gleiche Namen haben.