我需要在Prolog中的有向图中打印叶子列表。
我是Prolog的初学者,这是我的学校任务之一......
即。我的图表是:
oh(0,1).
oh(0,2).
oh(2,3).
oh(2,4).
oh(3,4).
oh(4,5).
oh(3,6).
oh(4,8).
我想我已经制定了查找树叶并将它们列入清单的规则。 (最后只是不确定那个失败。)
addtolist([Node], List, [Node|List]):-
oh(_, Node),
not(oh(Node, _)),
fail.
但我不知道如何显示此列表。
实际上我想在控制台中写一些类似?- show.
的东西,我希望得到像1,5,6,8
提前致谢。
答案 0 :(得分:0)
你有一个好主意,想要一些与其他事物无关的东西;我会把它编成自己的谓词,如下:
leaf_node(Node) :-
oh(_, Node),
\+ oh(Node, _).
我建议您使用\+/1
代替not/1
,因为它是ISO。你可以看到这仍然有效:
?- leaf_node(Node).
Node = 1 ;
Node = 5 ;
Node = 6 ;
Node = 8.
现在,有两种方法可以打印出来。一个失败驱动的循环似乎是你的目标,而且它很简单,就像这样:
show_leaves :-
leaf_node(Node),
write(Node), nl,
fail.
show_leaves :- true.
这样工作原理如下:
?- show_leaves.
1
5
6
8
true.
使用forall/2
的同一事物的更高版本将是这样的:
?- forall(leaf_node(Node), (write(Node), nl)).
1
5
6
8
true.
然而,作为一种实践的失败驱动循环被现代Prolog标准视为一种格斗,因为它没有很好地概括(以一种有趣的方式,一种失败驱动的循环想要成为"叶子代码"在系统中并且可以使解释失败复杂化)。因为您想要获得多个解决方案,所以您需要使用二阶谓词,例如bagof/3
或setof/3
,它将如下所示:
?- bagof(Node, leaf_node(Node), LeafNodes).
LeafNodes = [1, 5, 6, 8].
这可能是我们大多数人都会这样做的。事实上,如果你愿意,你可以在那里挤压整个leaf_node/2
定义,但是你需要使用存在量化来告诉bagof
你不关心那些节点您的叶节点是否连接到:
?- bagof(Node, A^B^(oh(A, Node), \+oh(Node, B)), LeafNodes).
LeafNodes = [1, 5, 6, 8].
我觉得量化的事情有点难以理解。
无论如何,希望这有帮助!