知识库:
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),失败后返回下行(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引擎内部不使用变量名,变量只是内存中特殊类型单元的地址。因此,当在跟踪过程中需要表示一个术语时,它必须重建它的文本表示,并且由于没有名称,它仅通过按升序对它们进行编号,以统一的方式为所有变量生成名称。你可能会问为什么它不保留名字作为元数据——答案是它可以这样做,但这没有意义,因为由于可能的递归,它将需要创建同一个var的"副本",我们再次需要通用命名。