いくつかのマイナーなコメントが最初にあります。そのカットは一切必要ありません。述部を正確に1つの回答に制限したい場合は、上部にあるonce/1
を使用して行います。それは概念的にクリーンであるだけでなく、さらに効率的です。
その他の問題は、Prologの安全でない否定に関連しています。あなたが誤ってあなたがしたように、あまりにも一般的な目標を引き渡すなら、否定は常に失敗するでしょう。言い換えれば、否定はPrologで次に壊れてしまいます。 2つの方法があります。そのような場合にエラーを生成するか、単に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
を再利用して別の定義です。私はあなたがこれらの色によって何を意味するのか本当にわかりません。それにもかかわらず:library(lambda)
を使用して
clink(X-_, Y-Color) :-
link(X, Color, Y).
route(X, Y, Path) :-
path(clink, Path, X-none, Y-_).
かさえ短い:
route(X, Y, Path) :-
path(\ (Xl,_)^(Yl^C)^clink(Xl,C,Yl), Path, X-none, Y-_).
してください、あなたの質問にvandalizeません。この投稿に問題がある場合は、カスタムフラグを立ててモデレータに警告することができます。 – Tunaki
一度投稿したコンテンツを削除する権利はありません。自己破産を追及しようとしないでください。 – Magisch