有人知道,如何在Prolog中获取叶节点列表?
让我们说,我有一个由这些有向边描述的简单有向图:
de(0,1).
de(0,2).
de(2,3).
de(2,4).
de(3,4).
de(4,5).
现在,如何递归浏览图形并编写这两个叶子节点(节点1和5)的列表?
感谢您的回答!
编辑:
好吧,我有第一个谓词写的&工作:
isLeaf(Node) :-
not(de(Node,_)).
但是现在,我不知道如何遍历图并编写叶节点的输出列表。我知道,这很容易,但我没有这种思维和编程方式的经验:(
答案 0 :(得分:4)
您需要定义一个生成器的谓词is_leaf/1
,
即它用可能的解决方案实例化输入变量。
这样的事情:
% Directed graph
de(0,1).
de(0,2).
de(2,3).
de(2,4).
de(3,4).
de(4,5).
% If Node is ground,
% then test if it is a child node that is not a parent node.
% If Node is not ground,
% then bind it to a child node that is not a parent node.
is_leaf(Node) :-
de(_, Node),
\+ de(Node, _).
用法示例:
?- is_leaf(Node).
Node = 1 ;
Node = 5.
?- is_leaf(Node), writeln(Node), fail ; true.
1
5
true.
?- findall(Node, is_leaf(Node), Leaf_Nodes).
Leaf_Nodes = [1, 5].
您的解决方案会立即致电not
。 (顺便说一句,SWI-Prolog建议使用\+
代替not
。)
isLeaf(Node) :-
not(de(Node,_)).
这意味着您的isLeaf/2
不是生成器:它会失败或成功(一次),并且如果它恰好是变量,则永远不会绑定输入参数。
此外,它从不测试输入是否为叶子,它只是测试它是否不是父节点。
% Is it false that 1 is a parent? YES
?- isLeaf(1).
true.
% Is it false that blah is a parent? YES
?- isLeaf(blah).
true.
% Is it false that 2 is a parent? NO
?- isLeaf(2).
false.
% Basically just tests if the predicate de/2 is in the knowledge base,
% in this sense quite useless.
?- isLeaf(Node).
false.
答案 1 :(得分:0)
想想你会做相反的事情,即制定一个可以告诉你节点是否是分支的谓词。
从中可以非常简单地编写一个遍历图形的谓词,如果当前节点是叶子则打印和回溯。