0

假设这里是一棵二叉搜索树,并且给定 above(X,Y)-X直接在上面的规则Y。我还创建了规则root(X)-X没有父级。

然后,我试图弄清楚这棵树中节点的深度。假设树的根节点是“r”所以我得到了 fact level(r,0)。为了实施规则level(N,D) :-,我想的是这里应该有一个递归。因此,我尝试了

level(N,D): \+ root(N), above(X,N), D is D+1, level(X,D). 

所以如果N不是根,X上面有一个节点N,层级D加一,然后递归。但是当我测试这个时,它只适用于根条件。当我创建更多事实时,例如节点“s”是节点“r”的左子节点,我的查询是 level(s,D)。它返回我“不”。我跟踪了查询,它显示了我

  1    1  Call: level(s,_16) ? 
  1    1  Fail: level(s,_16) ?

我只是困惑为什么我打电话时它会失败 level(s,D)

4

1 回答 1

0

您的查询存在一些问题:

  • 在 Prolog 中你不能写类似的东西D is D+1,因为一个变量只能被赋予一个值;
  • 在你调用的那一刻D is D+1D还没有实例化,所以它可能会导致错误;和
  • 您永远不会声明(至少不在可见代码中)level/2根的0.

一个解决方案是首先声明任何根的级别是0

level(N,0) :-
    root(N).

above/2现在我们必须定义归纳案例:首先,我们确实使用谓词来寻找父母。N严格来说,没有必要进行检查root/1,因为它会与存在above/2. 接下来我们确定该父LP节点的级别,最后我们通过说明级别的位置L is LP+1和级别op来计算节点的级别:LNLPP

level(N,L) :-
    above(P,N),
    level(P,LP),
    L is LP+1.

或者把它们放在一起:

level(N,0) :-
    root(N).
level(N,L) :-
    above(P,N),
    level(P,LP),
    L is LP+1.

由于您没有提供示例树,因此我无法测试此谓词的行为是否符合您的预期。


关于root/1

请注意,通过编写root/1,您引入了数据重复:您可以简单地编写:

root(R) :-
    \+ above(_,R).
于 2016-02-29T09:43:39.117 回答