在 PROLOG 中打印图叶列表

Printing a list of graph leaves in PROLOG

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

的东西

提前致谢。

你有一个很好的想法,要求一些与 link 无关的东西;我会像这样将其编纂为自己的谓词:

leaf_node(Node) :- 
  oh(_, Node),
  \+ oh(Node, _).

我建议您使用 \+/1 而不是 not/1 因为它是 ISO。你可以看到它仍然有效:

?- leaf_node(Node).
Node = 1 ;
Node = 5 ;
Node = 6 ;
Node = 8.

现在,打印出来有两种方法。 failure-driven 循环似乎是你的目标,它相当简单,就像这样:

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.

然而,failure-driven 循环作为一种实践被现代 Prolog 标准认为是一种 gr​​ody,因为它不能很好地概括(以一种有趣的方式,failure-driven 循环想要成为 "leaf code" 在系统中并且会使解释失败复杂化)。因为你想获得多个解决方案,你需要使用 second-order 谓词,例如 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].

我发现量化的东西有点难以理解。

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