序言,在元组列表中查找列表元素 [英] prolog, find list elements in a list of tuples

查看:79
本文介绍了序言,在元组列表中查找列表元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Prolog解决一个新程序,但遇到了麻烦,并且不知道如何继续...我必须做一个具有3个参数的谓词,第一个是元素列表,如果元组的第一个元素与第一个参数列表的元素匹配,则第二个是元组的列表,并且第三个必须是返回的包含元组的第二个元素的列表.它也必须删除副本!

I'm trying to solve a new program with Prolog, and I'm stuck, and don't know how to continue... I must do a predicate that has 3 arguments, the first is a list of elements, the second one is a list of tuples, and the third one must be a list returned that contains the second element of the tuples, if the first element of the tuple match with an element of the first argument list. It must delete copies also!!

例如,

check([a,c],[(a,aa),(bb,bbb),(a,aa),(c,def)],X).
X = [aa, def] .

如您所见,a和c在元组列表中匹配,因此返回元组的第二个元素.

As you can see, a and c match on the list of tuples, so return the second element of the tuples.

因此有效,但是,如果有多个元组包含与第一个列表匹配的第一个元素,则只需一次,例如:

So it works, BUT if there is more than one tuple that contains a first element that match on the first list, it only will take once, for example:

check([a,b],[(a,c),(a,d),(b,c),(b,e),(c,f)],X).
X = [c] .

它第一次找到a并取了c,第一次找到b并又取了c,但没有重复查找更多a或b,正确的结果应该是X = [c,d,e].

It finds a the first time and took c, and b the first time and took c again, but not iterate to find more a or b, the right result should be X=[c,d,e].

所以,请问您如何解决这种情况或解决问题的任何线索...

So please, I ask you help on how to solve this situation or any clue to solve it...

这是我的代码:

check([],_,[]).
check(L,DIC,Xord) :- inter(L,DIC,X), list_to_set(X,Xord).

inter([],_,[]).
inter(L1, DIC, L3) :- 
   L1 = [H|T], 
   DIC = [(DIC1,DIC2)|_], 
   H == DIC1, 
   L3 = [DIC2|L3T], 
   inter(T, DIC, L3T).
inter(L1,[_|DIC],L3) :- inter(L1,DIC,L3).
inter([_|T], DIC, L3) :- inter(T, DIC, L3).

提前感谢您的时间.

推荐答案

对于更容易理解的版本,我提出以下建议:

For an easier understandable version I propose the following:

:- use_module(library(lists)).

keys_dict_uniquevalues(Ks,D,UVs) :-
    keys_dict_values(Ks,D,Vs),              % Vs ... values with duplicates
    list_set(Vs,UVs).                       % UVs ... Vs deduplicated

keys_dict_values([],_D,[]).                 % No keys no values
keys_dict_values([Key|Keys],D,Vs) :-    
    key_dict_values(Key,D,Matches),         % all Matches for Key
    keys_dict_values(Keys,D,OtherVs),       % Matches for other Keys
    append(Matches,OtherVs,Vs).             % all found values in Vs

key_dict_values(_K,[],[]).                  % no mathes if dictionary empty
key_dict_values(K,[(K,V)|Pairs],[V|Vs]) :-  % Value is in list if key matches 
    key_dict_values(K,Pairs,Vs).
key_dict_values(K,[(X,_V)|Pairs],Vs) :-     % Value is not in list
    dif(K,X),                               % if key doesn't match
    key_dict_values(K,Pairs,Vs).

list_set([],[]).                            % empty list contains no duplicates
list_set([X|Xs],[X|Ys]) :-                  % head of the first list
    subtract(Xs,[X],Zs),                    % doesn't occur in Zs
    list_set(Zs,Ys).

如果要编写一个不使用库(列表)的程序,则必须替换keys_dict_values/3中的目标append/3和list_set/2中的目标减法/3.在下面的示例中,lists_appended/3和list_x_removed/3:

If you want so write a program without the use of library(lists) you have to replace the goal append/3 in keys_dict_values/3 and the goal subtract/3 in list_set/2. In the below example by lists_appended/3 and list_x_removed/3:

keys_dict_uniquevalues(Ks,D,UVs) :-
    keys_dict_values(Ks,D,Vs),
    list_set(Vs,UVs).

keys_dict_values([],_D,[]).
keys_dict_values([Key|Keys],D,Vs) :-
    key_dict_values(Key,D,Matches),
    keys_dict_values(Keys,D,OtherVs),
    lists_appended(Matches,OtherVs,Vs).

key_dict_values(_K,[],[]).
key_dict_values(K,[(K,V)|Pairs],[V|Vs]) :-
    key_dict_values(K,Pairs,Vs).
key_dict_values(K,[(X,_V)|Pairs],Vs) :-
    dif(K,X),
    key_dict_values(K,Pairs,Vs).

lists_appended([],L,L).
lists_appended([X|Xs],Ys,[X|Zs]) :-
    lists_appended(Xs,Ys,Zs).

list_set([],[]).
list_set([X|Xs],[X|Ys]) :-
    list_x_removed(Xs,X,Zs),
    list_set(Zs,Ys).

list_x_removed([],_X,[]).
list_x_removed([X|Xs],X,Ys) :-
    list_x_removed(Xs,X,Ys).
list_x_removed([X|Xs],Z,[X|Ys]) :-
    dif(X,Z),
    list_x_removed(Xs,Z,Ys).

以上示例中给出的查询适用于两个版本:

The queries given in the above exmaple work for both versions:

?- keys_dict_uniquevalues([a,c],[(a,aa),(bb,bbb),(a,aa),(c,def)],X).
X = [aa,def] ? ;
no
?- keys_dict_uniquevalues([a,b],[(a,c),(a,d),(b,c),(b,e),(c,f)],L).
L = [c,d,e] ? ;
no

@false所提供的反例在两个版本上均无法达到预期效果:

The counterexample provided by @false fails for both versions as expected:

?- keys_dict_uniquevalues([a,b],[(a,c),(a,d),(b,c),(b,e),(c,f)],[c,c]).
no

@false所建议的异常用法:

The unusual usage as suggested by @false:

   ?- keys_dict_uniquevalues([a,b],[KV1,KV2],[e]).
KV1 = KV2 = (a,e) ? ;
KV1 = (a,e),
KV2 = (b,e) ? ;
KV1 = (a,e),
KV2 = (_A,_B),
dif(b,_A),
dif(a,_A) ? ;
KV1 = (b,e),
KV2 = (a,e) ? ;
KV1 = (_A,_B),
KV2 = (a,e),
dif(b,_A),
dif(a,_A) ? ;
KV1 = KV2 = (b,e) ? ;
KV1 = (b,e),
KV2 = (_A,_B),
dif(b,_A),
dif(a,_A) ? ;
KV1 = (_A,_B),
KV2 = (b,e),
dif(b,_A),
dif(a,_A) ? ;
no

这篇关于序言,在元组列表中查找列表元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆