%% collect N elements produced by a generator in a row

take( 0, Next, Z-Z, Next).
take( N, Next, [A|B]-Z, NZ):- N>0, !, 
  next(Next,A,Next1),
  N1 is N-1,
  take(N1,Next1,B-Z,NZ).

%% A generator provides specific {next} implementation

next( hamm( A2,B,C3,D,E5,F,[H|G] ), H, hamm(X,U,Y,V,Z,W,G) ):- 
  H is min(A2, min(C3,E5)),
  (   A2 =:= H -> B=[N2|U],X is N2*2 ; (X,U)=(A2,B) ),
  (   C3 =:= H -> D=[N3|V],Y is N3*3 ; (Y,V)=(C3,D) ),
  (   E5 =:= H -> F=[N5|W],Z is N5*5 ; (Z,W)=(E5,F) ).

mkHamm(  hamm(1,X,1,X,1,X,X) ).              % int_overflow @ 20,000 already

  %% the output of time/1 is not shown in Ideone for some reason.

main(N) :- 
  statistics(inferences,I1),
  ( mkHamm(G),take(20,G,A-[],_),          write(A), nl, 
    take(1691-1,G,_,G2),take(2,G2,B-[],_),    write(B), nl,  
    take(  N  -1,G,_,G3),take(2,G3,[C1|_]-_,_),   write(C1), nl 
  ),
  statistics(inferences,I2),
  Infs is I2 - I1, nl, write('   '), write(Infs), write(' Infs'),
  true.

/*
ON INTS:

[1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 16, 18, 20, 24, 25, 27, 30, 32, 36]
[2125764000, 2147483648]

10k:   288325195312500000    58578 Infs    time:  0.05s    memory:  6204 kB


ON FLOATS (w/ overwhelming precision errors):

10,000     2.56494e+17       58578 Infs    time:  0.05s    memory:  6204 kB
100k:      5.14728e+24      508578 Infs    time:  0.51s    memory:  6204 kB
500k:      1.02580e+28     2508578 Infs    time:  4.22s    memory:  6204 kB     
1mln:      2.46193e+29     5008578 Infs    time: 12.94s    memory:  6204 kB 
*/