我试图编写一个Prolog谓词,它可以使用DCG将给定的非负整数分解为每个可能的总和。
例如:
?- s(3, L, []).
L = [3] ? ;
L = [2,1] ? ;
L = [1,2] ? ;
L = [1,1,1] ? ;
false.
我开始编写一个带有数字N
并返回L = [1,2,3,...,N]
的谓词:
mkList(N, L) :-
m(0, N, L).
m(X, X, []).
m(Y, L, [H|T]) :-
H is Y+1,
m(H, L, T).
但是,我不知道如何继续。
s(Input) -->
{ mkList(Input, InputList) },
{ member(X, InputList) },
[X].
这就是我要使用的内容,它开始逐个浏览列表。但是,我不确定在哪里应该添加规则来查找X
和Input
之间的差异。
答案 0 :(得分:0)
最好的方法是像Prolog一样思考,即递归。是的,你有递归。它甚至可能是对的,但我没有遵循它。
这样的思考应该有效:
mkList(Number,List) :-
pick a number between 1 and number. It'll be your first addend.
subtract it from number to get the remainder.
make a recursive call to handle the remainder.
patch together List based on the first addend and the list from the recursive call.
显然,当Number小于1时我们需要停止。
这不使用DCG,但就我而言,我无法看到DCG的相关性。
答案 1 :(得分:0)
基本案例很简单:
all_sum(N) --> [N].
现在,如果我们提供M between 1和N,我们可以递归调用,并取其余R(注意它必须是> 0)
all_sum(N) --> {...},[M],all_sum(R).
请使用上面的提示填写点。 你会得到
?- phrase(all_sum(3),L).
L = [3] ;
L = [1, 2] ;
L = [1, 1, 1] ;
L = [2, 1] ;
false.