List 序言:过滤器和列表
构造一个名为fPairsAtoms/3的谓词,以便给定一个原子(第一个参数)和一个对列表,通过仅选择具有第一个组件的对作为第一个参数的原子,将第三个参数与过滤后的对列表统一起来 例如: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(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