Natti
Natti

Reputation: 101

Prolog: How do you iterate between two lists (nest for-loop)?

I just started learning Prolog this week so I am not sure if for-loops are possible in Prolog. I have two lists in Prolog

stringList([hi,hello],[bye,later],X).

How do I create a new solution list with one element per list?

So the output should be:

X = [hi,bye]
X = [hi,later]
X = [hello,bye]
X = [hello,later]

Upvotes: 3

Views: 368

Answers (1)

mat
mat

Reputation: 40768

A major advantage when using Prolog is that you can delegate such loops to the Prolog engine. You do not have to write them explicitly.

For example, in your case, think about the problem in this way: What holds (or should hold) about X?

We can say:

  1. X is a list with two elements, say [A,B].
  2. A is a member of the list that is denoted by the first argument.
  3. B is a member of the list that is denoted by the second argument.

So, in Prolog:

one_from_each(As, Bs, [A,B]) :-
    member(A, As),
    member(B, Bs).

Sample query:

?- one_from_each([hi,hello],[bye,later], X).
X = [hi, bye] ;
X = [hi, later] ;
X = [hello, bye] ;
X = [hello, later].

And it works in other directions too:

?- one_from_each(As, Bs, [hi,bye]).
As = [hi|_4656],
Bs = [bye|_4662] ;
As = [hi|_4656],
Bs = [_4660, bye|_4668] ;
As = [hi|_4656],
Bs = [_4660, _4666, bye|_4674] .

Hence, the whole question is somewhat misguided. When coding in Prolog, always ask: How can I formulate what ought to hold? Once you have such a formulation, you can leave the search for solutions to the Prolog engine!

If you want, you can be more explicit. For example:

one_from_each([], _) --> [].
one_from_each([L|Ls], Rs) -->
    one_from_each_(Rs, L),
    one_from_each(Ls, Rs).

one_from_each_([], _) --> [].
one_from_each_([R|Rs], L) -->
    [[L,R]],
    one_from_each_(Rs, L).

Example:

?- phrase(one_from_each([hi,hello],[bye,later]), Ls).
Ls = [[hi, bye], [hi, later], [hello, bye], [hello, later]].

This is sometimes called a spatial representation, because the solutions are now no longer found on backtracking (temporal representation), but represented explicitly.

From this, you see that "loops" correspond to recursive definitions.

Upvotes: 5

Related Questions