2016-09-23 3 views
0

Ich frage mich, ob es in DLV eine Möglichkeit gibt, eine Liste mit den Elementen aller Prädikate zu erstellen, die in einer Regel wahr sind. Zum Beispiel, wenn ich die folgenden Prädikate für neue Prädikate sein sollteDLV Liste Zusammensetzung

foo(a, b). 
foo(a, c). 
foo(a, e). 
foo(b, c). 

Das Ergebnis Suche erfahren, wo das erste Element der erste Parameter von foo und der zweite Parameter ist, sollte eine Liste mit allen Elementen enthalten assoziiert der erste Parameter Empirisch:

bar(a, [b,c,e]). 
bar(b, [c]). 

Ich weiß, es ist ein Weg, um diese Ergebnisse zu bekommen (und viele mehr) mit dem folgenden Code:

bar(A, [X]) :- foo(A, X). 
bar(A, P) :- bar(A, P0), 
       foo(A, X), 
       not #member(X, P0), 
       #insLast(P0, X, P). 

Aber ich würde gerne wissen, ob eine Möglichkeit, die verhindert, dass es Generierung aller möglichen Listen der Größe von 1 bis N (wobei N die Anzahl der Elemente der endgültigen Liste ist). Ich möchte es aus zwei Gründen tun: (1) Reduziere die Rechenkosten (2) verhindere, dass alle unnötigen Prädikate verworfen werden.

Wenn der Rechenaufwand war kein Problem, was der Fall sein kann, dachte ich an den folgenden Änderungen, um mit den größten Listen nur die Prädikate zu halten:

tmp_bar(A, [X], 1) :- foo(A, X). 
tmp_bar(A, P, L) :- tmp_bar(A, P0, L0), 
         foo(A, X), 
         not #member(X, P0), 
         #insLast(P0, X, P), 
         L = L0 + 1. 
bar(A, P)  :- tmp_bar(A, P, L), 
        max_list(A, L). 
max_list(A, L) :- foo(A, _), 
        #max{X: tmp_bar(A, P, X)} = L. 

Dies ist jedoch beginnt werden kompliziert und zeigt alle Listen der maximalen Größe und nicht nur einer von ihnen. Wie werde ich alle außer einem los? Ich habe versucht, Balken (A, P) nur für den Fall zu generieren, dass es keinen anderen Balken gibt (A, _), aber ich bekomme "Regel ist nicht sicher". Auch versucht, die Anzahl der Vorkommen zu zählen und ähnliche Probleme erscheinen ...

Am wichtigsten ist, ist es möglich, die Ergebnisse zu erhalten, die ich auf einmal ohne diese vielen Tricks erwarte?

Jede Hilfe ist willkommen,

Vielen Dank!

Antwort

0

Anscheinend fand ich eine Lösung für das Problem durch Hinzufügen von Elementen in einer bestimmten Reihenfolge. Ich füge das Element am Ende der Liste nur hinzu, wenn es kleiner ist als das letzte Element der aktuellen Liste. Ich hatte es mit Namen und nicht mit Zahlen zu tun, also war das nicht möglich). Hier

ist der Code:

tmp_bar(A, [X], 1) :- foo(A, X). 
tmp_bar(A, P, L) :- tmp_bar(A, P0, L0), 
         foo(A, X), 
         #last(P0, Y), 
         Y < X, 
         #insLast(P0, X, P), 
         L = L0 + 1. 

bar(A, P) :- tmp_bar(A, P, L), 
      max_list(A, L). 

max_list(A, L) :- foo(A, _), 
       #max{X: tmp_bar(A, P, X)} = L. 

Hoffe, dass es jemand anderes in der Zukunft hilft.