【问题标题】:Collect leaves in general tree收集普通树的叶子
【发布时间】:2021-12-26 14:20:15
【问题描述】:

我正在尝试编写一个谓词leaves/2,它在 Prolog 中收集一棵普通树中的所有叶子。我有一个类似的二叉树谓词,但我一直试图将它概括为多路或通用树(其中一个节点可以有无限数量的子节点)。这是二叉树(其中叶节点由 l(_) 表示):

leaves( l(X), [X|T], T ).
leaves( tree(L,R), A, C ) :-
  leaves(L,A,B),
  leaves(R,B,C).
leaves(Tree,L) :-
  leaves(Tree,L,[]).

查询

leaves(tree(tree(l(3),l(2)),l(6)),Leaves)

正确返回

Leaves = [3,2,6]

当我尝试将其概括为多路树时,我陷入了一个节点包含整个树列表的事实。我试图递归地“解包”这样一个树列表,然后使用上述谓词的变体逐步处理它,但它不起作用,因为我发现很难将树列表与节点隔离以便单独处理它。

因此,一般树可以是一个句子的表示,其中每个节点包含一个句法类别,而叶子包含实际单词,如下所示:

tree( s, [ tree(np,[l(the),l(dog)]), tree(vp,[l(barks)]) ] )

然后以这个通用树作为参数的类似查询应该产生Leaves=[the,dog,barks]。我试图找到与二叉树相同风格的实现,而不使用append/2、DCG 或类似的东西。

【问题讨论】:

  • 你试过用笔和纸做吗?换句话说,不要像教别人那样用代码手动操作。您会惊讶于这有多少帮助。
  • @GuyCoder 谢谢,这当然是一个有价值的提示。不幸的是,我在纸上尝试时遇到了同样的问题。这很令人沮丧。

标签: tree prolog


【解决方案1】:

一个可能的解决方案如下:

leaves(Tree, Leaves) :-
    leaves(Tree, [], Leaves).
  
leaves(l(X), L, [X|L]).

leaves(tree(_, Children), L0, L) :-
    leaves(Children, L0, L).

leaves([], L, L).

leaves([Child|Children], L0, L) :- 
    leaves(Children, L0, L1),
    leaves(Child, L1, L).

例子:

?- leaves(tree(s, [tree(np, [l(the), l(dog)]), tree(vp, [l(barks)])]), Leaves).
Leaves = [the, dog, barks].

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多