Проблема в том, что когда вы запрашиваете следующее решение, X увеличивается до 4. Рекурсия продолжается, но, поскольку X теперь больше 3, ваш случай терминала никогда не будет совпадать.
Вы можете сами убедиться в этом:
?- spy(aos/2).
% Spy point on aos/2
true.
[debug] ?- aos(4,0).
* Call: (8) aos(4, 0) ? Options:
+: spy -: no spy
/c|e|r|f|u|a goal: find .: repeat find
a: abort A: alternatives
b: break c (ret, space): creep
[depth] d: depth e: exit
f: fail [ndepth] g: goals (backtrace)
h (?): help i: ignore
l: leap L: listing
n: no debug p: print
r: retry s: skip
u: up w: write
m: exception details
C: toggle show context
* Call: (8) aos(4, 0) ? creep
Call: (9) _850 is 4+1 ? creep
Exit: (9) 5 is 4+1 ? creep
Call: (9) write(5) ? creep
5
Exit: (9) write(5) ? creep
Call: (9) _856 is 0+1 ? creep
Exit: (9) 1 is 0+1 ? creep
* Call: (9) aos(5, 1) ? creep
Call: (10) _862 is 5+1 ? creep
Exit: (10) 6 is 5+1 ? creep
Call: (10) write(6) ? creep
6
Exit: (10) write(6) ? creep
Call: (10) _868 is 1+1 ? creep
Exit: (10) 2 is 1+1 ? creep
* Call: (10) aos(6, 2) ? creep
Call: (11) _874 is 6+1 ? creep
Exit: (11) 7 is 6+1 ? creep
Call: (11) write(7) ? creep
7
Exit: (11) write(7) ? creep
Call: (11) _880 is 2+1 ? creep
Exit: (11) 3 is 2+1 ? creep
* Call: (11) aos(7, 3) ? creep
Call: (12) write(end) ? creep
end
Exit: (12) write(end) ? creep
* Exit: (11) aos(7, 3) ? creep
* Exit: (10) aos(6, 2) ? creep
* Exit: (9) aos(5, 1) ? creep
* Exit: (8) aos(4, 0) ? Unknown option (h for help)
* Exit: (8) aos(4, 0) ? creep
true ;
* Redo: (11) aos(7, 3) ? creep
Call: (12) _886 is 7+1 ? creep
Exit: (12) 8 is 7+1 ? creep
Call: (12) write(8) ? creep
8
Exit: (12) write(8) ? creep
Call: (12) _892 is 3+1 ? creep
Exit: (12) 4 is 3+1 ? creep
* Call: (12) aos(8, 4) ? creep
Call: (13) _898 is 8+1 ? creep
Exit: (13) 9 is 8+1 ? creep
Call: (13) write(9) ? creep
9
Проблема в том, что когда вы просите другое решение, последняя точка выбора Пролога была самой внутренней после aos (7,3). Таким образом, он войдет во вторую ветвь с J = 7 и X = 3. Вы можете решить эту проблему так:
aos(_,3):- write('end').
aos(J,X):- X < 3, ((N is J+1, write(N),Y is X+1,aos(N,Y));
(N is J-1, write(N), Y is X+1,aos(N,Y))).
Однако, это не дает желаемой выходной последовательности. Вы получаете 567 5 45 3 345 3 23 1. Я не совсем уверен, что вам нужно сделать, чтобы получить эту выходную последовательность, но я подозреваю, что вам нужно сгруппировать ваши три дополнения и распределить их, используя вторую переменную здесь, вызывает у тебя проблемы. Я бы, наверное, реализовал так:
inc_or_dec(X, Y) :- succ(X, Y).
inc_or_dec(X, Y) :- succ(Y, X).
aos(N) :-
inc_or_dec(N , N1),
inc_or_dec(N1, N2),
inc_or_dec(N2, N3),
write(N1), write(N2), write(N3), write('end'), nl.
Это делает более очевидным для Пролога, где реальные точки выбора находятся, то есть не между отдельными цифрами в группах по три. Однако, это все еще не совсем дает вам последовательность, которую вы хотите; вы получите 567 565 545 543 345 343 323 321. Если вы хотите получить решения с 4 изначально, вам придется ослабить ограничение и позволить X появиться без изменений, но если вы сделаете это, вы также получите последовательности, такие как 444 и 555. Может быть полезно знать, чего вы пытаетесь достичь, а не просто как вы пытаетесь этого достичь.