生成列表 - 几何级数

时间:2015-07-04 22:34:31

标签: list prolog

我想使用带有4个参数的谓词生成几何级数列表 - 将生成进度的列表,此列表的长度,开始元素和进度的乘数。到目前为止我所做的只是一个3参数谓词来生成几何级数而不停止:

gengeom([X],X,_).
gengeom([H|Tail],H,Q):-X is H*Q,gengeom(Tail,X,Q).

此查询为我提供了启动元素1和乘数2的所有进度:

?-gengeom(L,1,2),write(L),nl,fail.

任何人都可以帮我写一个我真正想要的4参数谓词(在列表长度变成某个数字后停止生成更多数字)?

3 个答案:

答案 0 :(得分:6)

只需添加倒计时参数即可,并保留代码的良好生成属性:

gengeom([X],X,_,_).
gengeom([H|Tail],H,Q,N) :- N>1, M is N-1, X is H*Q, gengeom(Tail,X,Q,M).

?- gengeom(L,1,2,3).
L = [1] ;
L = [1, 2] ;
L = [1, 2, 4] ;
false.

当然,使用findall / 3,Prolog'列表生成器'可以让你更紧凑:

gengeom(L,H,Q,N) :-
    findall(V, (between(H,N,M), V is Q**(M-1)), L).

但是这个片段(类似于@ joel76'帖子)只会构建'最终'列表......

答案 1 :(得分:5)

使用SWI-Prolog,您可以写:

:- use_module(library(lambda)).

gengeom(Len, Start, Multiplier, L) :-
    length(L, Len),
    foldl(\X^Y^Z^(X = Y,
                 Z is Y * Multiplier),
          L, Start, _).

例如:

?- gengeom(5, 1, 2, L).
L = [1, 2, 4, 8, 16].

答案 2 :(得分:0)

好吧,正如你所问,包括长度参数你需要在列表长度为1时将停止条件更新为真,而通用子句必须在每一步减少这个长度。
现在gengeom/4谓词将如下所示:

gengeom([X], X ,_, 1):- !.
gengeom([H|Tail], H, Q, N):-N > 0, X is H * Q, N1 is N - 1, gengeom(Tail, X, Q, N1).

这可以通过开始1,乘数2和长度5找到进展

?- gengeom(L, 1, 2, 5).
L = [1, 2, 4, 8, 16]

您可以使用metapredicate findall/3找到从长度1到所选长度的所有解决方案:

findall(L, (member(N, [1,2,3,4,5]), gengeom(L,1,2, N)), R).

这应该是完整的:

gengeom([X], X ,_, 1):- !.
gengeom([H|Tail], H, Q, N):-N > 0, X is H * Q, N1 is N - 1, gengeom(Tail, X, Q, N1).

generate(Start, Step, Stop):- findall(L, (numlist(1,Stop, Len), member(N, Len), gengeom(L,Start,Step, N)), R), writeGen(R).

writeGen([]).
writeGen([H|Tail]):- write(H), nl, writeGen(Tail).

测试

?- generate(1, 2, 5).
[1]
[1, 2]
[1, 2, 4]
[1, 2, 4, 8]
[1, 2, 4, 8, 16]
true