Чтобы понять эту проблему, вы можете представить дерево с X
в качестве первого уровня и Y
в качестве второго уровня (в прологе используется разрешение sld, которое хорошо описывается деревом). Рассмотрим эту проблему:
p(1).
p(2):-!.
p(3).
sol(X,Y):-
p(X),
p(Y).
Я добавил предикат solve/2
, чтобы сделать его более понятным. Запустите запрос:
?- solve(X,Y).
Прежде всего, вы должны выбрать значение для X
. Пролог использует поиск в глубину сверху вниз, слева направо. Таким образом, он оценивает p(x)
: p(1)
успешно (потому что это первое предложение, если вы напишете p(2)
выше p(1)
, p(2)
будет успешным) и, таким образом, X = 1
. Затем оценивает p(Y)
: p(1)
успешно, и поэтому у вас есть первое решение:
X = Y, Y = 1.
Если вы нажмете больше, то пролог сделает возврат (вы можете представить это как шаг вверх по дереву) и попробует другое значение для p(Y)
. В этом случае p(2)
выполняется успешно, предикат истинен, и вы получаете:
X = 1, Y = 2.
Теперь, если вы нажмете дальше, из-за того, что в теле p(2)
есть разрез (!
) (общее правило в прологе имеет форму head :- body
), пролог не будет углубляться, а p(3)
будет проигнорирован. Так что решения p(Y)
больше нет. Итак, есть еще один возврат, и на этот раз для p(X)
, p(2)
успешно и X = 2
, а для p(Y)
, p(1)
успешно, и вы получаете:
X = 2, Y = 1.
Если вы нажмете на больше, вы получите:
X = Y, Y = 2.
Теперь, из-за того, что после p(2)
есть вырез, больше нет доступных решений как для X
, так и для Y
(!
вырезает все, что ниже p(2)
).
Если вы удалите разрез, вы получите все возможные решения:
X = Y, Y = 1
X = 1,
Y = 2
X = 1,
Y = 3
X = 2,
Y = 1
X = Y, Y = 2
X = 2,
Y = 3
X = 3,
Y = 1
X = 3,
Y = 2
X = Y, Y = 3
Имейте в виду, что порядок предложений важен. Если вы пишете
p(2).
p(1):-!.
p(3).
Ты получаешь
X = Y, Y = 2
X = 2,
Y = 1
X = 1,
Y = 2
X = Y, Y = 1
Вы можете проверить это поведение с помощью трассировщика. В SWI или SWISH вы можете написать ?-
trace, solve(X,Y).
Если у вас возникла такая ситуация:
p(1).
p(2).
p(3).
sol(X,Y):-
p(X),
!,
p(Y).
prolog проверит все возможные значения для Y
и только одно значение для X
, потому что разрез останавливает исследование дерева (в идеале у вас есть 3 ветви для X
(1,2,3) и 3 для Y
(1,2,3) , !
вырезает 2 и 3 из X
), и вы получаете:
X = Y, Y = 1
X = 1,
Y = 2
X = 1,
Y = 3
Извините за длинный пост, надеюсь на ясность.
person
damianodamiano
schedule
05.01.2018
p(X),p(Y)
он откатывается, чтобы изменить значение X? - person user452306   schedule 05.01.2018p(X), p(Y)
возвращается кp(X)
, потому что так работает Пролог. Разрез между ними,p(X), !, p(Y)
, предотвращает возврат кp(X)
. Другими словами, как толькоp(X), p(Y)
завершится успешно, Пролог отступит и попытается найти другоеY
, которое также приведет к успеху. Как только эти варианты исчерпаны, он возвращается назад, чтобы найти другойX
, чтобы позволитьp(X)
добиться успеха, а затем снова переходит кp(Y)
(начиная сp/1
фактов). - person lurker   schedule 05.01.2018X = 3
илиY = 3
в любом из ваших решений? Вы не из-заp(2) :- !.
. Пролог никогда не доходит до проверкиp(3).
. - person lurker   schedule 05.01.2018