从列表列表中返回元素 - prolog

1 list prolog

我有一个包含标题和分数的列表列表:[ [ 'title1',100 ],[ 'title2',200 ],...].如果我有一定的分数,我必须制作一个返回标题的谓词.find_title(Score,List,ListOfTitles).还有一些分数可能是相同的,这就是我试图将它存储在List中的原因.如果有多个标题具有相同的分数.

我试过这个:

return_title(Score,List,[H|T]):-
    return_title(Score,List,T),
    member([X,Score],List),
    H=X.
Run Code Online (Sandbox Code Playgroud)

但它不起作用..关于另一个实现的任何想法?

tas*_*tas 7

以声明的方式思考:只考虑谓词应该描述的内容.它是分数,标题和分数列表以及与第一个参数中的分数匹配的标题列表之间的关系.我发现找到谓词的描述性名称很有帮助,人们可以立刻看到哪个参数是什么.那么为什么不选择score_list_titles/3之类的东西.然后我想一下我的描述中有哪些案例要涵盖.对于这种关系,我看到三种情况:

score_list_titles(_S,[],[]).                 % 1: if list is empty titles is empty
score_list_titles(S,[[T,S]|TSs],[T|Ts]) :-   % 2: if score matches S, T is in titles
   score_list_titles(S,TSs,Ts).              % relation must hold for the tails as well
score_list_titles(S,[[T,X]|TSs],Ts) :-       % 3: if score
   dif(S,X),                                 % doesn't match S, T is not in titles
   score_list_titles(S,TSs,Ts).              % relation must hold for the tails as well
Run Code Online (Sandbox Code Playgroud)

查询此谓词会产生以下结果:哪些标题的分数分别为100,200和300?

   ?- score_list_titles(100,[['title1',100],['title2',200],['title3',100]],T).
T = [title1,title3] ? ;
no

   ?- score_list_titles(200,[['title1',100],['title2',200],['title3',100]],T).
T = [title2] ? ;
no

   ?- score_list_titles(300,[['title1',100],['title2',200],['title3',100]],T).
T = []
Run Code Online (Sandbox Code Playgroud)

什么标题有什么分数?

   ?- score_list_titles(S,[['title1',100],['title2',200],['title3',100]],T).
S = 100,
T = [title1,title3] ? ;
S = 200,
T = [title2] ? ;
T = [],
dif(S,100),
dif(S,200),
dif(S,100)
Run Code Online (Sandbox Code Playgroud)

您甚至可以使用if_/3更紧凑地表达这种关系:

score_list_titles(_S,[],[]).
score_list_titles(S,[[T,X]|TSs],TL) :-   % if S=X: T is in titles
   if_(S=X, TL=[T|Ts], TL=Ts),           % otherwise it isn't
   score_list_titles(S,TSs,Ts).          % relation must hold for the tails as well
Run Code Online (Sandbox Code Playgroud)

这样,谓词在前两个参数被接地的情况下甚至不会留下不必要的选择点(=不包含自由变量).您可以看到,如果您将以下查询与上述查询进行比较:在上述版本的score_list_titles/3中,我必须;在单个答案后输入,以获得没有进一步解决方案的反馈.

   ?- score_list_titles(100,[['title1',100],['title2',200],['title3',100]],T).
T = [title1,title3]

   ?- score_list_titles(200,[['title1',100],['title2',200],['title3',100]],T).
T = [title2]
Run Code Online (Sandbox Code Playgroud)