prolog - 为什么 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 引擎内部不使用变量名,变量只是内存中特殊类型单元的地址。因此,当它需要在跟踪期间表示一个术语时,它必须重建其文本表示,并且由于没有名称,它以统一的方式为所有变量生成它们,只需按升序编号即可。您可能会问为什么它不将名称保留为元数据 - 答案是它可以做到这一点,但它没有意义,因为由于可能的递归,它需要创建相同 var 的“副本”,我们再次来到通用命名的必要性。
推荐阅读
- web-worker - 无法从网络工作者读取/写入文件
- javascript - JQuery 链接 onClick 事件发送图像 - 如何获取链接对象?
- android - Kotlin 中的 edittext.setText("str") 和 edittext.text.text="str" 有什么区别?
- c# - 如何使用 Mediator 配置 MassTransit 以发布消息?
- android - Android Gradle“Api”不适用于外部库
- javascript - GRT 修复了响应式菜单 - jQuery 插件 - 关闭菜单的问题(点击链接后)
- google-apps-script - 获取表索引
- javascript - ReactJS 在生产中没有缩小错误
- javascript - 如何在嵌套对象中推送响应
- python - 如何在python中使用自己的键对数组进行排序