首页 > 解决方案 > Prolog问题,操作列表列表

问题描述

我是 Prolog 的新手,有一个问题:

假设我有一个列表列表;[list1, list2, list3,..., list_n]

如果 list_j包含list_i,即每个变量都list_i出现在list_j,则删除list_j

例如,如果输入是

[[a,b,c], [a,c], [a,d], [a,d,e]]

输出应该是

[[a,c], [a,d]]

因为[a,b,c]contains[a,c][a,d,e]contains [a,d]

如何在 SWI-Prolog 中实现这一点?任何帮助表示赞赏。

标签: prolog

解决方案


首先,SWI 已经有一个谓词来检查一个列表是否在另一个列表中“包含”(就集合包含而言)subset/2:( http://www.swi-prolog.org/pldoc/man?predicate=subset /2 )。

现在您可以使用它来检查是否从所有列表中删除特定列表:

remove(Lists, List) :-
    member(List, Lists),
    member(Sublist, Lists),
    Sublist \= List,
    subset(Sublist, List).

读作:remove ListfromLists如果它是 a memberofLists并且还有另一个(由 确认\=memberof Lists(call it Sublist),它是 a subsetof List

?- remove([[a,b,c], [a,c], [a,d], [a,d,e]], L).
L = [a, b, c] ;
L = [a, d, e] ;

现在你可以用它来回答你原来的问题:

remaining(Lists, Remaining) :-
    bagof(List,
          ( 
              member(List, Lists),
              \+ remove(Lists, List)
          ),
          Remaining).

让这些列表Remaining来自Lists哪些是member原始列表的 s 而Lists不是 ( \+) 是removed。

?- remaining([[a,b,c], [a,c], [a,d], [a,d,e]], Remaining).
Remaining = [[a, c], [a, d]].

推荐阅读