I want to know how smart first argument indexing is implemented on various Prolog implementations.
In particular, simple type-test goals like integer/1
right after a clause "neck" could contribute to better indexing.
Consider:
foo(h(X),X).
foo([],nil).
foo([_|_],cons).
foo(X,Y) :- integer(X), Y = n(X).
With this clause ordering I would like the goal foo([],_)
to succeed without leaving any useless choicepoints.
Unfortunately, SWI Prolog does not figure it out:
?- length(Xs,10),
maplist(=([]),Xs),
statistics(trailused,T1),
maplist(foo,Xs,Ys),
statistics(trailused,T2).
T1 = 5792,
T2 = 5968,
Xs = [[], [], [], [], [], [], [], [], [], []],
Ys = [nil, nil, nil, nil, nil, nil, nil, nil, nil, nil] ...
Do other Prolog implementations do better?
foo(X,Y) when nonvar(X)
, it gets quite illogical forX
being a variable: The first three clauses succeed, while the last fails. Optimizing for this particular mode appears to be a waisted effort: It would not occur in any pure program. – false