# Given a list of numbers, returns a list such that the numbers in the input are replaced by the result of num2list,

**URL:** <https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271>\
**Category:** Help!\
**Created:** [February 13, 2019, 2:48pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271 "2019-02-13T14:48:49Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gretta](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/gretta/32/100_2.png) [@Gretta](https://swi-prolog.discourse.group/u/Gretta)\
**Post date:** [February 13, 2019, 2:48pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/1 "2019-02-13T14:48:49Z")

</div>

I’m using: SWI-Prolog version 8.0.1

I am new in prolog so please don’t be to strict. I want to write a prolog program that given a list of numbers, returns a list such that the numbers in the input are replaced by the result of num2list, when they are followed by a bigger number, and otherwise skipped. When the list has only one number, this should also be replaced with the result of num2list. For example, if the input is [2,4,1,3,4,3,2,1], the result is [[0,1,2],[0,1],[0,1,2,3],[0,1]].

Any help would be appreciated.

Also could anyone suggest a good prolog tutorial?

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [February 13, 2019, 3:36pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/2 "2019-02-13T15:36:44Z")

</div>

I think `maplist/3` will be what you want: [http://www.swi-prolog.org/pldoc/doc\_for?object=maplist/3](http://www.swi-prolog.org/pldoc/doc_for?object=maplist/3) (e.g. `?- maplist(num2list, Input, Output).`)

For tutorials, Annie’s tutorials [here](http://www.pathwayslms.com/swipltuts/) were my introduction. Markus Triska’s stuff [here](https://www.metalevel.at/prolog) is also very good.

---

<div class="post-metadata">

**Author:** ![Gretta](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/gretta/32/100_2.png) [@Gretta](https://swi-prolog.discourse.group/u/Gretta)\
**Post date:** [February 13, 2019, 6:34pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/3 "2019-02-13T18:34:33Z")

</div>

Thank you for your reply James. If i want to implement it without maplist. How can i do that?

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [February 13, 2019, 8:57pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/4 "2019-02-13T20:57:37Z")

</div>

You can using the `listing/1` predicate to see the source of a predicate; e.g.,

```auto
listing(maplist/3).
:- meta_predicate apply:maplist(2,?,?).

apply:maplist(Goal, List1, List2) :-
    maplist_(List1, List2, Goal).

true.

?- listing(maplist_/3).
apply:maplist_([], [], _).
apply:maplist_([Elem1|Tail1], [Elem2|Tail2], Goal) :-
    call(Goal, Elem1, Elem2),
    maplist_(Tail1, Tail2, Goal).

true.

```

From that then, we can see that the equivalent code without maplist will look like this:

```auto
num2list_each([], []).
num2list_each([Num|NumRst], [NumList|NumListRst]) :- 
   num2list(Num, NumList),
   num2list_each(NumRst, NumListRst). 

```

---

<div class="post-metadata">

**Author:** ![Gretta](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/gretta/32/100_2.png) [@Gretta](https://swi-prolog.discourse.group/u/Gretta)\
**Post date:** [February 13, 2019, 11:29pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/5 "2019-02-13T23:29:31Z")

</div>

Sorry for my stupidness but how sample call will look like in this case?

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [February 14, 2019, 12:30am UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/6 "2019-02-14T00:30:32Z")

</div>

No problem! After defining the above `num2list_each/2` predicate, as well as `num2list/2`, you would use it like so:

```auto
?- num2list_each([2, 4, 1, 3], Out).
Out = [[0,1,2], [0,1,2,3,4], [0, 1], [0, 1, 2, 3]]
true.

```

---

<div class="post-metadata">

**Author:** ![Boris](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/boris/32/7486_2.png) [@Boris](https://swi-prolog.discourse.group/u/Boris)\
**Post date:** [February 14, 2019, 8:41am UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/7 "2019-02-14T08:41:45Z")

</div>

> [@Gretta](#):
>
> Also could anyone suggest a good prolog tutorial?

I know this doesn’t answer your question, but I strongly recommend [“The Art of Prolog” by Sterling and Shapiro](https://mitpress.mit.edu/books/art-prolog). It is much better than the tutorials I have found online. The book’s website now has a download link for the complete PDF.

It depends how deep you want to go, but the book is beginner-friendly, thorough, and well written. You don’t have to read it to the very end to make good use of it.

---

<div class="post-metadata">

**Author:** ![Gretta](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/gretta/32/100_2.png) [@Gretta](https://swi-prolog.discourse.group/u/Gretta)\
**Post date:** [February 15, 2019, 3:51pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/8 "2019-02-15T15:51:13Z")

</div>

IDK why i get these errors:  
ERROR: Undefined procedure: num2list/2  
ERROR: In:  
ERROR: [9] num2list(2,\_3284)  
ERROR: [8] num2list\_each([2,4|…],[\_3326|\_3328]) at c:/users/user/desktop/prolog/prolog-examples-master/num2list2.pl:3  
ERROR: [7]

---

<div class="post-metadata">

**Author:** ![Gretta](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/gretta/32/100_2.png) [@Gretta](https://swi-prolog.discourse.group/u/Gretta)\
**Post date:** [February 15, 2019, 3:52pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/9 "2019-02-15T15:52:12Z")

</div>

Thank you for your reply Boris. And thank you for your book suggestion. I will take a look. Hope it will help.

---

<div class="post-metadata">

**Author:** ![jamesnvc](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/jamesnvc/32/14_2.png) [@jamesnvc](https://swi-prolog.discourse.group/u/jamesnvc)\
**Post date:** [February 15, 2019, 4:41pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/10 "2019-02-15T16:41:10Z")

</div>

The stuff I wrote was assuming you’d already defined `num2list`, that error is indicating that you haven’t done so yet.

---

<div class="post-metadata">

**Author:** ![CapelliC](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/capellic/32/17_2.png) [@CapelliC](https://swi-prolog.discourse.group/u/CapelliC)\
**Post date:** [February 19, 2019, 5:33pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/11 "2019-02-19T17:33:41Z")

</div>

Once upon a time, findall/3, was the swiss knife of basic list processing. Coupled with nondeterministic accessors (like member/2, between/3, nth1/3, arg/3, append/3, etc etc) it provide common functionality in a fairly efficient and compact way.

for instance,

```
 num2list(N,Ns) :- findall(I, between(0,N,I), Ns).
```

---

<div class="post-metadata">

**Author:** ![CapelliC](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/capellic/32/17_2.png) [@CapelliC](https://swi-prolog.discourse.group/u/CapelliC)\
**Post date:** [February 19, 2019, 5:40pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/12 "2019-02-19T17:40:14Z")

</div>

oops, first time I use Discourse’ editor, I wrongly hit enter … let’s continue

```auto
num2list_each(Ns,Ls) :- 
    findall(L, (append(_, [A,B|_], Ns), A<B, num2list(A,L)), Ls).

?- num2list_each([2,4,1,3,4,3,2,1],Ls).
Ls = [[0, 1, 2], [0, 1], [0, 1, 2, 3]].

```

There is an obvious bug, wrt the missing num2list of the last element. Next we’ll see how to fix that, refining the _goal_ that is executed by findall/3, the 2nd argument.

---

<div class="post-metadata">

**Author:** ![CapelliC](https://yyz2.discourse-cdn.com/free1/user_avatar/swi-prolog.discourse.group/capellic/32/17_2.png) [@CapelliC](https://swi-prolog.discourse.group/u/CapelliC)\
**Post date:** [February 19, 2019, 6:14pm UTC](https://swi-prolog.discourse.group/t/given-a-list-of-numbers-returns-a-list-such-that-the-numbers-in-the-input-are-replaced-by-the-result-of-num2list/271/13 "2019-02-19T18:14:30Z")

</div>

Well, now correcting the bug about the last element, hope you can see the pattern…

```
num2list_each(Ns,Ls) :-
    findall(L, (append(_,T,Ns),
            (T=[A,B|_], A<B ; T=[A]),
            num2list(A,L)), Ls).

num2list(N,Ns) :-
    findall(I, between(0,N,I), Ns).
```
