Prolog将n写为连续数之和

Prolog将n写为连续数之和,prolog,Prolog,我在学习prolog,我想确定n的所有分解(n给定,正),作为连续自然数的和,但我不知道如何处理这个问题 有什么想法吗?这里的关键是介于/3之间,它涉及数字和范围。Prolog不会凭空变出数字,你必须给它一些线索。在这种情况下,您可以假设给定的数字范围在1和n之间: decomp2(N, X, Y) :- between(1, N, X), between(1, N, Y), N =:= X + Y. 这将给出两个数字的总和,得出N: ?- decomp2(5, X,

我在学习prolog,我想确定n的所有分解(n给定,正),作为连续自然数的和,但我不知道如何处理这个问题


有什么想法吗?

这里的关键是
介于/3
之间,它涉及数字和范围。Prolog不会凭空变出数字,你必须给它一些线索。在这种情况下,您可以假设给定的数字范围在1和n之间:

decomp2(N, X, Y) :-
    between(1, N, X),
    between(1, N, Y),
    N =:= X + Y.
这将给出两个数字的总和,得出N:

?- decomp2(5, X, Y).
X = 1,
Y = 4 ;

X = 2,
Y = 3 ;

X = 3,
Y = 2 ;

X = 4,
Y = 1 ;
一旦可以得到两个值,就可以通过
decomp2/2
删除一个值,并通过归纳得到其余值,从而得到一个更长的列表。您只需要提出一个基本情况,例如N的单例列表:

decomp(N, [N]).
decomp(N, [X|L]) :- decomp2(N, X, Y), decomp(Y, L).
请注意,这将产生大量重复

?- decomp(5, L).
L = [5] ;
L = [1, 4] ;
L = [1, 1, 3] ;
L = [1, 1, 1, 2] ;
L = [1, 1, 1, 1, 1] ;
L = [1, 1, 2, 1] ;
L = [1, 2, 2] ;
L = [1, 2, 1, 1] ;
L = [1, 3, 1] ;
L = [2, 3] ;
L = [2, 1, 2] ;
L = [2, 1, 1, 1] ;
L = [2, 2, 1] ;
L = [3, 2] ;
L = [3, 1, 1] ;
L = [4, 1] ;

您可能可以通过引入订购要求来抑制重复,例如X大于Y。

我已经找到了解决方案,它看起来像这样:

备注:在isConsecutive中,当列表本身就是数字时,我会去掉“解决方案”

% equal with the given parameter N.
% generatePair(N - integer, X - integer, Y - integer)
% generatePair(i,o,o)
% generatePair(N) = { (X,Y), X<Y && X+Y=N
generatePair(N, X, Y) :-
    my_between(1, N, Y),
    my_between(1, N, X),
    X < Y,
    N =:= X + Y.

% This predicate decomposes the given number N into a list of integers
% such that their sum is equal to N.
% decomposeNumber(N - integer, L - list)
% decomposeNumber(i,o)
% decomposeNumber(N) = { [X|L]
decomposeNumber(N, [N]).
decomposeNumber(N, [X|L]) :- generatePair(N, X, Y), decomposeNumber(Y, L).

% This predicate checks it the that elements in the given list have
% consecutive value.
% isConsecutive(L - list)
% isConsecutive(i)
% isConsecutive([l1,l2,..,ln]) = { true, L=[l1,l2] && l1+1=l2
%                                { isConsecutive(l2..ln), l1+1=l2 && n>2
%                                { false, otherwise
isConsecutive([X,Y]):-X+1=:=Y.
isConsecutive([H1,H2|T]):-H2=:=H1+1, isConsecutive([H2|T]).

nAsSumOfConsecutives(N,L):-decomposeNumber(N,X), isConsecutive(X), L=X.

main(N,L):-findall(R,nAsSumOfConsecutives(N,R),L).
%与给定参数N相等。
%generatePair(N-整数、X-整数、Y-整数)
%发电机空气(i、o、o)
%generatePair(N)={(X,Y),X2
%{否则为假
isConsecutive([X,Y]):-X+1=:=Y。
isConsecutive([H1,H2 | T]):-H2=:=H1+1,isConsecutive([H2 | T])。
nassumofconceutives(N,L):-decomposeNumber(N,X),isconsecuritive(X),L=X。
main(N,L):-findall(R,nassumofconceutives(N,R,L)。