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/1
和leaf/1
都是de错误1 ,2!
为什么不使用这样更清晰的表示?
is_tree(leaf(_)).
is_tree(bin(L,R)) :-
is_tree(L),
is_tree(R).
注意:
is_tree/1
比 tree/1
和 leaf/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/2
和 content/2
的问题... 使用 dcg!
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 中的默认性如何阻碍声明式调试和推理。
我在训练序言练习时遇到了一些问题,问题如下,
谓词定义了树的含义,可以用来判断一个词是否是树:
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/1
和leaf/1
都是de错误1 ,2!
为什么不使用这样更清晰的表示?
is_tree(leaf(_)). is_tree(bin(L,R)) :- is_tree(L), is_tree(R).
注意:
is_tree/1
比tree/1
和leaf/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/2
和 content/2
的问题... 使用 dcg!
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 中的默认性如何阻碍声明式调试和推理。