尝试实现以下谓词,它接受输入
并测试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]).
)调用它时,我遇到了一个问题,这些列表应仅适用于第一个列表。
我实际上有两个问题 -
true
(这是过滤部分)。我该怎么做?答案 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.