Reading all facts, one at a time, without failure driven loop

Hello,

I am blanking of the following:

I have a list of facts, say, based on fact/1.

Edit: the facts are predefined in a file, and are in fact the outcome of term_expansion – i assume that there are all static terms, generated during consult.

I have a failure driven loop to read in each fact and process it:

process_facts :-
   fact(X),
   process(fact(X)),
   fail.

process_facts.

I want to do this without a failure driven loop, so i can distinguish between facts processing that failed, and processing a next fact.

I don’t want to use calls such as findall, since the list of facts could be large and i want to guarantee that i am processing the facts in the sequence they occurs in the source file.

Any thoughts are much appreciated,

Dan

ok, solved …

It needs to look like so:

process_facts :-
   fact(X),
   (process(X) -> true; (!, fail)),
   fail.

process_facts.

You could also do something like (untested - code might have typos)

forall(fact(X), process(X)).

This will fail if any process/1 fails. If you need to be more specific, you could do:

forall(fact(X), (process(X)->true;throw(error(failed(X), _)))).

Also, there is now concurrent_forall/2, for faster (but non-deterministic) processing.

3 Likes