Scope of library(apply_macros)

Whats the scope of library(apply_macros). Somebody observed a drastic timing difference between SWI-Prolog 8.3.4 and SWI-Prolog 8.3.21. The predicate match2/3 is mutch faster in SWI-Prolog 8.3.4 than in SWI-Prolog 8.3.21.

I am a little bit investigating why this is so. I found that library(apply_macros) had a problem with a maplist. It did this one:

gimme_random_sequence(Length, Seq) :-
    length(Seq, Length),
    '__aux_maplist/2___aux_yall_8f8726bfc6600d3eda1280a41de9749e3ff1252c+0'(Seq).

But it didn’t do this one:

?- listing(match2/3).
match2(Seq1, Seq2, Count) :-
    (   maplist([X, Y, X-Y]>>true,
                Seq1,
                Seq2,
                Seq3)
    ->  aggregate_all(count,
                      ( member(X-X, Seq3),
                        X\='_'
                      ),
                      Count)
    ;   Count=0
    ).

Is this a bug or feature? Should I use a different variable name in the aggregate?

Open source:

Sequence Match Problem
https://gist.github.com/jburse/9fd22e8c3e8de6148fbd341817538ef6#file-sequence-pl

You should make sure that all related meta-predicates are loaded. So, for sanity

:- use_module(library(apply)).
:- use_module(library(yall)).

match2(Seq1, Seq2, Count) :-
   (   maplist([X,Y,X-Y]>>true, Seq1, Seq2, Seq3)
   ->  aggregate_all(count, (member(X-X, Seq3), X\='_'), Count)
   ;   Count = 0 ).
101 ?- listing(match2/3).
match2(Seq1, Seq2, Count) :-
    (   '__aux_maplist/4___aux_yall_0bb6d431494e13373fc7f7cf18d02cb8ec8e1313+0'(Seq1,
                                                                                Seq2,
                                                                                Seq3)
    ->  aggregate_all(count,
                      ( member(X-X, Seq3),
                        X\='_'
                      ),
                      Count)
    ;   Count=0
    ).

For speed, also prefer X \== c over X \= c. Were \= has to do quite a bit of work, \==, in particular against an atomic constant is a really simple test. As in most cases the negation makes little sense before X is sufficiently instantiated this is probably better anyway.

1 Like