简体   繁体   中英

Return list in recursion

proceed(N, [H|T], [Output]) :-
   N > 0, NewN is N - 1, NewH is H - 1,
   proceed(NewN, T, [NewH|Output]).

The concept is that it will take the list and decrement first N - elements by 1, and assign the result list to variable Output. Eg. when I write query:

?-proceed(2, [3,2,1], Answer)

I would like it to "return":

Answer = [2,1,1].

How can I achieve this? I know I need some stop predicate, but can't think of one. If someone could provide an answer with good explanation I would be grateful.

There are two problems with your current code:

  • The lack of the base clause, which you have correctly identified, and
  • The way that you are building up the output list is the wrong way around.

Now let's consider these two points one by one. Loosely speaking, your base clause should describe what happens when no further processing is required. When exactly this happens depends on the problem at hand: a base clause may describe what happens when the input list is empty, when one or more parameters reach a particular state, or another similar situation.

In your case, the base clause needs to describe what happens when N becomes zero. The answer is simple: when N is zero, the input list is copied into output without changes. Hence, your base clause is

proceed(0, L, L).

You also need to deal with the situation when your list runs out of elements before N reaches zero:

proceed(_, [], []).

This is simple, too - if the input list is empty, the output should be empty as well, regardless of the value of N .

Now let's go back to your main clause. Your code correctly computes the next value of N and the head element, but instead of sticking them into the output, it puts them into the recursive invocation. Here is the corrected version:

proceed(N, [H|T], [NewH|Output]) :-
    N > 0,
    NewN is N - 1,
    NewH is H - 1,
    proceed(NewN, T, Output).

Now the NewH is added back to the Output in the header of the clause, making sure that the output "flows back" to the caller. This may appear counter-intuitive, but this is how Prolog works.

Here is a demo on ideone .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM