繁体   English   中英

如何从 Prolog 中的列表访问唯一对?

[英]How to access unique pairs from a list in Prolog?

我有一个列表L = [a, b, c]并且我想选择所有唯一的非重复对: [a, b], [a, c], [b, c] 如果我简单地使用成员 function,它当然会选择每个排列,所以我必须有一个谓词

pick_pair(List, X, Y) :-
    member(X, List),
    member(Y, List),
    \+ X = Y.

为了访问成员,我使用另一个谓词将所有对收集到一个列表中

unique_pairs(List, Result) :-
    findall([X, Y], pick_pair(List, X, Y), Result).

然后我才访问结果列表,但它会生成[[a, b], [a, c], [b, a], [b, c], [c, a], [c, b]] 我试图摆脱那些与list_to_set已经存在的对相反的对,但是[a, b][b, a]在默认情况下不统一,所以它们被认为是不相等的,因此属于集合。 我会以某种方式需要为 function 或类似的东西超载统一。

我的问题是:

我们可以只访问列表中的对吗? my_pairs(X, Y, L)这样的东西会将对元素直接分配给XY 如果没有这样的谓词,我们如何制作唯一对的列表,以便我们可以使用member(X, List)访问其元素?

顺便说一下,这个问题相当于得到所有长度为 2 的组合。

可以使用select的自定义变体:

unique_pairs(L, E1, E2) :-
    select_forward(E1, L, L0),
    member(E2, L0).
    
select_forward(E, [H|T], F) :-
    select_forward_(T, H, E, F).
    
select_forward_(T, H, H, T).
select_forward_([H|T], _, E, F) :-
    select_forward_(T, H, E, F).

swi-prolog 中的结果:

?- unique_pairs([a,b,c], E1, E2).
E1 = a,
E2 = b ;
E1 = a,
E2 = c ;
E1 = b,
E2 = c ;
false.

在 Prolog 中一次生成nm件物品的组合很容易:

combination( 0 , _      , []     ) .
combination( N , [X|Xs] , [X|Ys] ) :- N > 0, N1 is N-1, combination(N1,Xs,Ys).
combination( N , [_|Xs] ,    Ys  ) :- N > 0, combination(N,Xs,Ys).

一旦你有了它,你的pick_pair/2就变成了:

pick_pair( Xs, P ) :- combination(2,Xs,P) .

您还可以通过算术构造组合:您只需要传递包含变量的所需长度的列表——就是这样:

combination( _      , []     ) .
combination( [X|Xs] , [X|Ys] ) :- combination(Xs,Ys).
combination( [_|Xs] , [Y|Ys] ) :- combination(Xs,[Y|Ys]).

使用此实现,如果第二个参数完全未实例化,它将生成从 0 到源列表长度的任意长度的所有组合。 如果第一个参数未实例化......它可能会产生一组[理论上]无限的结果。

有了这个实现,你的pick_pair/2就变成了

pick_pair( Xs, [P,Q] ) :- combination(Xs, [P,Q] ).

或者可能

pick_pair( Xs, P ) :- length(P,2), combination(Xs,P).

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM