在列表一节中,作者用了这样的方法来定义谓词:

member(H,[H|T]).
member(X,[H|T]):-member(X,T).

递归是显然的,但它是用什么方法完成的这个过程的呢?不理解的童鞋可以听我下面的讲解:^_^

首先,对于不理解的程序,最直接的办法莫过于调试,单步跟一遍,下面是SCIStusmember(c, [a, b, c, d])的单步跟踪结果:

% trace

| ?- member(c, [a, b, c,d]).

       1      1 Call: member(c,[a,b,c,d]) ?

       2      2Call: member(c,[b,c,d]) ?

       3      3Call: member(c,[c,d]) ?

?       3      3 Exit: member(c,[c,d]) ?

?       2      2 Exit: member(c,[b,c,d]) ?

?       1      1 Exit: member(c,[a,b,c,d]) ?

Yes

可以看到Prolog很聪明的理解了我们的目的,一步一步向前推,先看c是不是[a, b, c, d]的表头,不是,再看是不是[b, c, d]的表头,最后再看是不是[c, d]的表头,发现是,于是就退出来了,返回一个yes

那么在这个过程里,H,[H|T] 是怎么起作用的呢?其实我们可以这么想,member是一个二元谓词,所以可以把它写成member(Var1, Var2),在这里,我们输入的第一个变量Var1 = H,而第二个变量 Var2
则用“=”运算符与[H | T]做运算,注意是做运算,或者说是比较 Var2[H | T] 是否相等,如果带入刚才我们定义的Var1,那就是比较 Var2 [Var1 | T]是否相等,因为我们对T没有做什么约束,甚至可以是空——“[]“,所以表达式的真值就取决于Var1是否是是 Var2的表头,又因为这个谓词没有定义什么其他内容,所以这个真值就是谓词的真值。

写得有点乱,写个例子大家就明白了:

对于member(c, [a,b, c, d])

(0) 假定原型为 member( Var1, Var2 ).

% 下面的执行内容为member(H,[H|T]).

(1)Var1 = c.

(2)Var2 = [a, b, c, d].

(3)Var2 = [Var1 | T].

     [a, b, c, d] = [ c | [b, c, d] ].    %注意这是个判断

(3) 表达式返回 false.

(4) 谓词返回 false.

%下面执行内容为member(X,[H|T]):- member(X,T).

(4)Var1 = c.

(5)Var2 = [a, b, c, d].

(6)Var2 = [H | T]

      H = a, T = [b, c, d].

(7)member(Var1, T)

      member(c, [b, c, d]).

% 下面的执行内容为member(H,[H|T]).

(8)Var1 = c.

(9)Var2 = [b, c, d].

(10)Var2 = [Var1 | T].

     [b, c, d] = [c | [c, d] ].

(11) 表达式返回false.

(12) 谓词返回 false.

%下面执行内容为member(X,[H|T]):- member(X,T).

(13)Var1 = c.

(14)Var2 = [b, c, d].

(15)Var2 = [H | T]

      H = b, T = [c, d].

(16)member(Var1, T).

     member(c, [c, d])

% 下面的执行内容为member(H,[H|T]).

(16)Var1 = c.

(17)Var2 = [c, d].

(18)Var2 = [Var1 | T].

     [c, d] = [c | [d] ].

(19) 表达式返回true.

(20) 谓词返回true.

理解了这个过程,我们就可以把这个member函数写的再清晰一些:

member_m(H, T) :- [X | Y] = T, X = H.

member_m(H, T) :-

  [X | T] = T,

  member_m(H, T).

% Well, this is my
understaning of member/
2

发表评论

电子邮件地址不会被公开。 必填项已用*标注

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

你可以管理本篇文章的订阅。

Post Navigation