Я предполагаю, что вы посещаете тот же класс, что и @DavidGregg. Мой ответ на https://stackoverflow.com/questions/8789021/basic-prolog-but-struggling/8794162#8794162 может вам помочь.
FWIW, переменная пролога _
является анонимной / " не волнует " переменной. Переменная с именем типа ____
является , а не анонимной / " не волнует ". Анонимная переменная объединяется с чем угодно, и объединение не переносится, поэтому такие факты, как:
number(1).
letter(a).
предикат, такой как
foo :- number(_) , letter(_).
будет успешным, тогда как
foo :- number(____) , letter(____) .
не будет.
В вашем первом предложении
isjourney( Station1 , Station2 ) :-
overground( Station1 , _ , _ ) ,
overground( _ , Station2 , _ ) ;
overground( Station2 , _ , _ ) ,
overground( _ , Station1 , _ )
.
Вы уверены, что это так, как вы думаете?
Как и грамматики процедурных языков, операторы пролога И и ИЛИ имеют разный приоритет. Если вы собираетесь использовать оператор ИЛИ ;
, вам следует заключить скобки, чтобы прояснить предполагаемую привязку. Хотя лучше, имхо, вообще этого избежать:
isjourney( Station1 , Station2 ) :-
overground( Station1 , _ , _ ) ,
overground( _ , Station2 , _ )
.
isjourney( Station1 , Station2 ) :-
overground( Station2 , _ , _ ) ,
overground( _ , Station1 , _ )
.
Однако ваша основная мысль верна: существует маршрут между двумя станциями A и B , если
- станция А существует, а
- станция B существует, а
- существует прямой маршрут между станцией A и некоторой промежуточной станцией X, и
- существует маршрут между этой промежуточной станцией X и станцией B
Я полагаю, что вы пропустили один случай: станция A и станция B находятся рядом.
Однако я хотел бы отметить, что явная проверка существования станции не является действительно необходимой: предикат не может быть успешным, если станция не существует.
Я был бы склонен написать предикат что-то вроде
isjourney(A,B) :-
station_exists(A) , % verify that station A exists
station_exists(B) , % verify that station B exists
(
route_exists(A,B) % verify that a route exists between A and B
; % in either direction
route_exists(B,A)
)
.
route_exists(A,B) :- % 1st, check for directly adjacent stations
overground(A,B,_) ,
.
route_exists(A,B) :- % 2nd, check for indirect routes
overground(A,T,_) ,
route_exists(T,B)
.
% =========================================================
% check for the existence of a station
% we want the cut to alternatives. A station exists or it doesn't
% we don't want backtracking to succeed by finding every instance
% of the station
% in the route map.
% =========================================================
station_exists(X) :- overground(X,_,_) , ! .
station_exists(X) :- overground(_,X,_) , ! .
Обратный путь, конечно, должен перечислять все возможные маршруты в обоих направлениях.
Как отмечено в моем ответе, связанном с вышеупомянутым, решение все еще уязвимо для бездонной рекурсии, если на графике существует цикл (например, если станция A связана с станцией B, а станция B связана с обеими станциями C и A). ). Обнаружение таких циклов оставлено вам.