list - 在 Prolog 中将普通树转换为列表

标签 list recursion tree prolog

所以我正在学习编程范式类(class),我们正在学习 Prolog。最后一个练习是将一般的树结构展平为列表。一般来说,这意味着每个节点可以分支任意次数。以下是定义树的一组事实和规则:

leaf(_).
gnode([]).
gnode([leaf(_)|T]):-
    gnode(T).
gnode([gnode(X)|T]):-
    gnode(X),
    gnode(T).

因此,我的解决方案 gtree_list 需要返回叶子中的元素,或者在 gnode 的情况下返回一个列表(这些都应该计算为正确):

gtree_list(leaf(example),example).

gtree_list(gnode( [leaf(5),leaf(4)] ), [5,4]).

gtree_list(gnode( [gnode( [leaf(5)] ),leaf(4)] ), [[5],4]).

gtree_list(gnode( [] ), [] ).

所以 leaf 是元素,gnode 是列表。我当前的实现是这样的:

gtree_list( leaf( L), L ).
gtree_list( gnode( []), [] ).
gtree_list( gnode( [X|Y]), R ):-
    gtree_list( X, R1 ),
    gtree_list( gnode(Y), R2 ),
    append( [R1], R2, R ).

它将所有示例评估为真实,因此一切都很好。我的问题是,当我要求它从嵌套列表中创建树时,它失败了。所以,我剩下以下内容:

gtree_list(gnode( [gnode( [leaf(5) ]),leaf(4) ]), [ [5],4 ]). 

评估结果为真,

gtree_list(gnode( [gnode( [leaf(5)]),leaf(4) ]),X). 

返回X=[[5],4],但是

gtree_list( X, [[5],4] ). 

无法生成正确的树。它从最简单的到最复杂的构建,所以它是:

X = leaf( [[5],4] ); 
X = gnode( [leaf([5]), leaf(4)] ); 

然后我希望它返回X = gnode( [gnode([leaf(5)]), leaf(4)] ),但它从来没有这样做。在任何树中,在经历了所有可能的解决方案之后,它都会无限循环,这是预期的,但显然我的递归无法弄清楚如何对嵌套列表进行逆向工程,这是一个要求。

我错过了什么?

最佳答案

内联append,第二个参数也有机会指导推理:

gtree_list( leaf( L), L ).
gtree_list( gnode( []), [] ).
gtree_list( gnode( [X|Y]), [R1|R2] ):-
    gtree_list(     X,      R1    ),
    gtree_list( gnode(Y),      R2 ).

这似乎使它起作用:

2 ?- gtree_list( gnode( [gnode( [leaf(5) ]), leaf(4)]), [ [5], 4]). 
true ;
false.

3 ?- gtree_list( gnode( [gnode( [leaf(5)]), leaf(4)]), X). 
X = [[5], 4] ;
false.

4 ?- gtree_list( X, [[5], 4]). 
X = leaf([[5], 4]) ;
X = gnode([leaf([5]), leaf(4)]) ;
X = gnode([gnode([leaf(5)]), leaf(4)]) ;
false.

关于list - 在 Prolog 中将普通树转换为列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76499355/

相关文章:

java - 我的程序只返回树的根而不是打印整棵树

r - 向列表列表添加一个新元素(在 R 中)

将数据框列表列表中的列替换为另一个数据框列表列表中的列。 R

c - 寻找一组字符

python dict递归返回空列表

python - 如何在 python 中使用 Objectpath 导航包含数组的 JSON 文件以选择值?

德尔福7 : Select certain items of a TList

python - 如何检查字典列表中键的值是否都等于 0

java - Listnode实现计数出现次数方法的问题(递归)

c# - 使用 WinForms DevExpress XtraGrid c# 显示层次结构树