prolog中的递归(列表中)

时间:2011-04-28 20:47:52

标签: prolog

有人可以帮助我了解有关执行递归序言函数的基础知识吗。

append([],X,X). % base
append([X|Y],Z,[X|W]) :- append(Y,Z,W). %recursive

% base case
addup([], 0). % sum of the empty list of numbers is zero

% recursive case: if the base-case rule does not match, this one must:
addup([FirstNumber | RestOfList], Total) :-
    addup(RestOfList, TotalOfRest),   % add up the numbers in RestOfList
    Total is FirstNumber + TotalOfRest.

有人可以用英语或C / C ++ / Java解释一下......步骤如何。我实际上更愿意看到像追加或反转的东西..我主要只是操纵变量列表而不是整数..(我试图通过追加10次...呃)。

4 个答案:

答案 0 :(得分:5)

append(A, B, R)表示R是将A追加到B的结果。

基本案例

append([], X, X).

表示如果A = []B = X然后R = X = B:附加到其他列表A的空列表B等于B

递归案例

append([X | Y], Z, [X | W]) :- append(Y, Z, W).

表示如果A = [X | Y]是要追加到B = Z的非空列表,并且W Y附加到Z,则R = [X | W] 1}}。

另一种说法是:将非空列表A附加到另一个列表B,首先将A的尾添加到B,然后添加A的头部在列表的前面。

答案 1 :(得分:3)

免费在线图书“立即学习Prolog”有一节专门介绍追加的步骤:

http://cs.union.edu/~striegnk/learn-prolog-now/html/node47.html#subsec.l6.defining.append

答案 2 :(得分:0)

你想在C ++中看到它吗?

int const a[] = {1,2,3,4,5};
size_t const N = sizeof(a) / sizeof(int);

void addup(size_t depth, int &total)
{
    if (depth == N)   // base case; sum of no numbers is zero
        total = 0;
    else {            // recursive case
        int first_number = a[depth];
        size_t rest_of_list = depth+1;
        int total_rest;
        addup(rest_of_list, total_rest);
        total = first_number + total_rest;
    }
}

我会立即承认这是一个非常丑陋的C ++,但它是Prolog程序的直接翻译,除了使用数组和深度计数器模拟列表。

答案 3 :(得分:0)

prolog中的递归与任何其他语言的递归几乎完全相同。 prolog的诀窍在于

  • 每个变量都是本地的,
  • 一旦统一,变量就不再是变量。他们永远无法改变价值。

这意味着您经常需要构建我称之为“worker”谓词的东西,这些谓词可以实现所需的实际工作并带有一个或多个充当工作存储的变量。这是sum / 2的实现,用于求和整数列表:

% sum/2
sum( [] , 0 ).
sum( [X|Xs] , Total) :-
  sum(Xs,X,Total).

% sum/3 (worker predicate)
sum( [], Total, Total ).
sum( [X|Xs] , Subtotal , Total ) :-
  NewSubTotal is Subtotal + X ,
  sum( Xs , NewSubTotal , Total ).

这是ANSI C中的一个实现,它与上面的prolog代码密切相关:

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
// linked list structure
typedef struct listnode
{
  int              value ;
  struct listnode *next  ;
} LISTNODE ;

// core recursive worker function
int sum_core( int subtotal , LISTNODE *list )
{
  LISTNODE *head ;
  LISTNODE *tail ;
  int       list_item ;

  if ( list == NULL ) return subtotal ;

  head      = list        ;
  tail      = list->next  ;
  list_item = head->value ;

  return sum_core( subtotal + head->value , tail ) ;

}

// external interface
int sum( LISTNODE *list )
{
  LISTNODE *head      ;
  LISTNODE *tail      ;
  int       list_item ;

  if ( list == NULL ) return 0 ;

  head      = list        ;
  tail      = list->next  ;
  list_item = head->value ;

  return sum_core( list->value , tail ) ;

}

int main ( int argc , char * argv[] )
{
  LISTNODE *list ;
  int       total ;

  list                   = malloc(sizeof(LISTNODE)) ; list->value             = 1 ;
  list->next             = malloc(sizeof(LISTNODE)) ; list->next->value       = 2 ;
  list->next->next       = malloc(sizeof(LISTNODE)) ; list->next->next->value = 3 ;
  list->next->next->next = NULL ;

  total = sum( list ) ;

  return ;
}