【问题标题】:Checking whether the tree is avl-tree in prolog. error在prolog中检查树是否为avl-tree。错误
【发布时间】:2017-03-25 11:02:32
【问题描述】:

我的程序运行不正常。当我尝试对其进行测试时,我遇到了错误。

我的测试示例:

if_avl_tree(t(t(t(nil/0, 3, nil/0)/1, 7, t(t(nil/0, 9, nil/0)/1, 11, nil/0)/2)/3, 16, t(nil/0, 25, t(nil/0, 40, nil/0)/1)/2)/4).

这是我的代码:

if_avl_tree(t(_,_,_)/_ ) :- T=t(_,_,_)/_ , is_binTree(T), if_avl_tree(T, _), !.
if_avl_tree(nil/0, 0).
if_avl_tree(t(nil/0,_, nil/0), 1).
if_avl_tree(t(L,_,R )/H, Hh) :- if_avl_tree(L, H1), 
                                if_avl_tree(R, H2), abs(H1 - H2) =< 1, !,                                                                                      
                                H3 is 1 + max(H1,H2), H3=:=Hh.

is_binTree(nil/0) :- !.
is_binTree(t(L,_,R)/_):- is_binTree(L), is_binTree(R).

这是我的错误:

ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR:   [10] 1=:=_6218
ERROR:    [8] if_avl_tree(t(...,16,...)/4) at e:/prolog/tasks/lab06tomashchuk.pl:50
ERROR:    [7] <user>
ERROR: 
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.

【问题讨论】:

  • =:=/2 计算表达式参数并测试是否相等。所以它要求表达式是可评估的。如果由于未绑定变量而无法评估其中任何一个,它会告诉您参数没有充分实例化。在您的任期内,H3=:=HhH3Hh 不受约束。这个声明的目的是什么?只是将H3“分配”给Hh?如果是这样,那就没有必要了。在这种情况下,删除该语句并在谓词子句的头部使用H3 而不是Hh
  • 你为什么要剪这么多(!)?不要随意使用切割。当您不想要它们时,将它们用于修剪掉其他有效解决方案的特定目的。但是,如果您不确定,请先不使用它们。
  • 为什么是nil/0nil 一个人还不够吗?
  • 您有一点不一致:if_avl_tree(t(nil/0,_, nil/0), 1). 没有使用与您的其他谓词相同的树表示。

标签: prolog avl-tree instantiation-error


【解决方案1】:

您的示例代码绝对是正确的,但有一些异常情况。

让我们从二叉树的简单表示开始:

btree(Value, Left, Right)

这是不言自明的。如果没有子树,可以使用原子nil

如果我们想验证一个结构是否是二叉树,我们可以这样做:

is_binary_tree(nil).    % Allow for a nil tree with no values
is_binary_tree(btree(_, Left, Right)) :-
    is_binary_tree(Left),
    is_binary_tree(Right).

如果任何节点的两个子子树的高度最多相差 1,则二叉树是 AVL。如果您的二叉树表示已经将每棵树的高度作为树表示的一部分,如下所示:

btree(Value, Left, Right)/Height

那么当树的内容或结构改变时,必须假设Height 被维护。如果它们没有被更改,那么关于它是否是 AVL 树的决定不需要携带额外的高度参数。高度已经预先计算和维护,因此只需要检查它们:

is_AVL_tree(nil/0).
is_AVL_tree(btree(_, Left, Right)/_) :-
    Left = btree(_, _, _)/HeightLeft,
    Right = btree(_, _, _)/HeightRight,
    abs(HeightLeft - HeightRight) =< 1,
    is_AVL_tree(Left),
    is_AVL_tree(Right).

对于高度为 1 的情况,您不需要单独的基本情况。上面的两条规则已经解决了它。

如果您没有通过维护树来预先确定高度作为术语中的参数,那么我们需要携带高度作为参数并计算它们。 t 不需要作为树表示的一部分。这将是多余的,并使规则变得不必要的混乱。

is_AVL_tree(nil, 0).
is_AVL_tree(btree(_, Left, Right), Height) :-
    is_AVL_tree(Left, HeightLeft),
    is_AVL_tree(Right, HeightRight),
    abs(HeightLeft - HeightRight) =< 1,
    Height is 1 + max(HeightLeft, HeightRight).

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-08
    • 1970-01-01
    • 2019-10-18
    • 1970-01-01
    • 2016-04-30
    • 1970-01-01
    • 2020-04-07
    相关资源
    最近更新 更多