我们代表原子“ 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。