【问题标题】:Why does Prolog generate additional variables while querying?为什么 Prolog 在查询时会生成额外的变量?
【发布时间】:2021-11-07 01:46:18
【问题描述】:

知识库:

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)

【问题讨论】:

  • 你知道可变变量和不可变变量的区别吗?你知道绑定和不绑定是什么意思吗?当您知道这些问题的答案时,您将更接近于回答您的问题。
  • @GuyCoder 你能把我链接到Prolog中的一些好的参考吗?我的书没有涵盖它们,我在网上找不到好的参考资料。虽然我确实知道其他语言环境中的可变性。
  • 如果每个实例都使用相同的变量名,你将如何处理递归?
  • @GuyCoder 当我还在为我大学的另一门课程学习 Java 时,忘记 OO 很困难。
  • 为什么有人对这个寻求推荐的人投了赞成票。这个问题的推荐请求在哪里?

标签: prolog


【解决方案1】:

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

【讨论】:

  • 可以使用_Z_2978之类的名称。 “由于可能的递归,它需要创建相同变量的‘副本’”确实是答案。
  • 不保证变量按升序编号。但是,名称应该是唯一的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-04-04
  • 2011-09-20
  • 1970-01-01
  • 2018-08-31
  • 2019-12-30
  • 2012-06-03
相关资源
最近更新 更多