List 序言:集合与运算

List 序言:集合与运算,list,prolog,set,permutation,List,Prolog,Set,Permutation,我正在prolog中开发谓词来操作集合。我尝试使用以下内置预测实现3个谓词:member/2、append/3、length/2、permutation/2: 1) 列表到集合/2 将列表转换为集合的谓词。给定列表Xs=[1,2,3,3]我需要返回没有重复项的Xs的排列 输入 ?-列表到集合([3,1,a,a],Es)。 输出 ?- Es = [1,3,a]; ?- Es = [1,a,3]; ?- Es = [3,1,a]; ?- Es = [3,a,1]; ?- Es = [a,1,3];

我正在prolog中开发谓词来操作集合。我尝试使用以下内置预测实现3个谓词:member/2、append/3、length/2、permutation/2:

1) 列表到集合/2

将列表转换为集合的谓词。给定列表
Xs=[1,2,3,3]
我需要返回没有重复项的
Xs
的排列

输入

?-列表到集合([3,1,a,a],Es)。

输出

?- Es = [1,3,a];
?- Es = [1,a,3];
?- Es = [3,1,a];
?- Es = [3,a,1];
?- Es = [a,1,3];
?- Es = [a,3,1].

?- Es = [1,3,a];
?- Es = [1,a,3];
?- Es = [3,1,a];
?- Es = [3,a,1];
?- Es = [a,1,3];
?- Es = [a,3,1].
?- Es = [2, 4];
?- Es = [4, 2].
2) 工会/3

给定两个集合Xs,Rs。谓词
Union(Xs,Rs,Es)
检查
Es
是否是集合
Xs
Rs
之间的并集

输入

输出

?- Es = [1,3,a];
?- Es = [1,a,3];
?- Es = [3,1,a];
?- Es = [3,a,1];
?- Es = [a,1,3];
?- Es = [a,3,1].

?- Es = [1,3,a];
?- Es = [1,a,3];
?- Es = [3,1,a];
?- Es = [3,a,1];
?- Es = [a,1,3];
?- Es = [a,3,1].
?- Es = [2, 4];
?- Es = [4, 2].
4) 差异/3

给定两组Xs,Rs。谓词
Diff(Xs,Rs,Es)
检查
Es
是否是set
Xs
Rs
之间的差异

输入

输出

?- Es = [1,3,a];
?- Es = [1,a,3];
?- Es = [3,1,a];
?- Es = [3,a,1];
?- Es = [a,1,3];
?- Es = [a,3,1].

?- Es = [1,3,a];
?- Es = [1,a,3];
?- Es = [3,1,a];
?- Es = [3,a,1];
?- Es = [a,1,3];
?- Es = [a,3,1].
?- Es = [2, 4];
?- Es = [4, 2].
以下是我迄今为止所做的工作:

%list to set predicate
list_to_set(Xs , Cs) :-
  lpc(Xs, [], Cs).

lpc([], Rs, Rs).
lpc([X | Xs], Rs, Cs):-
    member(X, Rs),
    lpc(Xs, Rs, Cs).
lpc([X | Xs], Rs, Cs):-
    lpc(Xs, [X|Rs], Cs).

%union between two sets predicate
union([], _, _).
union([C|Cs], Ds, Es) :-
    member(C, Ds),
    union(Cs, Ds, Es).
union([C|Cs], Ds, [C|Es]) :-
    member(C, permutation(Cs, Es)),
    union(Cs, Ds, Es).

diff([], _, []).
diff([C |Cs], Ds, Es):-
    member(C, Ds),
    diff(Cs, Ds, Es).
diff([C | Cs], Ds, [C | Es]):-
    member(C, permutation(Cs, Es)),
    diff(Cs, Ds, Es).
伙计们,我如何调整上面的代码来处理排列?我尝试过各种实现,但都不起作用

  • 要设置的列表

     list_to_set([], []).
    
     list_to_set([H|T], Z):-
         member(H,T),
         list_to_set(T, Z1),!,
         permutation(Z1,Z).
    
     list_to_set([H|T], Z):-
         not(member(H,T)),
         list_to_set(T, Z1),!,
         append([H], Z1, Z2),
         permutation(Z2,Z).
    

  • 2) 联合

    警告:这不是集合并集操作,它更像是交叉点(代码基于您的示例)。
    3) 差异
    警告:这不是设置差分操作,它更像是对称差分(同样,代码基于您的示例)。
    如果不能使用减法谓词,定义自己的实现并不困难。

    不看实现,只检查查询
    联合([2,1,3,a],[4,1,3,a],Es)。
    :这里有全部3个!
    Es的排列
    。这将不容易扩展到更大的集合。您必须引入函数依赖关系,从而减少这些依赖关系!单一解决方案。