Вот версия, которая заканчивается для первого или второго связываемого аргумента:
pow2(E,X) :-
pow2(E,X,X).
pow2(0,s(0),s(_)).
pow2(s(N),Y,s(B)) :-
pow2(N,Z,B),
add(Z,Z,Y).
Вы можете определить условия его завершения с помощью cTI.
Итак,как я придумал это решение?Идея состояла в том, чтобы найти способ, как второй аргумент может определить размер первого аргумента.Основная идея заключается в том, что для всех i ∈ N : 2 i > i .
Поэтому я добавил еще один аргумент, чтобы выразить это отношение.Может быть, вы можете усилить это немного дальше?
И вот причина, почему оригинальная программа не завершается.Я даю причину как fail-slice .Смотрите тег для более подробной информации и других примеров.
?- pow2(P,s(s(0))), <b>false</b>.
<s>pow2(0,s(0)) :- <b>false</b></s>.
pow2(s(N),Y) :-
pow2(N,Z), <b>false</b>,
<s>times2(Z,Y)</s>.
Именно этот крошечный фрагмент является источником для прекращения!Посмотрите на Z
, которая является новой новой переменной!Чтобы решить проблему, этот фрагмент должен быть изменен каким-то образом .
И вот причина, по которой решение @ Keeper не прекращается для pow2(s(0),s(N))
.
?- pow2(s(0),s(N)), <b>false</b>.
<s>add(0,Z,Z) :- <b>false</b></s>.
add(s(X),Y,s(Z)) :-
add(X,Y,Z), <b>false</b>.
times2(X,Y) :-
add(X,X,Y), <b>false</b>.
<s>pow2(0,s(0)) :- <b>false</b></s>.
<s>pow2(s(N),Y) :- <b>false</b></s>,
<s>var(Y)</s>,
<s>pow2(N,Z)</s>,
<s>times2(Z,Y)</s>.
pow2(s(N),Y) :-
nonvar(Y),
times2(Z,Y), <b>false</b>,
<s>pow2(N,Z)</s>.