List 序言,删除列表列表中的超集

List 序言,删除列表列表中的超集,list,prolog,subset,superset,List,Prolog,Subset,Superset,假设我有以下列表: List = [[a],[a,b],[a,c],[b,c],[b,d],[a,b,c],[a,b,d],[b,c,e],[b,d,e,f]] 目标是删除列表中作为列表超集的每个列表 包含列表的列表始终具有以下属性: 列表中的列表按长度排序 列表中的每个列表都已排序 我最初的想法是简单地从列表中的第一个列表开始,遍历所有其他列表并删除作为超集的列表。接下来我看第二张单子,诸如此类 删除列表[a]的所有超集后,它应该如下所示: List = [[a],[b,c],[b,d]

假设我有以下列表:

List = [[a],[a,b],[a,c],[b,c],[b,d],[a,b,c],[a,b,d],[b,c,e],[b,d,e,f]]
目标是删除列表中作为列表超集的每个列表

包含列表的列表始终具有以下属性:

  • 列表中的列表按长度排序
  • 列表中的每个列表都已排序
我最初的想法是简单地从列表中的第一个列表开始,遍历所有其他列表并删除作为超集的列表。接下来我看第二张单子,诸如此类

删除列表[a]的所有超集后,它应该如下所示:

List = [[a],[b,c],[b,d],[b,c,e],[b,d,e,f]]
接下来,应删除[b,c]的超集:

List = [[a],[b,c],[b,d],[b,d,e,f]]
最后是[b,d]的超集:

List = [[a],[b,c],[b,d]]
上面这一行应该是结果

我已经创建了一个类似于成员谓词的谓词,但它不是获取单个元素并将其与列表进行比较,而是获取整个列表并将其与列表进行比较:

memberList([],_).
memberList([X|Xs],Y) :-
    member(X,Y),
    memberList(Xs,Y).
这只适用于列表

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

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

?- memberList([a,b],[a,b,c]).
true .
但在这之后我有点迷路了

我尝试了以下方法,可以删除单个集合的超集,但不起作用:

removeSupersetsList(_,[],[]).
removeSupersetsList(X,[Y|Ys],[Y|Out]) :-
    not(memberList(X,Y)),
    removeSupersetsList(X,Ys,Out).
removeSupersetsList(X,[Y|Ys],Out) :-
    memberList(X,Y),
    removeSupersetsList(X,Ys,Out).

所以我想知道是否有人能给我指出正确的方向,从列表中删除所有超集,或者甚至给出正确的谓词。

-Hello Xylon,我想我理解你的想法,所以我尝试用这个想法创建了一个解决方案。在这里(让我知道它是否适合您的需要,或者它是否有bug…)

%删除(ToRemove、ListWithPublists、LocRez、FinalRez)

%ListWithPublists中的列表将被删除,具体取决于要删除的列表

%LocRez是用于获取最终值的累加器(在末尾)

remove(_,[],LocRez,LocRez) :- !.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         memberList(ToRemove,Sublist),
                                                         remove(ToRemove,Rest,LocRez,FinalRez),!.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         not(memberList(ToRemove,Sublist)),
                                                         append(LocRez,[Sublist],LocRezNew),
                                                         remove(ToRemove,Rest,LocRezNew,FinalRez),!.
removeSupersetsList(List,Rez):-removeSupersetsList(List,[],Rez)%调用此进行测试

remove(_,[],LocRez,LocRez) :- !.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         memberList(ToRemove,Sublist),
                                                         remove(ToRemove,Rest,LocRez,FinalRez),!.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         not(memberList(ToRemove,Sublist)),
                                                         append(LocRez,[Sublist],LocRezNew),
                                                         remove(ToRemove,Rest,LocRezNew,FinalRez),!.
%删除超级设置列表(列表、LocRez、最终版)

remove(_,[],LocRez,LocRez) :- !.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         memberList(ToRemove,Sublist),
                                                         remove(ToRemove,Rest,LocRez,FinalRez),!.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         not(memberList(ToRemove,Sublist)),
                                                         append(LocRez,[Sublist],LocRezNew),
                                                         remove(ToRemove,Rest,LocRezNew,FinalRez),!.
%如果需要,从列表中删除列表头(在此过程中获得Rez)

remove(_,[],LocRez,LocRez) :- !.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         memberList(ToRemove,Sublist),
                                                         remove(ToRemove,Rest,LocRez,FinalRez),!.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         not(memberList(ToRemove,Sublist)),
                                                         append(LocRez,[Sublist],LocRezNew),
                                                         remove(ToRemove,Rest,LocRezNew,FinalRez),!.
%将头部附加到我们的LocRez中(获取LocRezNew),

remove(_,[],LocRez,LocRez) :- !.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         memberList(ToRemove,Sublist),
                                                         remove(ToRemove,Rest,LocRez,FinalRez),!.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         not(memberList(ToRemove,Sublist)),
                                                         append(LocRez,[Sublist],LocRezNew),
                                                         remove(ToRemove,Rest,LocRezNew,FinalRez),!.
%为Rez递归调用此函数

remove(_,[],LocRez,LocRez) :- !.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         memberList(ToRemove,Sublist),
                                                         remove(ToRemove,Rest,LocRez,FinalRez),!.

remove(ToRemove,ListWithSublists,LocRez,FinalRez) :-     ListWithSublists=[Sublist|Rest],
                                                         not(memberList(ToRemove,Sublist)),
                                                         append(LocRez,[Sublist],LocRezNew),
                                                         remove(ToRemove,Rest,LocRezNew,FinalRez),!.
removeSupersetsList(List,LocRez,LocRez) :- List=[] ,!.
removeSupersetsList(List,LocRez,Final) :- ( List=[ToRemove|_] ; List=[ToRemove] ),
                                          remove(ToRemove,List,[],Rez),
                                          append(LocRez,[ToRemove],LocRezNew),
                                          removeSupersetsList(Rez,LocRezNew,Final),!.

我使用的是SWI Prolog,在那里我找到了一个精心制作的库,然后使用/3可以很容易地清理列表

rem_super_sets([], []).
rem_super_sets([L|Ls], R) :-
    (   select(T, Ls, L1), % get any T in Ls
        ord_subset(L, T)   % is T a superset of L ?
    ->  rem_super_sets([L|L1], R) % discard T, keep L for further tests
    ;   R = [L|L2],
        rem_super_sets(Ls, L2)
    ).
这里有一个验证和结果

test :-
    List = [[a],[a,b],[a,c],[b,c],[b,d],[a,b,c],[a,b,d],[b,c,e],[b,d,e,f]],
    rem_super_sets(List, R),
    write(R).

?- test.
[[a],[b,c],[b,d]]
true.

非常感谢,这正是我们需要的。我们应该更加注意默认谓词,因为这是一个很好的实现。您曾暗示过这一点,但这只适用于按长度排序的集合。非常感谢您的时间和创建的解决方案。