繁体   English   中英

prolog中的递归引用

[英]Recursive reference in prolog

我尝试实施时遇到了一些问题

friends(mia, ellen).
friends(mia, lucy).
friends(X,Y) :-
  friends(X,Z),
  friends(Y,Z).

当我问?- friends(mia, X). ,它耗尽了本地堆栈。

然后我补充说

friends(ellen, mia) friends(lucy, mia) 

我问?- friends(mia, X). ,它不断回复X = mia

我无法理解,为什么它是递归的?

friends/2这一条款有缺陷:

friends(X,Y) :- friends(X,Z),friends(Y,Z).

把它翻译成英文:“如果XY有一个共同的朋友Z ,那么XY就是朋友。”

或者,让我们专注,让X成为“我”,让Y成为我的邻居“FooBert”,让Z成为“你”:所以,如果我是你的朋友而FooBert是你的朋友......这是否让我和FooBert成为朋友? 我不这么认为,我讨厌那个人 - 他回家后总是砸门。 :)

我建议你考虑一下friends/2 应该拥有的代数属性,它可能具有的代数属性,以及它 应该有的代数属性。 反身性,对称性,反对称性,传递性如何?

首先,两个假设:

  • 您要编写的实际代码是以下代码,并带有适当的点:

     friends(mia,ellen). friends(mia,lucy). friends(X,Y) :- friends(X,Z), friends(Z,Y). 
  • 变性持有:朋友的朋友也是我的朋友(我宁愿模仿友谊作为距离:“A在B附近”,“B在C附近”并不一定意味着“A在C附近”)。 重复的答案是关于先弄清楚你想要建模的东西。

现在,让我们看看为什么我们进入无限递归。

一步步

那么,当我们问: friends(mia,X)时会发生什么?

  1. 第一个条款给Y=ellen (你要求更多解决方案)
  2. 第二个条款给出Y=lucy (你再次询问更多解决方案)
  3. 堆栈溢出 !

让我们详细说明第三个条款:

  1. 我想知道friends(mia,Y)持有某个变量Y
  2. 是否存在变量Z ,以便friends(mia,Z)持有?

    请注意,除了从YZ重命名之外,我们问的问题与上面的第1步相同吗? 这闻起来像无限递归 ,但让我们看看...

  3. 我们尝试了friends的前两个条款,但后来因为没有friends(ellen,Y)friends(lucy,Y)而失败,所以......
  4. 我们调用第三个子句以便找到是否存在传递友谊,并且我们回到步骤1而没有进一步进展=>无限递归。

此问题类似于无上下文语法中的无限左递归

修复

有两个谓词:

  1. known_friends/2 ,它提供了直接的关系。
  2. friends/2 ,也编码传递性

     known_friends(mia,ellen). known_friends(mia,lucy). friends(X,Y) :- known_friends(X,Y). friends(X,Y) :- known_friends(X,Z), friends(Z,Y). 

现在,当我们问friends(mia,X)friends/2给出了与known_friends/2的两个子句相同的答案,但没有找到传递条款的任何答案:这里的区别是known_friends会稍微进步一下,即找到一个已知的mia朋友(没有递归),并试图找到(递归)该朋友是否是其他人的朋友。

朋友的朋友

如果我们添加known_friends(ellen, bishop) :-)那么friends也会找到Y=bishop ,因为:

  • known_friends(mia,ellen)持有,和
  • friends(ellen,bishop)是递归发现的。

如果您在友谊图中添加循环依赖项(在known_friends ),那么您friends无限遍历此图。 在解决此问题之前,您必须考虑以下问题:

  • friends(X,Y) <=> friends(Y,X)是否适合所有人(X,Y)
  • 对于所有Xfriends(X,X)怎么样?

然后,在评估friends时,你应该保留一组所有见过的人,以便检测你何时循环通过known_friends ,同时考虑上述属性。 如果你想尝试,这也不应该太难实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM