I am trying to implement a simple version of findall in Prolog without using the built-in findall or similar built-in predicates -- just as a learning exercise.
For example, suppose there is a relation a/1 in my database,
a(1).
a(11).
a(13).
and I want a relation like find_the_as(List) to give me List = [1,11,13].
I can do this with a "fail" based loop using assert and retract, but I am thinking there must be a recursive way to do this using an accumulator (and I am just not seeing it).
Thanks in advance!
for example:
a(1).
a(11).
a(13).
%
% collect all the N such that a(N)
% into a List
%
collect_n_such_that_a_of_n(List) :-
retractall(the_n_such_that_a_of_n(_)),
assert(the_n_such_that_a_of_n([])),
(
a(N),
the_n_such_that_a_of_n(As),
retractall(the_n_such_that_a_of_n(_)),
assert(the_n_such_that_a_of_n([N|As])),
fail
) ; true,
the_n_such_that_a_of_n(List).
Using this example:
then the query:
returns:
The example uses:
Unlike with findall, the resulting list does not contain duplicates. eg. if you add an extra
a(11)then the resulting list will still only contain one11.Unlike with findall, the elements in the resulting list are in reverse order to which they were found (i.e.
[13, 11, 1]rather than[1, 11, 13]).