在 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 标准认为是一种 grody,因为它不能很好地概括(以一种有趣的方式,failure-driven 循环想要成为 "leaf code" 在系统中并且会使解释失败复杂化)。因为你想获得多个解决方案,你需要使用 second-order 谓词,例如 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].
我发现量化的东西有点难以理解。
无论如何,希望这对您有所帮助!
我需要在 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 标准认为是一种 grody,因为它不能很好地概括(以一种有趣的方式,failure-driven 循环想要成为 "leaf code" 在系统中并且会使解释失败复杂化)。因为你想获得多个解决方案,你需要使用 second-order 谓词,例如 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].
我发现量化的东西有点难以理解。
无论如何,希望这对您有所帮助!