Indexing strategy on lists

I have the following utility predicate and was a little bit surprised that I was leaving a choice point behind, so I inserted the cut in the first clause. I thought that indexing of the list would lead to this cut being unnecessary, but it appears that is not the case. Is this because it is not the first argument, or a metapredicate?

/*
 * mapm(P:predicate,L:list,O:list,S0:any,SN:any) is nondet.
 *
 * Monadic map over state
 */
:- meta_predicate mapm(4,?,?,?,?).
mapm(_P,[],[],S,S) :-
    !.
mapm(P,[H|T],[HP|TP],S0,SN) :-
    call(P,H,HP,S0,S1),
    mapm(P,T,TP,S1,SN).
1 Like

Yes. Non-first argument indexing is currently only applied if first argument indexing doesn’t work and there are enough clauses. Improving that has been discussed several times. Bottom line, SWI-Prolog lacks smart indexing for static predicates of (say) less than 10 clauses that cannot be handled by first argument indexing.

So, you need an intermediate predicate. See e.g., ?- edit(maplist/3).

2 Likes