Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Will using member within a forall clause in SWI-Prolog always output the elements in the same order?

Having recently got into Prolog I've been using it for a few simple tasks and began to wonder about using member within forall loops like the one in the trivial example below:

forall(member(A,[1,2,3,4]), print(A)).

In the case that you do something like this is it always true that forall will process the elements within the list in the same order every time its called? Does it have to be enforced by say doing something like:

A = [1,2,3,4], sort(A, B), forall(member(C,B), print(C)).

From what little research I've initially done I'm guessing that it comes down to the behaviour of member/2 but the documentation for the function on SWI-Prolog's website is very brief. It does however mention determinism with regards member/2 which gave me an inkling I might be on the right path in saying that it would always extract the elements in the same order, though I'm far from certain.

Can anyone give me any guarantees or explanations on this one?

like image 231
Jonathan Rainer Avatar asked Feb 03 '14 16:02

Jonathan Rainer


1 Answers

Non-determinism in Prolog simply refers to a predicate having potentially more than one solution. Clearly, member/2 is such a predicate. This does not mean that you have to be worried about your computation becoming unpredictable. Prolog has a well-defined computation rule which essentially says that alternative solutions are explored in a depth-first, left-to-right manner. Thus your goal member(X,[1,2,3,4]) will generate solutions to X in the expected order 1,2,3,4.

Sorting the list [1,2,3,4] will not make any difference, as it is already sorted (according to Prolog's standard term order).

A word of caution about forall/2: some Prologs define this, but it is probably less useful than you imagine, because it is not really a "loop". You can use it in your example because you only perform a print side effect in each iteration. For most other purposes, you should familiarize yourself with recursive patterns like

print_list([]).
print_list([X|Xs]) :- print(X), print_list(Xs).
like image 134
jschimpf Avatar answered Oct 11 '22 15:10

jschimpf