List 序言:过滤器和列表

List 序言:过滤器和列表,list,filter,prolog,List,Filter,Prolog,构造一个名为fPairsAtoms/3的谓词,以便给定一个原子(第一个参数)和一个对列表,通过仅选择具有第一个组件的对作为第一个参数的原子,将第三个参数与过滤后的对列表统一起来 例如: fPairsAtoms(sA,[[basA,absAb],[ab,bbsA],[sA,abbsB],[bsA,sAsB],[sA,bb]],X) 结果: X = [[sA,abbsB],[sA,bb]] 我不明白。。。。。我应该面对哪些类型的练习? 你能帮我找到解决办法吗 今天我从prolog开始,在各个

构造一个名为fPairsAtoms/3的谓词,以便给定一个原子(第一个参数)和一个对列表,通过仅选择具有第一个组件的对作为第一个参数的原子,将第三个参数与过滤后的对列表统一起来

例如:

fPairsAtoms(sA,[[basA,absAb],[ab,bbsA],[sA,abbsB],[bsA,sAsB],[sA,bb]],X)  
结果:

X = [[sA,abbsB],[sA,bb]]
我不明白。。。。。我应该面对哪些类型的练习? 你能帮我找到解决办法吗


今天我从prolog开始,在各个方面我都是新手。如果你今天才开始,解决这个问题可能有点太早了

首先,您应该了解Prolog术语是什么:
atoms
、逻辑
变量
、复合术语
foo(x,x,bar(baz))

然后你应该理解统一,
a=a
a=a
a=a
a=foo(a)
foo(a)=foo(a)
[atom,B]=[a,bar]

您应该了解列表表示,其中

[A,B,C]
=[A,B |[C]]
=[A |[B,C]]
=[A |[B |[C]]
= .... 
=[A、B、C |[]]
因此,统一
[A | B]=[A]
成功,导致也统一
A=A
B=[]
,但统一
[A | B]=[]
失败

然后你需要理解谓词,这在程序解释中意味着

证明(这个):-需要证明(这个),也需要证明(那个)。
所以

fPairsAtoms(sA,[[basA,absAb],[ab,bbsA],[sA,abbsB],[bsA,sAsB],[sA,bb]],X):-
X=[[sA,abbsB],[sA,bb]]。
这是一个完全正确的定义,尽管非常狭窄

但我们也一样

fPairsAtoms(sA,[[basA,absAb],[ab,bbsA],[sA,abbsB]|[[bsA,sAsB],[sA,bb]],X):-
X=[[sA,abbsB]|[[sA,bb]]。
%及
FPA原子(sA,[[ab,bbsA],[sA,abbsB]|[[bsA,sAsB],[sA,bb]],X):-
X=[[sA,abbsB]|[[sA,bb]]。
%及
fPairsAtoms(sA,[[sA,abbsB]|[[bsA,sAsB],[sA,bb]]],X):-
X=[[sA,abbsB]|[[sA,bb]]。
%及
FPA原子(sA,[[bsA,sAsB],[sA,bb]],Y):-
Y=[[sA,bb]]。
% ... 及
FPA原子(sA,[],Y):-
Y=[]。
而且

fPairsAtoms(sA,[[sA,abbsB]| L],X):-
L=[[bsA,sAsB],[sA,bb]],
Y=[[sA,bb]],
X=[[sA,abbsB]| Y]。
因此

fPairsAtoms(sA,[[sA,abbsB]| L],X):-
L=[[bsA,sAsB],[sA,bb]],
原子(L,Y),
Y=[[sA,bb]],
X=[[sA,abbsB]| Y]。
%及
fPairsAtoms(sA,[[sA,abbsB]| L],X):-
L=[[bsA,sAsB],[sA,bb]],
原子(L,Y),
X=[[sA,abbsB]| Y]。
%及
fPairsAtoms(sA,[[sA,abbsB]| L],X):-
原子(L,Y),
X=[[sA,abbsB]| Y]。
%诸如此类
fPairsAtoms(sA[A | L],X):-
A=[sA,B],
原子(L,Y),
X=[A | Y]。
%甚至
fPairsAtoms(SA[A | L],X):-
A=[SA,B],
原子(SA,L,Y),
X=[A | Y]。
但另一方面,如果没有匹配,我们看到它是匹配的

fPairsAtoms(SA[A | L],X):-
A=[SB,B],
dif(SA,SB),
原子(SA,L,Y),
X=Y。
%即。
fPairsAtoms(SA,[[SB,B]| L],X):-
dif(SA,SB),
原子(SA,L,X)。
那么我们最后得到的两条条款中的哪一条

fPairsAtoms(SA,[[SA,|]| L],X):-
原子(SA,L,Y),
X=[A | Y]。
Fpairatoms(SA,[[SB,|]L],X):-
dif(SA,SB),
原子(SA,L,X)。

是正确的吗?答案是:两者都有

要过滤列表中的对,您需要遍历它,同时将给定的原子与每对中的第一个元素进行比较。遍历列表的一个简单谓词是:

traverse([]).
traverse([Head| Tail]) :-
    traverse(Tail).
问题描述中的谓词命名错误,不遵循推荐的Prolog编码准则。让我们将其重命名为
filter\u pairs\u by\u key/3
,并将参数顺序更改为
filter\u pairs\u by\u key(pairs,SearchKey,FilteredPairs)
。此外,建议在Prolog中使用键值对的表示形式为
键值
。有一些标准谓词和库谓词需要这种表示(例如,
keysort/2
)。基于
traverse/2
谓词模板和代码风格建议,我们可以编写:

filter_pairs_by_key([], _, []).
filter_pairs_by_key([Key-Value| Pairs], SearchKey, [Key-Value| FilteredPairs]) :-
     Key = SearchKey, 
     filter_pairs_by_key(Pairs, Atom, FilteredPairs).
filter_pairs_by_key([Key-_| Pairs], SearchKey, FilteredPairs) :-
     Key \= SearchKey, 
     filter_pairs_by_key(Pairs, SearchKey, FilteredPairs).
| ?- filter_pairs_by_key([basA-absAb,ab-bbsA,sA-abbsB,bsA-sAsB,sA-bb], sA, FilteredPairs).          

FilteredPairs = [sA-abbsB,sA-bb] ? 

yes