编写Prolog代码,返回给定数字的整数和列表

时间:2015-12-02 20:02:07

标签: list prolog dcg

我试图编写一个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].

这就是我要使用的内容,它开始逐个浏览列表。但是,我不确定在哪里应该添加规则来查找XInput之间的差异。

2 个答案:

答案 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.