图形实现(图表是否包含所有顶点?)

时间:2018-04-27 01:51:58

标签: prolog

尝试实现以下谓词,它接受输入

  • 列表列表 - 一个列表=一个测试图T(作为边)
  • 图G本身(作为边)

并测试T是否包含G的所有顶点。如果它(true)应该返回它。基本上它是列表过滤。

到目前为止我所拥有的是:

covb([],G).
covb([H|R],G) :-
    isItCov(G,H), covb(R,G).

isItCov([],H).
isItCov([V-W|R],H) :-
    vertex(V,H),
    vertex(W,H), 
    isItCov(R,H).

vertex(V,[V-_|G]).
vertex(V,[_-V|G]).
vertex(V,[_|G]):- vertex(V,G). 

covb([[a-c,c-b,c-d]],[a-b,a-c,a-d,c-d,b-c])工作正常(true)。对于covb([[a-c]],[a-b,a-c,a-d,c-d,b-c]也可以正常工作(false)。当我用多个列表(例如covb([[a-c,c-b,c-d],[a-c]],[a-b,a-c,a-d,c-d,b-c]).)调用它时,我遇到了一个问题,这些列表应仅适用于第一个列表。 我实际上有两个问题 -

  1. 为什么它仅适用于一个列表?
  2. 我想返回传递条件的列表列表项并返回true(这是过滤部分)。我该怎么做?

1 个答案:

答案 0 :(得分:0)

首先,您的程序有许多单例变量警告。 不要忽略单例变量警告。他们可以隐藏真正的错误。此外,由于更有经验的Prolog用户知道具有单例变量警告的程序甚至不值得运行,他们将(a)只看到警告并确定他们不再有兴趣试图帮助您,或(b)修复警告他们,但根据定义,他们将致力于一个不再是你发布的程序的程序!

现在提问。

  

为什么它仅适用于一个列表?

你真的不清楚你在这里要求的是什么,或者只是在#34; covb([[a-c,c-b,c-d],[a-c]],[a-b,a-c,a-d,c-d,b-c]).以上,这应该仅适用于第一个。"

此查询 失败:

?- covb([[a-c,c-b,c-d],[a-c]],[a-b,a-c,a-d,c-d,b-c]).
false.

这归结为测试两个列表中的每一个:

?- isItCov([a-b,a-c,a-d,c-d,b-c], [a-c,c-b,c-d]).
true .

?- isItCov([a-b,a-c,a-d,c-d,b-c], [a-c]).
false.

第一个列表确实覆盖了图表,而第二个列表没有。总的来说,如果所有列表都覆盖了图表,那么您对covb/2的定义就会成功。情况并非如此,因此您的covb/2查询失败。

这是你想知道的吗?

  

我想返回传递条件并返回true的列表列表(这是过滤部分)。我该怎么做?

您可以查看Prolog的文档是否包含“" filter"”字样。在SWI-Prolog上你可以这样做:

?- apropos(filter).
true.

这将指向include/3谓词,它似乎可以执行您想要的操作:

?- include(isItCov([a-b,a-c,a-d,c-d,b-c]), [[a-c,c-b,c-d],[a-c]], Covers).
Covers = [[a-c, c-b, c-d]].

如果要为具体应用程序编写过滤谓词,可能看起来像这样:

graph_covers(_Graph, [], []).
graph_covers(Graph, [Nodes|NodesRest], Covers) :-
    (   isItCov(Graph, Nodes)
    ->  Covers = [Nodes|CoversRest]
    ;   Covers = CoversRest ),
    graph_covers(Graph, NodesRest, CoversRest).

这与您的谓词类似,它只是添加了一个额外的参数来收集isItCov/2成功的节点列表。如果它没有成功,它将继续使用包含当前节点列表的列表 not

?- graph_covers([a-b,a-c,a-d,c-d,b-c], [[a-c,c-b,c-d],[a-c]], Covers).
Covers = [[a-c, c-b, c-d]] ;
false.