在PROLOG中打印图形叶列表

时间:2016-01-08 19:38:06

标签: list graph prolog nodes

我需要在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

这样的东西

提前致谢。

1 个答案:

答案 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/3setof/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].

我觉得量化的事情有点难以理解。

无论如何,希望这有帮助!