I'd like to generate a geometric progression list using a predicate with 4 parameters - the list where the progression will be generated, the length of this list, the start element, and the multiplier of the progression. What I've done so far is having only a 3-parameter predicate to generate the geometric progression without stopping :
gengeom([X],X,_).
gengeom([H|Tail],H,Q):-X is H*Q,gengeom(Tail,X,Q).
And this query gives me all progressions with start element 1 and multiplier 2 :
?-gengeom(L,1,2),write(L),nl,fail.
Can anyone help me write the 4-parameter predicate I'd really like to have (that stops generating any more numbers after the length of the list has become a certain number) ?
just adding a countdown parameter will work, and will preserve the nice generative property of your code:
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.
of course, you could get somewhat more compact using findall/3, the Prolog 'list generator':
gengeom(L,H,Q,N) :-
findall(V, (between(H,N,M), V is Q**(M-1)), L).
but this snippet (similar to @joel76' post) will build just the 'final' list...
With SWI-Prolog, you can write :
:- use_module(library(lambda)).
gengeom(Len, Start, Multiplier, L) :-
length(L, Len),
foldl(\X^Y^Z^(X = Y,
Z is Y * Multiplier),
L, Start, _).
For example :
?- gengeom(5, 1, 2, L).
L = [1, 2, 4, 8, 16].
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With