どのように機能するかをよりよく理解できるように、取り組んでいることをどのように達成できるかを実証しようとしました。あなたのOPはあまり完全ではなかったので、私はいくつかの自由を取りました! ここに私が取り組んでいる事実があります:
road(birmingham,bristol, 9).
road(london,birmingham, 3).
road(london,bristol, 6).
road(london,plymouth, 5).
road(plymouth,london, 5).
road(portsmouth,london, 4).
road(portsmouth,plymouth, 8).
これが、パスを見つけるために呼び出す述語get_road/4です。これは基本的に、2 つのアキュムレータ (1 つは既に訪れたポイント用、もう 1 つは通過した距離用) を持つ作業述語を呼び出します。
get_road(Start, End, Visited, Result) :-
get_road(Start, End, [Start], 0, Visited, Result).
get_road (+Start, +End, +Waypoints, +DistanceAcc, -Visited,
-TotalDistance ) :
最初の節は、最初の地点と最後の地点の間に道路がある場合、ここで終了できます。
get_road(Start, End, Waypoints, DistanceAcc, Visited, TotalDistance) :-
road(Start, End, Distance),
reverse([End|Waypoints], Visited),
TotalDistance is DistanceAcc + Distance.
2 番目の節は、最初のポイントと中間ポイントの間に道路がある場合、それを取得して get_road(intermediate, end) を解決できることを示しています。
get_road(Start, End, Waypoints, DistanceAcc, Visited, TotalDistance) :-
road(Start, Waypoint, Distance),
\+ member(Waypoint, Waypoints),
NewDistanceAcc is DistanceAcc + Distance,
get_road(Waypoint, End, [Waypoint|Waypoints], NewDistanceAcc, Visited, TotalDistance).
使用方法は次のとおりです。
?- get_road(portsmouth, plymouth, Visited, Distance).
そして利回り:
Visited = [portsmouth, plymouth],
Distance = 8 ;
Visited = [portsmouth, london, plymouth],
Distance = 9 ;
Visited = [portsmouth, plymouth, london, plymouth],
Distance = 18 ;
false.
お役に立てば幸いです。