Prolog中的树叶遍历

Tree leaf traversal in Prolog

我在训练序言练习时遇到了一些问题,问题如下,

谓词定义了树的含义,可以用来判断一个词是否是树:

tree(t(L,R)) :- tree(L), tree(R).

tree(T) :- T\=t(_ , _).

通过使用这个谓词,您可以找到树中的一个元素(称为叶):

leaf(t(L,R),E) :- leaf(L,E);  leaf(R,E).

leaf(T,T) :- T\=t(_ , _).

所以这里有两个问题,第一个是写谓词 elements/2,它生成一个元素列表,因为它们在树的叶子中以从左到右的顺序在第一个参数中找到!

第二个是写一个谓词 same content/2,当两棵树以相同的顺序包含相同的元素时,它就会成功!重复很重要。

希望有擅长prolog的大神帮帮我,万分感谢

tree/1leaf/1都是de错误1 ,2! 为什么不使用这样更清晰的表示?

is_tree(leaf(_)).
is_tree(bin(L,R)) :-
   is_tree(L),
   is_tree(R).

注意:

  • is_tree/1tree/1leaf/1 更通用:它可以 生成 以及 测试树——甚至两者都做一点(如果参数是部分实例化的)。

  • is_tree/1 从不 给出逻辑上不合理的答案——无论它用在哪个 "mode" 中。

is_tree/1的一些示例用法:

?- is_tree(T).                                   % generate
  T  = leaf(_A)
; T = bin(leaf(_A),leaf(_B))
; T = bin(leaf(_A),bin(leaf(_B),leaf(_C)))
; T = bin(leaf(_A),bin(leaf(_B),bin(leaf(_C),leaf(_D))))
...

?- is_tree(bin(leaf(1),bin(leaf(2),3))).         % test
false.

?- is_tree(bin(leaf(1),bin(leaf(2),leaf(3)))).   % test
true.

?- T = bin(bin(leaf(1),2),_), is_tree(T).        % do both (or at least try)
false.

?- T = bin(bin(leaf(1),leaf(2)),_), is_tree(T).  % do both
T = bin(bin(leaf(1),leaf(2)),leaf(_A))
T = bin(bin(leaf(1),leaf(2)),bin(leaf(_A),leaf(_B)))
T = bin(bin(leaf(1),leaf(2)),bin(leaf(_A),bin(leaf(_B),leaf(_C)))) 
...

回到关于如何实施 elements/2content/2 的问题... 使用 !

leaves(leaf(E))  --> [E].
leaves(bin(L,R)) --> leaves(L), leaves(R).

same_content(A,B) :-
   phrase(leaves(A),Ls),
   phrase(leaves(B),Ls).

示例查询:

?- same_content(bin(leaf(1),bin(leaf(2),leaf(3))), 
                bin(bin(leaf(1),leaf(2)),leaf(3))).
true.

脚注 1:rock-solid treatise on teaching Prolog 讨论了许多常见的障碍,包括 默认性
脚注 2:this answer 中 @mat 解释了 Prolog 中的默认性如何阻碍声明式调试和推理。