Search code examples
prologclpfd

How to sum the results without findall


Is there an efficient and generic way of summing up results without generating an intermediate list:

main(A) :-
  B #< 4000000,
  B mod 2 #= 0,
  findall(B, fibonacci(_, B), Bs), 
  sum_list(Bs, A).

Note: this is Project Euler #2.


Solution

  • You can use predicate [aggregate_all/3][1] to do the aggregation without generating the intermediate list (runs in constant memory with SWI and I guess also with SICStus).

    Instead of using findall/3 + sum_list/2 use aggregate_all(sum(B), ..., Sum):

    euler2(Sum):-
      B #< 4000000,
      B mod 2 #= 0,
      aggregate_all(sum(B), fibonacci(_, B), Sum).