Ответы от @ thequark и от @ LittleBobbyTables отлично работают при использовании с заземленными строками.
Но что, если они не ограничены по длине, как в следующих запросах?
?- phrase(s(3),_). % expected: success
% observed: no answer(s)
?- phrase(s(-10),_). % expected: failure
% observed: no answer(s)
Мы, конечно, хотим, чтобы запросы, подобные приведенному выше, заканчивались повсеместно!
Давайте используем clpfd и напишем:
:- use_module(library(clpfd)).
s(0) --> [].
s(N) --> {N#>0,N#=N0+1},[a],s(N0),[b].
Примеры запросов:
?- phrase(s(N),[a,a,a,a,b,b,b,b]).
N = 4 ; % works like in the other answers
false.
?- phrase(s(3),Xs).
Xs = [a,a,a,b,b,b] ; % now, this works too!
false. % (terminates universally)
?- phrase(s(-10),_). % fails, like it should
false.