# Problem mit Prolog



## sabrina21 (19. April 2009)

Hallo zusammen, ich habe ein großes Problem in Prolog, ich arbeite an einem Prologprogramm, dass bei der Eingabe eines schwachen Verbs, die Vergangenheitsform ausgibt, zur Erinnerung schwache Verben; das sind Verben die ihre Stammform in der Vergangenheitsform behalten, z.B. 

liebte -> lieb(te) im Gegensatz zu starken Verben, die ihren Stamm verändern, z.B. 

schlafen -> schlief.

Mein Ansatz war dabei folgender 
	
	
	



```
%präterialform([spielen], Echo). ergibt die präterialform!
map(abbauen, abbaute).
map(bauen, baute).
map(besiegen, besiegte).
map(führen, führte).
map(glauben, glaubte).
map(holen, holte).
map(intervenieren, intervenierte).
map(jauchzen, jauchzte). 
map(kaufen, kaufte).
map(klettern, kletterte).
map(loben, lobte).
map(musizieren, musizierte).
map(nominieren, nominierte).
map(operieren, operierte).
map(planen, plante).
map(richten, richtete).
map(saugen, saugte).
map(siegen, siegte).
map(spielen, spielte).
map(trauen, traute).
map(unifizieren, unifizierte.)
map(verschachern, verschacherte).
map(wünschen, wünschte).
map(X, X).
präterialform([], []).
präterialform([E|Rest], [AbbE|AbbRest]) :-
  map(E, AbbE),
  präterialform(Rest, AbbRest).
```

Hierbei müsste man jetzt z.B. folgende Eingabe machen: "präterialform([spielen], Echo)." um die entsprechende Vergangenheitsform zu erhalten. Jetzt will ich das Programm aber mit Hilfe des Prädikats "read" ein paar built-in-Prädikaten und auch atom_chars (Listenverarbeitung) soweit verändern, dass es die Vergangenheitsform selbstständig bildet, ohne wie in meinem Programm auf ein festen Bestand an Wörtern zurück zu greifen. Wüsste jemand ungefähr, wie man das am besten Anfängt? Leider drehe ich mich dabei ganz schön im Kreis.

Alles Liebe 

Sabrina


----------



## deepthroat (20. April 2009)

Hi.

Kennst du schon das atom_concat Prädikat? 

Und bitte wähle einen aussagekräftigen Titel, immer der gleiche ist ja auch langweilig...

Gruß


----------



## sabrina21 (21. April 2009)

Hi Deepthroat und vielen Dank für Deine Hilfe,
also das atom_concat Prädikat kannte ich noch nicht. Ich habe mich inzwischen darüber ein wenig informiert und verschiedene Ansätze gefunden, aber leider keinen, der dazu führt, dass eine Eingabe, z.B. "lieben" in "liebte" ausgegeben wird. 

% atom_concat(?Atom1, ?Atom2, ?Atom3)
% read_term(-Term, +Options)
read_term(-Term...

Hast Du evtl. noch einen weiteren Befehl, den man dabei berücksichtigen muss?

Lieben Gruß

Sabrina


----------



## deepthroat (21. April 2009)

sabrina21 hat gesagt.:


> Hi Deepthroat und vielen Dank für Deine Hilfe,
> also das atom_concat Prädikat kannte ich noch nicht. Ich habe mich inzwischen darüber ein wenig informiert und verschiedene Ansätze gefunden, aber leider keinen, der dazu führt, dass eine Eingabe, z.B. "lieben" in "liebte" ausgegeben wird.
> 
> % atom_concat(?Atom1, ?Atom2, ?Atom3)
> ...


Nein, mehr braucht man dafür eigentlich nicht. Aber zeig doch mal deinen Code.

Gruß


----------



## sabrina21 (21. April 2009)

Hallo nochmal,
da ich diese atom_csoncat - Befehle bis jetzt noch nicht ans Laufen bekommen habe, kann ich leider auch keinen Code vorzeigen.
Mir ist überhaupt nicht klar, wo das Problem liegt, bzw. warum diese Prädikate nicht arbeiten. 
Eigentlich soll doch eine Eingabe, z.B. "liebe" eingelesen werden und als "liebte" ausgegeben werden, ich habe als Read-Befehl


```
read_term(-Term, +Options)
```

und wollte erst als "+Options" 


```
atom_concat(?Atom1, ?Atom2, ?Atom3)
```

versuchen, doch die Optionen scheinen begrenzt zu sein auf bestimmte Prädikate, leider steige ich insgesamt einfach nicht wirklich durch, es soll zwar ansich eine recht einfache Aufgabenstellung sein, dennoch scheine ich an irgendetwas grundlegendes nicht gedacht zu haben.

Alles Liebe

Sabrina


----------



## deepthroat (21. April 2009)

sabrina21 hat gesagt.:


> Hallo nochmal,
> da ich diese atom_csoncat - Befehle bis jetzt noch nicht ans Laufen bekommen habe, kann ich leider auch keinen Code vorzeigen.
> Mir ist überhaupt nicht klar, wo das Problem liegt, bzw. warum diese Prädikate nicht arbeiten.
> Eigentlich soll doch eine Eingabe, z.B. "liebe" eingelesen werden und als "liebte" ausgegeben werden, ich habe als Read-Befehl
> ...


Du meinst du hast versucht atom_concat(...) dort anstelle der +Options einzusetzen? Das geht selbstverständlich nicht. Das funktioniert aber eigentlich nie (außer bei Prädikaten die andere Prädikate als Argument erwarten). 

Wenn du read_term verwenden willst, mußt du auch Optionen angeben. Diese sind allerdings exakt festgelegt. Oder du übergibst eine leere Liste, dann kannst du allerdings auch gleich read/1 nehmen.

Warum schreibst du nicht erstmal das map/2 Prädikat so das es allgemein funktioniert? Das ist doch erstmal die Hauptarbeit. Und dann solltest du evtl. nochmal die genaue Aufgabenstellung hier reinstellen...

Gruß


----------



## sabrina21 (21. April 2009)

Hi dt ;-)

Ja ich hatte ja schon befürchtet, dass der Ansatz daneben ist. Also zur Aufgabenstellung selber, es geht wie gesagt darum ein Prädikat zu schreiben, dass von einem beliebigen schwachen Verb, die Vergangenheitsform bilden kann, also z.B. lieben -> liebte, arbeiten -> arbeitete usw. ich brauche also read Befehle, Befehle mit denen ich Listen verarbeiten kann z.B. atom_chars und weitere Buil-inPrädikate. Ich schaue mir mal dieses map/2 Prädikat genau an.

Gruß
S.


----------



## deepthroat (21. April 2009)

Hi.





sabrina21 hat gesagt.:


> Also zur Aufgabenstellung selber, es geht wie gesagt darum ein Prädikat zu schreiben, dass von einem beliebigen schwachen Verb, die Vergangenheitsform bilden kann, also z.B. lieben -> liebte, arbeiten -> arbeitete usw.


OK. Das ist einfach.


sabrina21 hat gesagt.:


> ich brauche also read Befehle, Befehle mit denen ich Listen verarbeiten kann z.B. atom_chars und weitere Buil-inPrädikate.


Warum? Wie kommst du darauf? Steht das so in der Aufgabenstellung?

Was für ein Prologsystem verwendest du denn eigentlich? Die interaktive Prologsitzung nimmt dir doch das read schon ab? Reicht es denn nicht wenn du "map(lieben, E)." eingibst, das dann das Prologsystem "E = liebte" ausgibt?

Gruß


----------



## sabrina21 (21. April 2009)

Hi dt,

also ich verwende die SWI Prolog Version 5.6.64 und wenn ich "map(lieben, E)" eingebe, dann kommt "Error: toplevel: undefinedprocedure map/2 (DWIM could not correct goal). Allerdings lese ich gerade erst, wie dieses map-Prädikat überhaupt funktioniert.

"_ich brauche also read Befehle, Befehle mit denen ich Listen verarbeiten kann z.B. atom_chars und weitere Buil-inPrädikate._"

Naja das ist nur ein Hinweis zu der Aufgabenstellung, der nicht zwingend umgesetzt werden muss, wenn diese Map-Variante gehen würde, könnte die es ja auch tun. vorausgesetzt WENN 

Greetz 

;-)


----------



## sabrina21 (21. April 2009)

In den beiden Büchern zur Einführung in Prolog, mit denen ich arbeite, kann ich leider nichts zu diesem Map-Prädikat finden, falls Du eine Onlinequelle hast, wäre es nett, wenn Du diese ggf. verlinken könntest, denn auch wenn ich "map/2 Prolog" google werde ich nicht fündig.

Gruß


----------



## deepthroat (21. April 2009)

Hi Sabrina,





sabrina21 hat gesagt.:


> also ich verwende die SWI Prolog Version 5.6.64 und wenn ich "map(lieben, E)" eingebe, dann kommt "Error: toplevel: undefinedprocedure map/2 (DWIM could not correct goal). Allerdings lese ich gerade erst, wie dieses map-Prädikat überhaupt funktioniert.


Also das map Prädikat hast du doch ins Spiel gebracht bei deinem Beispiel. Wie auch immer du es nennst, du müßtest ein Prädikat schreiben welches diese Übersetzung macht. Die Übersetzung der Präsens in die Präteritumform an sich ist trivial - das sind ja nur 2 Regeln; die sind dir klar, oder?! ;-)

Gruß


----------



## sabrina21 (21. April 2009)

Achso ich dachte, Du meintest man könnte dieses map-Prädikat problemnah noch anders einsetzen, als ich es bereits getan hatte. 
Das Problem an meiner Lösung ist aber, das ich ja selber den Lexikonbestand an Wörtern angegeben habe (von A wie abbauben, bis W wie wünschen), das heisst meine Lösung funktioniert ja lediglich mit den Wörtern, die ich selber in den bestand eingefügt habe, gesucht ist jedoch ein Prädikat, was diese Aufgabe praktisch on-the-fly erledigt ^^ also was einen generellen Umwandlungsansatz enthält ohne einfach eine vorgefertigte Liste wieder auszugeben. Also es muss ein Wort im Präsens eingelesen werden, dass umgehend in die Vergangenheitsform umgewandelt wird und dann sofort wieder ausgegeben wird, anders als bei meinem Ansatz, der das ja nur für die Wörter kann, die ich eingefügt habe.
Sorry das ich mich da etwas blöd ausgedrückt hatte. Diese zwei trivialen Regeln die Du ansprichst sind mir ansich nicht unbedingt klar, bzw. weiss ich nicht was Du meinst.

Gruß

Sabrina


----------



## deepthroat (21. April 2009)

sabrina21 hat gesagt.:


> Achso ich dachte, Du meintest man könnte dieses map-Prädikat problemnah noch anders einsetzen, als ich es bereits getan hatte.
> Das Problem an meiner Lösung ist aber, das ich ja selber den Lexikonbestand an Wörtern angegeben habe (von A wie abbauben, bis W wie wünschen), das heisst meine Lösung funktioniert ja lediglich mit den Wörtern, die ich selber in den bestand eingefügt habe, gesucht ist jedoch ein Prädikat, was diese Aufgabe praktisch on-the-fly erledigt ^^ also was einen generellen Umwandlungsansatz enthält ohne einfach eine vorgefertigte Liste wieder auszugeben.


Ja, das war mir von Anfang an klar. Ich hätte ausgehend von deinem Beispielcode dein map/2 Prädikat einfach dahingehend geändert.


sabrina21 hat gesagt.:


> Diese zwei trivialen Regeln die Du ansprichst sind mir ansich nicht unbedingt klar, bzw. weiss ich nicht was Du meinst.


Na, wie willst du denn grundsätzlich die Übersetzung machen? Nach welchen Regeln erfolgt denn die Übersetzung? Das mußt du dir schon überlegen bevor du überhaupt anfängst ein Programm dafür zu schreiben.

Gruß


----------



## sabrina21 (21. April 2009)

Grundsätzlich möchte ich ein Wort (schwaches Verb) mit einem Read-Befehl einlesen, dieses Wort dann im günstigsten Fall in seine Silben zerlegen und dann die letzte Silbe einfach mit der Silbe für die Vergangenheitsform ersetzen, also "-te".

z.B.
Eingabe :   lieben

Zerlegung in:

lieb-en              

Ersetzung von "-en" in "-te"

Vielleicht kann man die Silben ja in Einer Liste erfassen, wo im Head der Stamm steht, z.B. "lieb" und im Tail die Endung, der Tail müsste dann wiederum mit der Endung "-te" ersetzt werden, so dachte ich mir das Ganze.


----------



## deepthroat (21. April 2009)

sabrina21 hat gesagt.:


> Grundsätzlich möchte ich ein Wort (schwaches Verb) mit einem Read-Befehl einlesen, dieses Wort dann im günstigsten Fall in seine Silben zerlegen


Aha. Und wie? ;-]


sabrina21 hat gesagt.:


> und dann die letzte Silbe einfach mit der Silbe für die Vergangenheitsform ersetzen, also "-te".
> 
> z.B.
> Eingabe :   lieben
> ...


Was ist mit "erobern" o.ä.?


sabrina21 hat gesagt.:


> Vielleicht kann man die Silben ja in Einer Liste erfassen, wo im Head der Stamm steht, z.B. "lieb" und im Tail die Endung, der Tail müsste dann wiederum mit der Endung "-te" ersetzt werden, so dachte ich mir das Ganze.


Ja, warum eine Liste? Wie könnte da das atom_concat/3 Prädikat nützlich sein? Ist es notwendig wirklich das Wort in seine Silben zu trennen? (evtl. reicht auch die Endung?)

Gruß


----------



## sabrina21 (22. April 2009)

Hi DT ;-)

Danke nochmal für Deine ganze Hilfe, also ich seh schon, dass atom_concat Prädikat scheint der Schlüssel zu sein, ich werde mal versuchen mehr über dieses Prädikat herauszubekommen in den Einführungsbüchern, die ich hier habe, ist das Prädikat leider nur rudimentär beschrieben, aber das wird schon, das Netz dürfte da noch etwas zu haben.
Ich denke aber, dass ich mein ganzes Mapkonzept ja dann weitesgehend über Board werfen kann.
Anyway ich melde mich wieder und berichte über meine Fortschritte.

Alles Liebe

Sabrina


----------



## deepthroat (22. April 2009)

Hi Sabrina!

Bevor du jetzt einen Haufen Dokumenation liest:

Das atom_concat macht ja im Grunde nichts anders als append/3 für Listen, nur das es eben mit Atomen funktioniert. Als Tipp:

```
atom_concat(Stamm, en, spielen).
```

Und bspw. mit read:

```
?- read(Wort), atom_concat(Stamm, en, Wort).
|: spielen.
Wort = spielen,
Stamm = spiel.
```
Gruß


----------



## sabrina21 (22. April 2009)

Ich hatte erst an sowas gedacht:


```
atom_concat('lieben', ' liebte', PräsensPräteritum).
```

aber das ist ja echt unkreativ.


----------



## sabrina21 (22. April 2009)

Hey habe da jetzt glaube ich etwas gefunden:

atom_concat(Stamm, en, spielen), atom_concat(Stamm, te, Präterialform).

Das sollte das Problem zumindest weitesgehend lösen. Leider kann man damit keine Verben, wie "erobern" ableiten, es seidenn mithilfe von folgendem Befehl:

atom_concat(Stamm, rn, erobern), atom_concat(Stamm, rte, Präterialform).

Noch Anmerkungen?

Lieben Gruß

S.


----------



## deepthroat (22. April 2009)

sabrina21 hat gesagt.:


> Hey habe da jetzt glaube ich etwas gefunden:
> 
> atom_concat(Stamm, en, spielen), atom_concat(Stamm, te, Präterialform).
> 
> ...


Das sind genau die 2 Regeln von den ich gesprochen hatte. Die kann man jetzt prima zu einem Prädikat zusammenführen, wobei natürlich das Wort durch eine Variable ersetzt werden muss.

Gruß


----------

