I want to write all of a list in prolog. But the problem is I don't want to use recursion. So I want to to this iteratively.
-
If by *writing all the list* you mean *writing to output all elements in the list*, you could use `forall/2`: `forall(member(X, L), write(X).`. – Tudor Berariu Jun 11 '14 at 13:35
-
@TudorBerariu: `member/2` is recursively defined. – false Jun 11 '14 at 13:37
-
As you said, you cannot avoid recursion. I assumed he wants to avoid writing explicit recursive predicates. Of course you are right, `member/2` uses recursion. – Tudor Berariu Jun 11 '14 at 13:39
-
Why don't you want to use recursion? – lurker Jun 11 '14 at 13:44
2 Answers
Strictly speaking, there is no way how you can avoid recursion when you want to express some relation about all (or sufficiently many) elements in a list. However, you might delegate the recursive part to some library predicate.
Take the maplist-family as an example. Say maplist(=(_), Xs)
which describes all lists whose elements are the same. To you, there is no longer any recursion. But behind, there is a recursive definition:
maplist(_C_1, []).
maplist(C_1, [E|Es]) :-
call(C_1, E),
maplist(C_1, Es).
There are also other ways to realize shortcuts for recursive predicates, like do-loops and B-Prolog's loops. But ultimately, they all translate to some recursive definition (or call recursive predicates).
There is really no reason to worry about using recursion in Prolog. After all, systems are quite optimized to handle recursion efficiently. Often, recursive predicates "run like" simple loops in imperative programming languages. Also, memory allocation is very well targeted to clean up intermediary/volatile data.
With Swi-Prolog, I have been experimenting with the fact that findall/3 unifies it's last list-argument, aka. it can "run on reverse" or input/output swapped, something like this findall(,,[a,b,c])
Then I came up with this:
Li=[a,b,c,d,e,f,g,h],findall(A, (append(A,B,Li),B=[C|_],writeln(C)), _).
A and B gets instantiated to sublists
Even this works!!
Li=[a,b,c,d,e,f,g,h],findall(_, (append(_,B,Li),B=[C|_],writeln(C)), _).
http://swish.swi-prolog.org/p/oMEAdQWk.pl
Well I don't know how efficient the code is, propably is not efficient. And you should first learn the recursive rules of Prolog :)

- 122
- 1
- 8