生成列表 - 几何级数
Generate list - geometric progression
我想使用具有 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 参数谓词(在列表长度达到一定数字后停止生成更多数字)?
好吧,正如您所问,包括长度参数在内,当列表的长度为 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]
您可以找到从长度 1 到选定长度的所有解决方案,使用元谓词 findall/3
:
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
使用 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].
只需添加一个倒计时参数即可,并且会保留您代码的良好生成 属性:
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 'list generator':
gengeom(L,H,Q,N) :-
findall(V, (between(H,N,M), V is Q**(M-1)), L).
但是这个片段(类似于@joel76' post)将只构建 'final' 列表...
我想使用具有 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 参数谓词(在列表长度达到一定数字后停止生成更多数字)?
好吧,正如您所问,包括长度参数在内,当列表的长度为 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]
您可以找到从长度 1 到选定长度的所有解决方案,使用元谓词 findall/3
:
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
使用 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].
只需添加一个倒计时参数即可,并且会保留您代码的良好生成 属性:
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 'list generator':
gengeom(L,H,Q,N) :-
findall(V, (between(H,N,M), V is Q**(M-1)), L).
但是这个片段(类似于@joel76' post)将只构建 'final' 列表...