This is another way that I find quite enjoyable:
:- op(1200, xfx, all). :- op(1200, xfx, s5). :- op(1200, xfx, s10). all(F,X):- F =.. [_|T], findall(T, F,X). s5(F,X):- F =.. [_|T], findnsols(5,T,F,X). s10(F,X):- F =.. [_|T], findnsols(10,T,F,X). p(1). p(2). p(3). p(4). p(5). p(6). p(7). nat(0). nat(s(X)) :- nat(X). nat_nat_sum(0,X,X). nat_nat_sum(s(X),Y,s(Z)) :- nat_nat_sum(X,Y,Z).
IN:
?- nat(X),nat(Y),nat_nat_sum(X,Y,Z) s5 Sols. Sols = [[nat(0), (nat(0), nat_nat_sum(0, 0, 0))], [nat(0), (nat(s(0)), nat_nat_sum(0, s(0), s(0)))], [nat(0), (nat(s(s(0))), nat_nat_sum(0, s(s(0)), s(s(0))))], [nat(0), (nat(s(s(...))), nat_nat_sum(0, s(s(...)), s(s(...))))], [nat(0), (nat(s(...)), nat_nat_sum(0, s(...), s(...)))]] ; Sols = [[nat(0), (nat(s(s(s(s(s(...)))))), nat_nat_sum(0, s(s(s(s(s(...))))), s(s(s(s(s(...)))))))], [nat(0), (nat(s(s(s(s(...))))), nat_nat_sum(0, s(s(s(s(...)))), s(s(s(s(...))))))], [nat(0), (nat(s(s(s(...)))), nat_nat_sum(0, s(s(s(...))), s(s(s(...)))))], [nat(0), (nat(s(s(...))), nat_nat_sum(0, s(s(...)), s(s(...))))], [nat(0), (nat(s(...)), nat_nat_sum(0, s(...), s(...)))]] ; Sols = [[nat(0), (nat(s(s(s(s(s(...)))))), nat_nat_sum(0, s(s(s(s(s(...))))), s(s(s(s(s(...)))))))], [nat(0), (nat(s(s(s(s(...))))), nat_nat_sum(0, s(s(s(s(...)))), s(s(s(s(...))))))], [nat(0), (nat(s(s(s(...)))), nat_nat_sum(0, s(s(s(...))), s(s(s(...)))))], [nat(0), (nat(s(s(...))), nat_nat_sum(0, s(s(...)), s(s(...))))], [nat(0), (nat(s(...)), nat_nat_sum(0, s(...), s(...)))]] . ?- p(X) s5 Sols. Sols = [[1], [2], [3], [4], [5]] ; Sols = [[6], [7]].
The advantage is that you can simply add how many responses you want at the end of the query. Then you get lists of this length as answers, so they are not just written to the console, but can be used for further requests.