Пролог - Помогите понять правило - PullRequest
1 голос
/ 15 января 2012

У меня есть база данных, полная фактов, таких как:

checkpoint(checkpoint1,checkpoint2,2).
checkpoint(checkpoint2,checkpoint3,3).
checkpoint(checkpoint3,checkpoint4,4).
checkpoint(checkpoint4,checkpoint5,2).
checkpoint(checkpoint5,checkpoint6,2).

например, контрольная точка (первая контрольная точка, вторая контрольная точка, время в минутах).

Тогда следующее правило проверяет, возможно ли путешествие между двумя контрольными точками в гонке:

journey(X,Y):- checkpoint(X,_,_), checkpoint(_,Y,_),!; checkpoint(Y,_,_), checkpoint(_,X,_),!.

journey(X,Y):- checkpoint(X,Z,_), journey(Z,Y).
journey(X,Y):- checkpoint(Z2,Y,_), journey(X,Z2).

Обратите внимание, что вы не можете пропустить контрольные точки, вы можете добраться до контрольной точки4, сначала перейдя к 1,2, а затем к 3. Однако вы можете вернуться назад, например, с контрольной точки 4 обратно на 3.

Я понимаю, что этот код проверяет, возможно ли путешествие между двумя контрольными точками, если существует промежуточная контрольная точка между X и Y, которая в данном случае является Z. Однако я не совсем понимаю, что делает Z2. Я предполагаю, что он просто используется в качестве другого промежуточного звена, такого как Z, но почему он назван другой переменной? Разве нельзя изменить Z2 на Z, и он все равно будет работать?

Ответы [ 2 ]

1 голос
/ 15 января 2012

Вы можете переименовать переменную, не меняя смысла правила, если вы переименуете все вхождений одинаково.

Но первое правило путешествия кажется мне неправильным: какой эффектВы ожидаете, что порезы там?У дизъюнкции нет шансов сработать, вызвать первый разрез.

Оставьте только первое правило, затем попробуйте ?- findall((X,Y),journey(X,Y),L). Вы увидите единственный ответ L = [ (checkpoint1, checkpoint2)].

Итак, ответ от@dasblinklight (+1) предлагает более глубокую коррекцию, кроме переименования переменных: просто отбросьте правило первого путешествия ...

РЕДАКТИРОВАТЬ

Эта процедура (без разрезов) расширяетисходная спецификация, позволяющая перечислить все возможные поездки и могла бы соответствовать исходному определению:

journey(X, Y):-
    journey([], X, Y).
journey(Visited, X, Y) :-
    ( checkpoint(X, I, _) ; checkpoint(I, X, _) ),
    \+ memberchk(I, Visited),
    ( I = Y ; journey([X|Visited], I, Y) ).
1 голос
/ 15 января 2012

Z2 может быть абсолютно переименовано в Z в последнем правиле, и логика правила не изменится. Причина, по которой автор не решился использовать Z, вероятно, заключается в том, что эта переменная не обозначает "среднюю точку", как Z в первом правиле.

Лично я бы выбрал более описательные имена переменных - From и To звучат как хорошие кандидаты:

journey(From,To):- checkpoint(From,Mid,_), journey(Mid,To).
journey(From,To):- checkpoint(Someplace,To,_), journey(From,Someplace).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...