Value_list/3 - Construct a list of same value

Often one needs a list of a specific length with all values set to a specific value, e.g.

[0, 0, 0, 0, 0]

As Jan W. notes (next reply)

value_list(Length,Value,L) :-
    length(L,Length),
    maplist(=(Value),L).

The way I first did it has been moved to this reply.

What about this?

value_list(Length,Value,L) :-
    length(L,Length),
    maplist(=(Value),L).

Thanks. :slightly_smiling_face:

I learn more from you by showing my wrong ways then you showing me the right way.



Here is the original post where I did it the harder way before Jan W. showed the better way.

I leave it here because it is one of the few simple working examples of libary(yall) using bracy list.


value_list(Length,Value,L) :-
    length(L0,Length),
    maplist({Value}/[_,Value]>>true,L0,L).

Example usage:

?- value_list(5,0,L).
L = [0, 0, 0, 0, 0].

How this works.

length/2 is often used to generate list of variables of a given size, e.g.

?- length(L,5).
L = [_, _, _, _, _].

Normally when a list of variables is displayed, if the variable is not bound to a value it is displayed as _ but the variables really are different variables, e.g.

?- length(L,5),numbervars(L).
L = [A, B, C, D, E].

Now to get the desired result (list of values) the value just needs to be bound to each variable. maplist/3 should come to mind.

maplist/3 is often written using a helper predicate for the goal but using library(yall) a Lambda can be used, e.g.

maplist([_,0]>>true,L0,L).

However if one tries to use a variable for the value, e.g.

maplist([_,Value]>>true,L0,L).

it will not work as expected.

With library(yall) one has to be careful with the variables used in the Lambda. Under the coves library(yall) (src) makes use of copy_term_nat/2 but library(yall) also provides a means to resolve the problem.

A bracy list {...} specifies which variables are shared between the wrapped goal and the surrounding context.

Thus Value can be shared outside of the Lambda and inside the Lambda when identified in the bracy list, i.e. {Value}, e.g.

maplist({Value}/[_,Value]>>true,L0,L)

It took me a long time to realize that it is possible to pass arguments to the goal in maplist (as you do with =(Value) in your solution, and I have some difficulties deciphering how this works more exactly from the documentation here. Are there other parts of the docs that cover this more in detail?

EDIT:
For those interested there is more info about this on this page, which is linked to in the docs.

See also call/2,… which is what is used by maplist. For example,

maplist(f(x), L1, L2)

calls call(f(x), H1, H2) where H1 and H2 are elements from L1 and L2.

There is a whole array of examples attached to maplist/2, right there under the docs. Several of them show how to use maplist with what I think is called partial application? “Filling” a list is there among the examples, too. :sweat_smile: You just need to click on the descriptive title of the example to expand it.

2 Likes

Thanks! Now i understand better.

I missed that :see_no_evil: