[Progra] Prolog Listen

[Progra] Programmierung
[DSAL] Datenstrukturen und Algorithmen
[SWT] Softwaretechnik
[DB] Datenbanken und Informationssysteme

Prolog Listen

Beitragvon mr.nice » 06.02.08 19:15

Hi

ich habe ein Problem mit folgendem Code:
Code: Alles auswählen
copy([], Copy).
copy([X|T],[]) :- copy(T, [x]).
copy([X|T],Copy) :- copy(T, [X|Copy]).


wenn ich jetzt zB:
Code: Alles auswählen
?- copy([1,2,3,4],X).


frage, krieg ich die leere Liste zurück und keine Kopie!!

Was mach ich falsch?
mr.nice
 
Beiträge: 43
Registriert: 07.01.08 18:34

Beitragvon Coolcat » 06.02.08 19:27

Code: Alles auswählen
% Die Kopie der leeren Liste ist die leere Liste
copy([], []).

% Die erste Liste ist eine Kopie der zweiten, wenn T eine Kopie von S ist und das erste Element der Listen gleich ist.
copy([X|T],[X|S]) :- copy(T, S).


Übrigens könnte man das auch einfach als
Code: Alles auswählen
copy(X,X).

definieren, wäre einfacher ;)
My software never has bugs. It just develops random features.
Benutzeravatar
Coolcat
Promoter
 
Beiträge: 2574
Registriert: 28.11.05 21:26
Wohnort: Kohlscheid / Düsseldorf
Studiengang: Informatik (Dipl.)
Studiert seit: fertig
Anwendungsfach: BWL

Beitragvon proxylittle » 06.02.08 23:21

Code: Alles auswählen
copy([X|T],[]) :- copy(T, [x]).


ist x klein??? außerdem ist X ja der header... also nur ein Wert und keine Liste mehr. reicht dann nicht(?):
Code: Alles auswählen
copy(T,X).
Code: Alles auswählen
<!--   No Comment   -->
Benutzeravatar
proxylittle
 
Beiträge: 106
Registriert: 28.01.08 15:38
Wohnort: Aachen (Köln Wochenende)

Beitragvon mr.nice » 07.02.08 02:21

ja mit
Code: Alles auswählen
copy(X,X).

komm ich leider nicht allzuweit, aber danke ;)

ich stehe eher vor so einem problem:

Code: Alles auswählen

fromIndex(Start,AS,BS) :- fromIndex2(Start,AS,BS,false).

fromIndex2(Start, [], [], X).
fromIndex2(Start, [X|T], [X|[]], false) :- gleich(Start,X),
                                                           fromIndex2(Start, T, S, true).
fromIndex2(Start, [X|T], [X|S], true) :- fromIndex2(Start, T, S, true).
fromIndex2(Start, [X|T], BS, false) :- fromIndex2(Start, T, BS, false).


Anfrage:
Code: Alles auswählen
?- fromIndex(3,[1,2,3,4,5],Y) .

Y = [3]

Yes




Leider spukt er mir immer nur die Zahl aus, die er gefunden hat, den Rest lässt er aber weg... das mit dem false und true ist sicher unsinnig, aber ich habs anders nicht hinbekommen, dass er überhaupt was macht.

Außerdem wunders mich, dass er überhaupt was auspuckt, weil in der Zeile, in der gleich(Start,X) steht, wird ja für die gespeicherte, neue Liste ein S übergeben, was es garnicht gibt...(übergibt der bei sowas eigentlich die leere Liste, manchmal steht da son [1,2,3,G3...] anstatt nix??)
mr.nice
 
Beiträge: 43
Registriert: 07.01.08 18:34

Beitragvon mr.nice » 07.02.08 02:46

....
mr.nice
 
Beiträge: 43
Registriert: 07.01.08 18:34

Beitragvon partisan » 07.02.08 14:05

Was soll denn die Funktion "fromIndex" genau tun?
Benutzeravatar
partisan
 
Beiträge: 88
Registriert: 05.09.06 17:48
Wohnort: Aachen
Studiengang: Informatik (Dipl.)
Studiert seit: SS 07
Anwendungsfach: Chemie

Beitragvon HE » 07.02.08 14:52

mr.nice hat geschrieben:jich stehe eher vor so einem problem:

Code: Alles auswählen

fromIndex(Start,AS,BS) :- fromIndex2(Start,AS,BS,false).

fromIndex2(Start, [], [], X).
fromIndex2(Start, [X|T], [X|[]], false) :- gleich(Start,X),
                                                           fromIndex2(Start, T, S, true).
fromIndex2(Start, [X|T], [X|S], true) :- fromIndex2(Start, T, S, true).
fromIndex2(Start, [X|T], BS, false) :- fromIndex2(Start, T, BS, false).




Ich gehe mal davon aus, dass du alle Listen-Elemente ab Start haben willst. Dann wäre das hier eine bessere Möglichkeit:

Code: Alles auswählen
fromIndex(Start,AS,BS) :- fromIndex(Start,AS,BS,false).
fromIndex(Start, [], [], X).
fromIndex(Start, [X|T], [X|S], false) :- Start = X, fromIndex(Start, T, S, true).
fromIndex(Start, [X|T], S, false) :- Start \= X, fromIndex(Start, T, S, false).
fromIndex(Start, [X|T], [X|S], true) :- fromIndex(Start, T, S, true).


Wenn du aber alle Elemente ab dem so-und-sovielten Element haben willst (was zu Index besser paßt), wäre das hier eine Lösung:

Code: Alles auswählen
fromIndexM(1,Liste,Liste).
fromIndexM(N,[_|Liste],Res) :- N > 1, M is N-1, fromIndexM(M,Liste,Res).
Benutzeravatar
HE
 
Beiträge: 453
Registriert: 09.03.07 12:20
Wohnort: Aachen
Studiert seit: WS 06/07
Anwendungsfach: Mathe

Beitragvon proxylittle » 07.02.08 15:03

Leider spukt er mir immer nur die Zahl aus, die er gefunden hat, den Rest lässt er aber weg...


Klar, denn nur dann ist deine Regel wahr wenn folgendes zutrifft:
Code: Alles auswählen
fromIndex2(Start, [X|T], [X|[]], false) :- gleich(Start,X),fromIndex2(Start, T, S, true).
Sagen wir gleich(Start,X) ist wahr... also:
Code: Alles auswählen
fromIndex2(Start, [X|T], [X|[]], false) :- yes,fromIndex2(Start, T, S, true).
Jetzt muss nurnoch fromIndex2(Start, T, S, true) zutreffen.. und das tut es nur wenn:
Code: Alles auswählen
fromIndex2(Start, [], [], X).
also sozusagen wenn der Rest der Liste leer ist, denn bei einem Element MUSS er in deinem Code aufhören weil in den beiden anderen Regeln leerst sie ja praktisch. Also kommt in deiner Liste nur ein Element vor.. = X und X ist auch wonach du gesucht hast.. logisch oder?

EDIT: HE hat ne schöne Lösung :) schau dir se lieber ma an
Code: Alles auswählen
<!--   No Comment   -->
Benutzeravatar
proxylittle
 
Beiträge: 106
Registriert: 28.01.08 15:38
Wohnort: Aachen (Köln Wochenende)

Beitragvon mr.nice » 07.02.08 19:11

danke leute, mitlerweile hab ich das ganze ein bisschen umgebaut und es funktioniert...

Dieses ganze Listen hin und her gehacke ist irgedendwie ein bisschen verwirrend am Anfang in Prolog :)
mr.nice
 
Beiträge: 43
Registriert: 07.01.08 18:34

Beitragvon NeX » 09.02.08 14:12

ich finde prolog auch noch nicht wirklich intuitiv :)


na ja aber mal eine andere Frage.

Ich benutze Hilfsfunktionen um z.B. einen Akku benutzen zukönnen.

Die Funktion tut auch genau das was ich will ohne Fehler ohne alles...

es geht z.b. um die Funktion teilt und meine dazugehörige Hilfsfunktion teilt_.
teilt(X,Y). funktioniert solange man für X,Y Werte einsetzt.

Sobald man aber X,Y nicht durch einen Wert ersetzt funktioniert es nicht mehr...
Beispiel:
Code: Alles auswählen
75 ?- teilt(3,12).
More?


Yes
76 ?- teilt(3,X).

X = 3 ;
ERROR: >/2: Arguments are not sufficiently instantiated


kann mir hier vielleicht jemand weiterhelfen....
ich weiss das ich eigentlich um den brei durm rum spreche aber vielleicht kann mir ja jemand sagen ob das vorkommen darf oder nicht...
Don't think about....Just do it!
Benutzeravatar
NeX
 
Beiträge: 550
Registriert: 18.10.07 16:03
Wohnort: Mönchengladbach
Studiengang: Informatik (B.Sc.)
Studiert seit: WS 08/09
Anwendungsfach: BWL

Beitragvon theTux » 09.02.08 14:53

Ohne die genaue Implementierung zu kennen, ist es schwer, den Fehler zu finden. Es wird wohl daran liegen, dass du an einer Stelle einen Operator (Vergleich oder is) verwendest, der auf mindestens einer Seite einen komplett instanzierten Ausdruck erwartet.

Beispiel:
Code: Alles auswählen
X is Y+Z

X kann mit einem festen Wert belegt sein, muss aber nicht. Ist es belegt, vergleicht is, ist X nicht belegt, funktioniert is in gewissem Maße wie eine Zuweisung. Y und Z müssen aber zwangsläufig in dem Moment der Auswertung schon mit einem festen Wert belegt sein.
Das liegt daran, dass es beliebig viele mögliche Werte gibt, die den gesamten Ausdruck wahr machen können, wenn beide Seiten nicht belegt sind. In diesem Falle gibt es auch beliebig viele Möglichkeiten, wenn X belegt ist, aber Y und Z nicht.

Ich vermute, dass du in deinem Programm einen solchen Operator an einer Stelle verwendest, wo noch nicht alles instanziert ist. Wenn der Rest korrekt ist, sollte es reichen, die Reihenfolge der Bedingungen zu ändern.
Stur lächeln und... oh, falscher Pinguin.
Benutzeravatar
theTux
 
Beiträge: 577
Registriert: 15.01.06 16:41

Beitragvon NeX » 09.02.08 15:14

hi,

ich habe zwar mittlerweile keine hilfsfunktion mehr ...aber ich benutze ein
Code: Alles auswählen
 U is ....
sowie
Code: Alles auswählen
Y>0
.....

also kann es durchaus daran liegen....

mal ne andere frage...in der aufgabenstellung steht nichts davon das auch abfragen wie teilt(X,9) möglich sein müssen....

muss ich mein programm also noch ändern oder würde das auch so punkte geben.....

aber abgesehen davon würde ich prolog gern besser beherrschen von daher....wüsste ich schon wie ich sowas umgehe...aber code posten darf ich hier ja nicht ....
Don't think about....Just do it!
Benutzeravatar
NeX
 
Beiträge: 550
Registriert: 18.10.07 16:03
Wohnort: Mönchengladbach
Studiengang: Informatik (B.Sc.)
Studiert seit: WS 08/09
Anwendungsfach: BWL

Beitragvon theTux » 09.02.08 15:40

In der Aufgabenstellung steht nicht, dass es mit einer Variablen funktionieren muss. Bei der Fakultät macht es allerdings trotzdem Sinn, das so zu programmieren, dass es mit einer Ergebnisvariable geht.

Such in deinem Code einfach nach Stellen, an denen nichtinitialisierte Variablen verwendet werden und probiere, die entsprechenden Klauseln zu verschieben, so dass sie an Stellen stehen, an denen die Variablen bereits initialisiert sind.
Stur lächeln und... oh, falscher Pinguin.
Benutzeravatar
theTux
 
Beiträge: 577
Registriert: 15.01.06 16:41

Beitragvon theTux » 09.02.08 15:45

So wie du es gemacht hast (PN), wird es wohl nicht gehen... Vielleicht findest du einen anderen Algorithmus, mit dem du das gleiche realisieren kannst...
Stur lächeln und... oh, falscher Pinguin.
Benutzeravatar
theTux
 
Beiträge: 577
Registriert: 15.01.06 16:41

Beitragvon NeX » 09.02.08 16:54

also ist der ganze algorithmus falsch? bzw ich sollte am besten einen anderen ansatz wählen?

dann brauche ich also doch wieder eine hilfsfunktion....

bei fakultät klappt es bei mir....

Edit: bei fafultät natürlich doch nicht....

ich habe aber keine ahnung wie ich umstellen soll oder etwa das "is" rauslassen soll...
Don't think about....Just do it!
Benutzeravatar
NeX
 
Beiträge: 550
Registriert: 18.10.07 16:03
Wohnort: Mönchengladbach
Studiengang: Informatik (B.Sc.)
Studiert seit: WS 08/09
Anwendungsfach: BWL

Nächste

Zurück zu Praktische Informatik