Некоторые незначительные замечания во-первых: вам не нужно это разрезать вообще. Если вы действительно хотите ограничить предикат точно одним ответом, сделайте это сверху, используя once/1
. Это не только концептуально чище, но и более эффективно.
Другая проблема, с которой вы столкнулись, связана с небезопасным отрицанием Пролога. Если вы случайно, как и вы, сдадите цель, которая является слишком общей, отрицание всегда будет терпеть неудачу. Другими словами: отрицание в Prolog является следующим. Есть два выхода: либо создать ошибку для таких случаев, либо просто использовать более точное определение, например, non_member/2
.
Давайте посмотрим, что случилось бы с non_member/2
на месте:
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)
; ...
Таким образом, все ответы описывают один и тот же Path = "bj"
(короткая форма для [b,j]
). Но последний аргумент теперь представляет собой список элементов, которые должны быть разными для [j,brown]
. Так что лучше было бы:
route(X, Y, Path) :-
route(X, Y, Path, []).
А вот альтернативное определение повторного path/4
. Я не совсем уверен, что вы подразумеваете под этими цветами. Тем не менее:
clink(X-_, Y-Color) :-
link(X, Color, Y).
route(X, Y, Path) :-
path(clink, Path, X-none, Y-_).
или даже короче при использовании library(lambda)
:
route(X, Y, Path) :-
path(\ (Xl,_)^(Yl^C)^clink(Xl,C,Yl), Path, X-none, Y-_).
Пожалуйста, не хулиганить на ваш вопрос. Если есть проблема с этим сообщением, вы можете предупредить модератора, подняв пользовательский флаг. – Tunaki
Вы не имеете права удалять свой собственный контент после размещения. Пожалуйста, воздержитесь от дальнейших попыток самоуважения. – Magisch