Choice points with lists

I’m using: SWI-Prolog version 9.0.4 for x86_64-linux

With

a(1).
a(2).

Querying a(1) seems to “yield a single choice point” as the REPL finishes immediately and does not prompt for another answer.

However, with the program

a([_]).
a([_, _]).

Querying with a([1]) returns true but prompts for another answer.
Is a choice point being created for a([_, _])? if so, why since a([_, _]) does not unify with `a([1])

Where did you find this terminology? I would have said that “there are no choice points” after ?- a(1).

A choice point means there might be additional solutions. In this case there might be, but upon further computation it turns out that there are none.

In some cases the Prolog implementation can correctly predict that there will be no more solutions. This is somehow related to the topic of indexing.

From myself, mostly due to a lack of understanding of Prolog implementation :slight_smile: Thanks for the correction.

I think this is the answer I was looking for, thanks for the rabbit hole to explore :slight_smile:

1 Like

The indexing distinction for lists is [] (empty list) vs [_|_] (non-empty list).

[_] and [_, _] are both non-empty lists, so have no indexing distinction between them.

Perhaps they could be put inside meaningful terms having different term names, so that the term name is the indexing distinction? This depends on the meaning/significance/classification of 1 vs 2 elements in the list, of course. Basic example:

a(one([_])).
a(two([_, _])).
?- a(one(L)).
L = [_].  % No unwanted choicepoint
1 Like

You can rewrite it into, like in the Gertjan van Noord trick:

a([_|T]) :- a2(T).

a2([]).
a2([_]).

It doesn’t show a spurious choice point anymore:

?- a([1]).
true.
1 Like

An easy fix is to use table/1, e.g.:

:- table a/1.
a([_]).
a([_, _]).

Results, showing no unwanted choicepoint:

?- a([1]).
true.

?- a([_]).
true.