Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate list - geometric progression

Tags:

list

prolog

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) ?

like image 478
Viktor Anastasov Avatar asked Dec 03 '25 09:12

Viktor Anastasov


2 Answers

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

like image 65
CapelliC Avatar answered Dec 06 '25 00:12

CapelliC


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].
like image 30
joel76 Avatar answered Dec 06 '25 01:12

joel76



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!