Prolog谓词树中的单个节点

时间:2019-03-20 20:02:12

标签: prolog

对一个谓词进行编码,该谓词将在一个树中找到一个只有一个子节点的所有节点。 有了树

treeEx(X) :-
    X = t(73,t(31,t(5,nil,nil),nil),t(101,t(83,nil,t(97,nil,nil)),nil)).


     73
    /  \
  31   101
 /     /
5     83
     /   
    97  

它应该返回L = [31, 101, 83]

我尝试了以下操作,但是它返回了所有节点。我不知道如何仅列出单个子节点。

single(nil,[]).
single(t(X,L,R),[X|S]) :- 
   append(SL,SR,S), single(L,SL), single(R,SR). 

1 个答案:

答案 0 :(得分:1)

  

[..]谓词,该谓词查找树中的所有节点与一个单个子节点。

首先考虑一下您感兴趣的情况:

  • usecols:=具有值t(V,nil,R)和单个(右)子节点V的节点。
  • R:=具有值t(V,L,nil)和单个(左侧)子元素V的节点。

然后考虑其他您不感兴趣的情况(尽可能笼统地说):

  • L:=值为t(V,nil,nil)且没有子节点的节点。
  • V:=值为t(V,L,R)的节点,左节点({V)和右节点(L)都是

接下来考虑您要“做什么”:收集列表中您感兴趣的案例的值。因此,如果您有感兴趣的案例,则需要将值R添加到包含结果的列表中:

V

这样,您可以编写谓词:您知道它具有一个“输入”参数(树)和一个“输出”参数(列表)。首先是您感兴趣的情况:

[V|RestResults] % whatever RestResults is, not important atm

您将值single(t(V, nil, R), [V|Vr]) :- single(R, Vr). single(t(V, L, nil), [V|Vl]) :- single(L, Vl). 添加到从单个子分支获得的结果(值列表)中。

接下来是您不感兴趣的案例。首先是简单的案例:

V

那是一个叶子节点(没有子节点)。它的值没什么意思,它的子代可能没有结果,所以结果列表是空列表。

最后,最复杂的情​​况:

single(t(_,nil,nil), []).

两个孩子;在这种情况下,该值并不有趣,但是子级是:您需要收集结果列表,并将其追加以创建此节点的结果列表。

现在,您编写这些规则的顺序在Prolog中通常很重要,但是在这种情况下,顺序并不重要(当Prolog对节点使用“错误”规则时,例如最后一个-两个孩子-一个single(t(_, L, R), X) :- single(L, Vl), single(R, Vr), append(Vl, Vr, X). ,然后它很快就会到达t(_,nil,nil)的情况下-没有规则匹配,并且回溯到“正确”规则)。尽管如此,我还是要根据规则的模式有多“具体”对规则进行排序:首先,该规则不包含任何孩子,然后两个规则对应一个孩子,最后一个规则对应两个孩子。

({Live on ideone)