Nuances and usage tips on findall/4?

I’m using: SWI-Prolog version 8.0.2.

https://www.swi-prolog.org/pldoc/doc_for?object=findall/4

First, I want to make sure I understand findall/4. Is it accurate to say that when you pass findall/4 a list of solutions in the -Bag argument, it returns all the solutions in +Tail that are not already in -Bag?

If so, then would one use findall/4 to get a new set of solutions you have not already tried? For example, perhaps you have an app where new solutions become available over time and you only want to try new solutions?

Are there any other creative uses of findall/4 that would be useful to know about?

I think the idea is that if you want to build a list from the end, you want to use a difference list to make that efficient, and not have to use append.

For example,

% ugly/inefficient way
?- findall(X, member(X, [1,2,3,4]), S1),
    findall(X, member(X, [a,b,c,d]), S2), 
    append(S1, S2, Solns).
S1 = [1, 2, 3, 4],
S2 = [a, b, c, d],
Solns = [1, 2, 3, 4, a, b, c, d].

% using difference list + findall/4 - no append
?- findall(X, member(X, [1,2,3,4]), Solns, Tail),
    findall(X, member(X, [a,b,c,d]), Tail, []).
Solns = [1, 2, 3, 4, a, b, c, d],
Tail = [a, b, c, d].

Good example by @jamesnvc. The following tests for the predicate may also help clarify its semantics:

https://github.com/LogtalkDotOrg/logtalk3/blob/52e15bb251c0dd650241e344dd8786fcd6fada0d/tests/prolog/predicates/findall_4/tests.lgt

1 Like