Я предполагаю, что вы посещаете тот же курс, что и @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 существует, и
- существует прямой маршрут между станцией А и некоторой промежуточной станцией 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). Обнаружение таких циклов остается за вами.
person
Nicholas Carey
schedule
13.01.2012