打印出没有findall的列表

时间:2012-11-07 20:18:50

标签: tree prolog prolog-findall

我需要在prolog中执行一个程序,该程序打印出给定级别N上的树的所有节点的列表(它必须是列表)。我只是无法将节点放入列表中。有人告诉我使用findall函数,但它仍然无法正常工作。我想不改变谓词levelNodes,但没有findall的解决方案将是好的。

domains
element=integer
treetype=tree(element,treetype,treetype);nil
list=element*
predicates
create_tree(element,treetype)
insert_left(treetype,treetype,treetype)
insert_right(treetype,treetype,treetype)
levelNode(treetype,element)
levelNodes(element,treetype,element)
goal
create_tree(10,Ten),
create_tree(11,Eleven),
create_tree(3,Three),
create_tree(5,Five),
create_tree(8,Eight),
create_tree(4,Four),
create_tree(1,One),

insert_left(Ten,Eleven,Eleven1),
insert_right(Three,Eleven1,Eleven2),
insert_left(Five,Eight,Eight1),
insert_right(Four,Eight1,Eight2),
insert_left(Eleven2,One,One1),
insert_right(Eight2,One1,FinalTree),
levelNode(FinalTree,1),
nl.
clauses
levelNode(tree(I,L,R),N):-
    findall(X,levelNodes(X,tree(I,L,R),N),O),
    write(O).
levelNodes(X,tree(I,_,_),0):-
    X=I,
    !.
levelNodes(X,tree(I,L,R),N):-
    N>0,
    N2=N-1,
    levelNodes(X,L,N2),
    levelNodes(X,R,N2). 
create_tree(A,tree(A,nil,nil)).

insert_left(X,tree(A,_,B),tree(A,X,B)).

insert_right(X,tree(A,B,_),tree(A,B,X)).

1 个答案:

答案 0 :(得分:1)

如果我改写我得到的任务:

  • 开始递归访问,传递正确初始化的Level,
  • 如果等级为0 - >;停止递归('返回'数据,我使用head'最后一个参数),
  • 在递归之前递减级别,并且返回数据。

这里有一个草图,包括递归调用和consing。

levelNode(tree(N,_,_), 0, [N]).
levelNode(tree(_,L,R), Level, Ns) :-
    Level > 0,
    Sub is Level - 1, % maybe you'll need Sub=Level-1
    % recurse left, ...

OT 请注意,Prolog中的递归数据结构非常容易描述,并且是问题建模的重要组成部分。考虑而不是

create_tree(10,Ten),
create_tree(11,Eleven),
create_tree(3,Three),
create_tree(5,Five),
create_tree(8,Eight),
create_tree(4,Four),
create_tree(1,One),

insert_left(Ten,Eleven,Eleven1),
insert_right(Three,Eleven1,Eleven2),
insert_left(Five,Eight,Eight1),
insert_right(Four,Eight1,Eight2),
insert_left(Eleven2,One,One1),
insert_right(Eight2,One1,FinalTree),
levelNode(FinalTree, 1, Nodes),
...

在这些相当难以阅读的代码之后,我们有FinalTree = tree(1, tree(11, tree(10, nil, nil), tree(3, nil, nil)), tree(8, tree(5, nil, nil), tree(4, nil, nil)))

切换到其他(等效)表示使其更具可读性,您不觉得吗?

...
Tree = t(1, t(11, t(10, t, t), t(3, t, t)), t(8, t(5, t, t), t(4, t, t))),
levelNode(Tree, 1, Nodes),
...

编辑代码

levelNode(t(N,_,_), 0, [N]).
levelNode(t(_,L,R), Level, Ns) :-
    Level > 0,
    Sub is Level - 1, % maybe you'll need Sub=Level-1
    levelNode(L, Sub, A),
    levelNode(R, Sub, B),
    append(A, B, Ns).

试验:

?- T=t(1,t(2,t,t),t(3,t,t)),levelNode(T,1,L).
T = t(1, t(2, t, t), t(3, t, t)),
L = [2, 3] ;
false.