如何公平地列举树木?

问题描述 投票:0回答:0

我们代表原子“ nil”和非空树代表术语t(x,l,r)的非空树,其中x分别表示root节点,l和l分别表示左和右子树。

这样,测试术语是否表示二进制树的谓词如下:

is_tree(nil). is_tree(t(_, Left, Right)) :- is_tree(Left), is_tree(Right).
例如,它效果很好,例如:

% ?- is_tree(nil). %@ true. % ?- is_tree(t(a, nil, nil)). %@ true. % ?- is_tree(t(a, t(b, nil, nil), nil)). %@ true.

,但是,当带有一般查询时,它似乎只会创建右侧节点:

% ?- is_tree(X). %@ X = nil %@ ; X = t(_A,nil,nil) %@ ; X = t(_A,nil,t(_B,nil,nil)) %@ ; ... .

现在,如果X是列表,我本来可以用
length(X, _)

进行迭代以进行迭代加深。但是,由于论点不是列表,我对如何获得公平枚举感到不知所措。 我试图制作一个谓词来计算树的深度:

tree_depth(nil, 0).
tree_depth(t(_, Left, Right), Depth) :-
    tree_depth(Left, D0), tree_depth(Right, D1),
    Depth #= max(D0, D1) + 1. 

然后,试图用约束来限制它,但我得到的只是一个非终止查询,在检查后,它只是继续生成越来越深的树木,只有右手子树:

% ?- Y #< 3, tree_depth(X, Y), is_tree(X). %@ Y = 0, X = nil %@ ; Y = 1, X = t(_A,nil,nil) %@ ; Y = 2, X = t(_A,nil,t(_B,nil,nil)) %@ ; *hangs*
在这一点上,我不确定我该怎么办,我在做什么错。我正在使用Scryer Prolog。
    

prolog
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.