首页 > 解决方案 > 为什么 Prolog 在查询时会生成额外的变量?

问题描述

知识库:

child(martha,charlotte).
child(charlotte,caroline).
child(caroline,laura).
child(laura,rose).


descend(X,Y) :- child(X,Y).
descend(X,Y) :- child(X,Z),
                descend(Z,Y).

询问:descend(martha, laura).

Prolog 首先调用 child(martha, laura) 失败然后返回到descend(martha, laura)。

现在,它需要调用 child(martha, Z) 来检查条件,但为什么需要将 Z 提供给另一个变量,例如_2978?我认为只调用(或查询)child(martha, Z) 就可以了。

痕迹:

   Call: (8) descend(martha, laura) ? creep
   Call: (9) child(martha, laura) ? creep
   Fail: (9) child(martha, laura) ? creep
   Redo: (8) descend(martha, laura) ? creep
   Call: (9) child(martha, _2978) ? creep   % HERE, why does Prolog 
                                            % need this extra variable                                             
                                            % _2978 instead of 
                                            % utilizing the original Z variable? 
   Exit: (9) child(martha, charlotte) ? creep

一个更简单的例子:我有知识库:numeral(0)

然后我查询numeral(X)。在跟踪期间,我可以看到第一个调用是numeral(_3233).

标签: prolog

解决方案


Prolog 引擎内部不使用变量名,变量只是内存中特殊类型单元的地址。因此,当它需要在跟踪期间表示一个术语时,它必须重建其文本表示,并且由于没有名称,它以统一的方式为所有变量生成它们,只需按升序编号即可。您可能会问为什么它不将名称保留为元数据 - 答案是它可以做到这一点,但它没有意义,因为由于可能的递归,它需要创建相同 var 的“副本”,我们再次来到通用命名的必要性。


推荐阅读