[Prolog] Problem mit Listen

Vielleicht ist ja hier jemand der sich mit Prolog auskennt.

Ich sitze nun schon seit einiger Zeit an einem Problem.
Und zwar habe ich eine Liste folgender Form:
[a,a,a, [b,b,b, [c,c,c, [d,d,d,[...]]], [c,c,c, [d,d,d,[...]]]]] (Punkte stehen für und so weiter)

Ich möchte diese nun folgendermaßen ausgeben:
aaa
bbb
ccc ccc
ddd ddd
.......
.......

Das versuche ich mit diesem Code:
Code:
printproof([X,Y,Z]):-write(X),write(Y),write(Z).
printproof([X,Y,Z|[S],[A]]):-write(X),write(Y),write(Z).,nl,printproof(S),printproof(A).
printproof([X,Y,Z|[A]]):-write(X),write(Y),write(Z),nl,printproof(A).
So lange die liste nur so [..[...[...[.. ist funktioniert das wunderbar, aber sobald eine Verzweigung [..[..][..]] dazukommt geht es nicht mehr. Für die Verzweigung hätte ich eigentlich die 2. zeile im Code, aber das scheint nicht zu funktionieren.

Kann mir jemand weiterhelfen?
 
nach welchem Muster möchtest Du die Ausgabe gestalten?
Also
aaa
bbb
ccc ccc
ddd ddd
dass tatsächlich gleiche Elemente neben einander in einer Zeile wären?

Sonst würde ich auf Anhieb sagen dass mir Deine 2 Zeile nicht so wirklich gefällt:
Code:
printproof([X,Y,Z|[S],[A]])
da | für den "Rest" steht und Du dabei schlecht sagen kannst "gib mir den Rest und dahinter noch ein Element" ;)

Wenn es tatsächlich alles nach dem Muster [1,2,3,[1,2,3,[...]]] Aufgebaut ist, würde ich das auf die Schnelle so machen:
Code:
p_proof([X,Y,Z]):- writeln((X,Y,Z)).     %für die letzen 3 Elemente
p_proof([X,Y,Z|T]):- writeln((X,Y,Z)),p_proof(T).
p_proof([H]):- p_proof(H).  %zum "entpacken" der [] Klammern
p_proof([H|T]):- p_proof(H),p_proof(T).  %zum Entpacken der Klammern
 
Wenn es tatsächlich alles nach dem Muster [1,2,3,[1,2,3,[...]]] Aufgebaut ist, würde ich das auf die Schnelle so machen:
Code:
p_proof([X,Y,Z]):- writeln((X,Y,Z)).     %für die letzen 3 Elemente
p_proof([X,Y,Z|T]):- writeln((X,Y,Z)),p_proof(T).
p_proof([H]):- p_proof(H).  %zum "entpacken" der [] Klammern
p_proof([H|T]):- p_proof(H),p_proof(T).  %zum Entpacken der Klammern
Da ist die Lösung so einfach, und ich komm einfach nicht drauf :(
Danke für deine Hilfe.

edit: Obwohl dein Vorschlag funktioniert hätte ich noch eine Frage zu meiner 2. Zeile. Warum funktioniert es nicht wenn ich
printproof([X,Y,Z|,[A]])
in
printproof([X,Y,Z,,[A]])
umschreibe?

Das wäre doch genau das Muster wenn ich 3 Elemente und dann 2 Listen habe?
 
Zuletzt bearbeitet:
Warum funktioniert es nicht wenn ich
printproof([X,Y,Z|,[A]])
in
printproof([X,Y,Z,,[A]])
umschreibe?
Das wäre doch genau das Muster wenn ich 3 Elemente und dann 2 Listen habe?

Wer sagt das ;) ?

Bei
printproof([X,Y,Z,,[A]])
lese ich als Prolog interpreter erstmal:
"da soll eine Liste mit X,Y,Z Variablen sein, eine Unterliste mit 1 Element, weitere Unterliste mit 1 Element" ;)

Die Liste
Code:
[b,b,b, [c,c,c, [...]], [c,c,c, [...]]]
schaut aber etwas anders aus - da haben Unterlisten mehr als Ein Element ;)

Um dieses Muster zu matchen müsste man den Code noch erweitern:
Code:
printproof([X,Y,Z,[S|T1],[A|T2]])
was sich dann aber insgesamt imho zu kompliziert gestalten würde.
 
Ich versuche nun die Liste die oben ausgegeben wird nach bestimmten Elementen zu durchsuchen.

Das mache ich so:
Code:
dabei([H1,H2,H3],H1,H2,H3).
dabei([H1,H2,H3|_],H1,H2,H3).
dabei([_|T],H1,H2,H3) :- dabei(T,H1,H2,H3).
dabei([H],H1,H2,H3):- dabei(H,H1,H2,H3). 
dabei([H|T],H1,H2,H3):- dabei(H,H1,H2,H3),dabei(T,H1,H2,H3).
Ich übergebe also die Liste und 3 Elemente die gesucht werden sollen. Die Liste wird so wie oben beim Ausgeben durchwandert und mit der 1. und 2. Zeile jeweils geschaut ob die 3 Elemente vorkommen.

Wenn ich das mit dieser Eingabe teste
dabei([2,2,3,[2,3,4,[1,3,3,[1,2,3],[7,7,7]]]],1,3,3).
funktioniert es. Auch mit allen anderen Zahlenkombinationne die in der Liste vorkommen funktioniert es, nur mit einer einzigen nicht. Mit 1,2,3

Weißt du woran das liegen könnte?
 
Weil 1,2,3 hier gefunden wird:
Code:
dabei([H|T],H1,H2,H3):- --->dabei(H,H1,H2,H3)<----,dabei(T,H1,H2,H3).
also in "dabei(H,H1,H2,H3)". Die ist dann erfüllt - allerdings muss noch "dabei(T,H1,H2,H3)"
erfüllt werden, was nur dann der Fall wäre, wenn 1,2,3 zwei mal in der Liste vorkommen würde ;)

wenn, dann sollte man das in
Code:
dabei([H|T],H1,H2,H3):- dabei(H,H1,H2,H3) ; dabei(T,H1,H2,H3).
ändern - also dann erfüllt, wenn es im Header ODER im Tail ist (und nicht in beiden).

Wenn es allerdings um das Durchsuchen geht, würde ich ehrlich gesagt das Ganze etwas anders gestalten - zuerst die Liste "abflachen":
Code:
  flatten_list(X,Y) :- flatten_list(X,Y,[]).

 flatten_list([]) --> !.
 flatten_list([H|T]) --> !, flatten_list(H),flatten_list(T).
 flatten_list(H) --> [H].
(sollte SWI Listfunktion "flatten" ähnlich oder gleich sein).

Damit erhält man eine Liste ohne Unterlisten.
Bsp:
Code:
24 ?- flatten_list([2,2,3,[2,3,4,[1,3,3,[1,2,3],[7,7,7]]]],FlatList).
FlatList = [2, 2, 3, 2, 3, 4, 1, 3, 3|...].
Nun kann man sie nach belieben ausgeben oder durchsuchen wie man mag :)


Bsp:
Code:
flatten_list(X,Y) :- flatten_list(X,Y,[]).

 flatten_list([]) --> !.
 flatten_list([H|T]) --> !, flatten_list(H),flatten_list(T).
 flatten_list(H) --> [H].

 %strenge 3 Elemente Suche
 %gefunden:
 dabei([X,Y,Z|_],X,Y,Z).   % X,Y,Z|_ beinhaltet auch 3 elementige Listen ;)
 dabei([_,_,_|T],X,Y,Z):- dabei(T,X,Y,Z).   %oder 3 Elemente Überspringen und weitersuchen
Anfrage:
Code:
X=[2,2,3,[2,3,4,[1,3,3,[1,2,3],[7,7,7]]]], flatten_list(X,Flat),dabei(Flat,1,2,3).
Antwort
Code:
X = [2, 2, 3, [2, 3, 4, [1|...]]],
Flat = [2, 2, 3, 2, 3, 4, 1, 3, 3|...]
(also true, da X und Flat ausgegeben werden)
 
Zurück
Oben