Prolog-该程序如何工作

| 我有用序言语言编写的程序。 问题是我无法理解它是如何工作的。
even_number([],[]).
even_number([H|T],S):-even_number(T,W),Z is H mod 2,Z==0,S=[H|W].
even_number([_|T],S):-even_number(T,S).
它所做的就是从列表中提取偶数并将其存储到另一个列表中。 我知道它可以使用递归工作,但是我无法理解执行过程中的步骤。 谁能解释?     
已邀请:
该程序包含三个规则,它们作为一个组应用。它们基本上一起工作为
if ... else if ... else if ... [else fail]
。 第一条规则是:空列表中的偶数是空列表。这很容易。 如果第一个规则失败(即第一个参数不是空列表),则应用第二个规则。这有点复杂,但是基本上说要包括列表的第一个元素(如果是偶数的话)。逻辑分解如下。如果右边的所有条件都为真,则以
H
开头且尾部为
T
的列表中的偶数为ѭ4::
T
中的偶数为某个列表
W
Z
H
除以2后的余数;
Z
为零;
S
H
,然后是
W
(无论
W
是什么)。 (请注意,如果将第一个项移至测试ѭ14after之后,则此规则将更有效。) 如果该规则失败(即
H
是奇数),则应用最后一条规则:列表中的偶数是列表尾部的偶数。     
它写得很差。如果稍微重构一下并使它尾部递归,可能会更容易理解:
even_numbers( X , R ) :-
  even_numbers( X , [] , T ) ,
  reverse( T , R ).

even_numbers( [] , T , T ).
even_numbers( [X|Xs] , T , R ) :-
  Z is X mod 2 ,
  Z == 0 ,
  ! ,
  even_numbers( Xs , [X|T] , R ).
even_numbers( [_|Xs] , T , R ) :-
  even_numbers( Xs , T , R ).
第一个谓词ѭ17谓词是公共包装器。它调用私有助手“ѭ18”,该助手以相反的顺序返回偶数列表。它颠倒了这一点,并尝试将其与包装器中传递的结果统一起来。 helper方法执行以下操作: 如果源列表为空:将累加器(T)与结果统一。 如果源列表不为空,并且列表的首(X)为偶数, 向下递归到列表的尾部(Xs),将X推到累加器上。 如果源列表不为空,并且列表的首部(X)为奇数, 向下递归到列表的尾部(Xs),而无需修改累加器。 但是,正如@AndréParamés指出的那样,在调试器中对其进行处理,将清楚正在发生的事情。     

要回复问题请先登录注册