1
votes

I have a certain list which is generated from a predicate and looks like this:

[a, b, c]

I also have a following predicate p/3 that could be applied to each element of my list:

?- p(a, NewList, Number).

and it will return:

NewList = [c, d],
Number = 2.

where NewList is a newly generated list from a element, and Number is the NewList length.

Problem:

I want to apply the p/3 predicate to all elements, and get

  1. one list which consists of all elements from all NewLists aka all NewLists appended together
  2. and the sum of all Numbers.

I tried to do it like this:

loop_list([Element|[]], NewList, Number) :-
    p(Element, NewList, Number).
loop_list([Head|Tail], [Tmp|NewList], Number) :-
    loop_list(Tail, Tmp, Number).

but failed.

1

1 Answers

0
votes

It is often better to separate your concerns, and solve one task at once. You can use maplist/4 [swi-doc] here to call the predicate over all the elements in the list. This will then unify the third and the fourth element with the results of p/3.

Next we can make use of append/2 [swi-doc] to append lists together, and sumlist/2 [swi-doc] to sum the elements of a list together.

We thus can implement this as:

loop_list(Ls, Xs, Sum) :-
    maplist(p, Ls, Xss, Items),
    append(Xss, Xs),
    sumlist(Items, Sum).