Using maplist with many arguments: Example

The current maplist implementation allows up to 4 lists. Here is what happens if you happen to have a predicate with more than 4 arguments:

$ cat maplistexample.pl
sum_products(A, B, C, D, R) :-
    R is A+B * C+D.

sum_products_lists(As, Bs, Cs, Ds, Rs) :-
    maplist(sum_products, As, Bs, Cs, Ds, Rs).

This compiles but throws an error at run-time:

?- [maplistexample].
true.

?- sum_products_lists([1,2], [3,4], [5,6], [7,8], Result).
ERROR: Unknown procedure: maplist/6
ERROR: In:
ERROR:   [11] maplist(sum_products,[1,2],[3,4],[5,6],[7,8],_22184)
ERROR:   [10] sum_products_lists([1,2],[3,4],[5,6],[7,8],_22264) at maplistexample.pl:5
ERROR:    [9] toplevel_call(user:user: ...) at swipl/lib/swipl/boot/toplevel.pl:1113
   Exception: (11) maplist(sum_products, [1, 2], [3, 4], [5, 6], [7, 8], _11284) ? abort

One work-around is to use library(apply_macros).

:- use_module(library(apply_macros)).

sum_products(A, B, C, D, R) :-
    R is A+B * C+D.

sum_products_lists(As, Bs, Cs, Ds, Rs) :-
    maplist(sum_products, As, Bs, Cs, Ds, Rs).

… and then:

?- make.
%  library(apply_macros) compiled into apply_macros 0.00 sec, 53 clauses
% maplistexample compiled 0.00 sec, 3 clauses
true.

?- sum_products_lists([1,2], [3,4], [5,6], [7,8], Result).
Result = [23, 34].

Good. Note that instead of calling you could do

?- list_undefined.

For people who want to play with this, I can grant write access to the examples github repo. I plan to add a webhook, so the changes are immediately visible on the backend servers.

If you want access, respond by direct message with your github user name. Of course, anyone can fork and make pull requests.

This sounds a good enough approach for me at least.

About list_undefined: Now that I read the docs, I finally understand why ?- make. shows things that I don’t see otherwise (the reason is that make/0 runs list_undefined/0).

1 Like