Einige kleinere Kommentare zuerst: Sie brauchen diesen Schnitt überhaupt nicht. Wenn Sie das Prädikat wirklich auf genau eine Antwort beschränken möchten, tun Sie dies am oberen Ende mit once/1
. Das ist nicht nur konzeptionell sauberer, es ist noch effizienter.
Das andere Problem, das Sie hatten, hängt mit der unsicheren Negation von Prolog zusammen. Wenn Sie versehentlich ein zu allgemeines Ziel übergeben, wird die Negation immer fehlschlagen. Mit anderen Worten: Negation ist in Prolog als nächstes gebrochen. Es gibt zwei Möglichkeiten: Entweder einen Fehler für solche Fälle oder einfach eine bessere Definition wie non_member/2
verwenden.
Mal sehen, was mit non_member/2
an Ort und Stelle geschehen wäre:
link(b,brown,j).
route(X,X,[X],_).
route(X,Z,[X|Path],Positions):-
link(X,Colour,Y),
% \+member([Y,Colour],Positions),
non_member([Y,Colour],Positions),
route(Y,Z,Path,[[Y,Colour]|Positions]).
non_member(E, Es) :-
maplist(dif(E), Es).
| ?- route(X,Y,Path,Rs).
Y = X, Path = [X]
; X = b, Y = j, Path = "bj", Rs = []
; X = b, Y = j, Path = "bj", Rs = [_A],
dif([j,brown],_A)
; X = b, Y = j, Path = "bj", Rs = [_A,_B],
dif([j,brown],_A),
dif([j,brown],_B)
; X = b, Y = j, Path = "bj", Rs = [_A,_B,_C],
dif([j,brown],_A),
dif([j,brown],_B),
dif([j,brown],_C)
; X = b, Y = j, Path = "bj", Rs = [_A,_B,_C,_D],
dif([j,brown],_A),
dif([j,brown],_B),
dif([j,brown],_C),
dif([j,brown],_D)
; X = b, Y = j, Path = "bj", Rs = [_A,_B,_C,_D,_E],
dif([j,brown],_A),
dif([j,brown],_B),
dif([j,brown],_C),
dif([j,brown],_D),
dif([j,brown],_E)
; ...
So können alle Antworten beschreiben die gleiche Path = "bj"
(Kurzform für [b,j]
). Aber das letzte Argument ist jetzt eine Liste von Elementen, die sich alle von [j,brown]
unterscheiden müssen. So wäre die beste gewesen:
route(X, Y, Path) :-
route(X, Y, Path, []).
Und hier ist eine alternative Definition Wiederverwendung path/4
. Ich bin nicht wirklich sicher, was Sie mit diesen Farben meinen. Dennoch:
clink(X-_, Y-Color) :-
link(X, Color, Y).
route(X, Y, Path) :-
path(clink, Path, X-none, Y-_).
oder noch kürzer mit library(lambda)
:
route(X, Y, Path) :-
path(\ (Xl,_)^(Yl^C)^clink(Xl,C,Yl), Path, X-none, Y-_).
Bitte, beschädige nicht Ihre Frage. Wenn ein Problem mit diesem Beitrag besteht, können Sie einen Moderator benachrichtigen, indem Sie das benutzerdefinierte Flag erhöhen. – Tunaki
Sie haben nicht das Recht, Ihre eigenen Inhalte zu löschen, sobald sie gepostet wurden. Bitte verzichten Sie auf weitere Selbstversuchsversuche. – Magisch