2016-07-09 23 views
2

Ich bin daran interessiert, eine lange Verkettung von Listen unter Verwendung der Prolog-Sprache durchzuführen. Ziel ist es, ein Prädikat zu definieren, das eine unbekannte Anzahl von Listen erhält und sie alle zu einer Liste verkettet (die als zweites Argument für das Prädikat angegeben wird).Wie führt man eine lange Verkettung von Listen in Prolog durch?

Ich weiß, ich sollte zuerst verstehen, wie Prolog Argumente mit unbegrenzter Größe unterstützt, aber ich denke, die Antwort darauf ist die Verwendung von Listen, zum Beispiel: [a | [[b, c, d] | [[e, f, g] | [h, i, j, k]]]].

Wenn ja, dachte ich über das Prädikat etwas wie diese zu schreiben:

l_conc([ ],[ ]). 
l_conc([[ ]|Tail],L):- 
     l_conc(Tail,L). 
l_conc([[Head|L1]|Tail],[Head|L2]):- 
     l_conc([L1|Tail],L2). 

Es ist jedoch nur leere Listen miteinander verkettet. Bitte helfen Sie mir hier (sowohl in Bezug auf die Darstellung der Argumente und das Prädikat selbst) :-) Danke!

+1

[Hier ist eine Antwort] (http://stackoverflow.com/a/9787502/772868). – false

Antwort

3

Bevor ich die eigentliche Frage beantworte, habe ich ein paar Kommentare.

Zunächst kann der Begriff, den Sie als Beispiel [a | [[b,c,d] | [[e,f,g] | [h,i,j,k]]]] geben, kompakter in Prolog geschrieben werden. Sie können den Prolog Toplevel selbst verwenden, um zu sehen, was dieser Begriff eigentlich ist:

 
?- Ls = [a | [[b,c,d] | [[e,f,g] | [h,i,j,k]]]]. 
Ls = [a, [b, c, d], [e, f, g], h, i, j, k]. 

Daraus sehen Sie, dass dies nur eine Liste. Es ist jedoch nicht eine Liste von   Listen, weil die Atome a, h, i usw. sind nicht   Listen.

Daher entspricht Ihr Beispiel nicht Ihrer Frage. Es gibt Möglichkeiten, Listen zu "plattdrücken", aber ich kann nur empfehlen gegen zu glätten, weil es keine reine Beziehung ist. Der Grund ist, dass [X] als eine "flache" Liste gilt, aber X = [a,b,c] macht [[a,b,c]]nicht   flach, so dass Sie in logische Inkonsistenzen laufen, wenn Sie flatten/2 verwenden.

Was ich stattdessen empfehlen, ist append/2. Der einfachste Weg, dies zu implementieren, ist die Verwendung eines DCG   (). Betrachten Sie zum Beispiel:

 
together([]) --> []. 
together([Ls|Lss]) --> 
     list(Ls), 
     together(Lss). 

list([])  --> []. 
list([L|Ls]) --> [L], list(Ls). 

Beispiel query:

 
?- phrase(together([[a],[b,c],[d]]), Ls). 
Ls = [a, b, c, d]. 

In diesem Beispiel genau einer Ebene der Verschachtelung entfernt wurde.

+0

Hallo Mat, verstehe ich die Diskrepanz in dem Beispiel und verstehen Ihre Erklärung über DCG. Was ich nicht verstehe ist, warum kann ich nicht/2 nur anhängen verwenden, wenn es in der Sprache heimisch ist - es scheint, dass es genau das tut, was ich brauche ... Außerdem habe ich versucht, die DCG-Code zu übersetzen in Regeln und Fakten Code, aber es ergab nicht das gleiche Ergebnis. Kannst du mir helfen zu finden, was ich hier reparieren soll? new_together ([], []). new_together ([Ls | Lss], [NewLs | NewLss]): - \t neue_liste (Ls, NewLs), \t new_together (Lss, NewLss). neue_liste ([], []). neue_liste ([L | Ls], [L | NewLs]): - \t neue_liste (Ls, NewLs). Danke! – avish12

+1

Sie können ** und sollten natürlich das vordefinierte 'append/2' in realen Programmen verwenden, wenn Ihr Prolog-System dieses Prädikat bereits bereitstellt. Sie sollten jedoch auch lernen, solche Prädikate selbst zu schreiben, wenn Sie noch nicht wissen, wie Sie das tun sollen, um diese Zusammenhänge besser zu verstehen und auch, wenn Sie sie brauchen, leicht Variationen zu implementieren. Um zu sehen, wie die DCG, die ich gab, in Prolog-Klauseln übersetzt werden kann, verwende "listing/1", wie "? - listing (zusammen // 1)." – mat