Does SWI-Prolog do any simple transformations to remove duplicate patterns? For example, a simple mechanical transformation of Boris’ code for select/3
(with different variable names)
select(Head, [Head|Rest], Rest).
select(Select, [Head|Rest1], [Head|Rest2]) :-
select(Select, Rest1, Rest2).
gives
select(Select, [Head|Rest1], Rest2) :-
select2(Select, Head, Rest1, Rest2).
select2(Head, Head, Rest, Rest).
select2(Select, Head, Rest1, [Head|Rest2]) :-
select(Select, Rest1, Rest2).
which probably ends up generating one or two more virtual machine instructions than the code in library(lists)
:
select(X, [Head|Tail], Rest) :-
select3_(Tail, Head, X, Rest).
select3_(Tail, Head, Head, Tail).
select3_([Head2|Tail], Head, X, [Head|Rest]) :-
select3_(Tail, Head2, X, Rest).
The transformation in library(lists)
for member/2
merely flips the arguments, presumably from the time when only first argument indexing happened.
And I’m curious what happens with something like
pred([X|Xs], ...) :-
pred1(X),
pred2([X|Xs], ...).
… does it get transformed to something like this (with “deep” indexing)
pred([Arg1, ...) :-
Arg1=[X|Xs],
pred1(X),
pred2(Arg1, ...).
(I see this pattern fairly often in some of my code).