Prolog搜索键/值列表并输出值列表

Prolog搜索键/值列表并输出值列表,prolog,Prolog,我再一次被一个非常简单的序言任务困住了。我想定义一个谓词kv_search/3,它接受一个键/值列表,例如[[a,1],[b,2],[c,3],[d,4],[e,8],[a,9],[b,10]作为第一个参数,一个键作为第二个参数,并在第三个参数中输出一个包含该键的所有值的列表 我目前的做法如下: kv_find([[K,V|_]|Rest], K, Result) :- kv_find(Rest, K, [V|Result]). kv_find([[Ks,_|_]|Rest], K,

我再一次被一个非常简单的序言任务困住了。我想定义一个谓词
kv_search/3
,它接受一个键/值列表,例如
[[a,1],[b,2],[c,3],[d,4],[e,8],[a,9],[b,10]
作为第一个参数,一个键作为第二个参数,并在第三个参数中输出一个包含该键的所有值的列表

我目前的做法如下:

kv_find([[K,V|_]|Rest], K, Result) :- 
    kv_find(Rest, K, [V|Result]).

kv_find([[Ks,_|_]|Rest], K, Result) :-
    Ks \= K ,
    kv_find(Rest, K, Result).

kv_find([], _, _).
但是,此解决方案的问题是,它只输出true或false,而不是打印缺少的参数

例如,以下查询结果为
true
,而不是我预期的
B=[1,9]

kv_find([[a,1],[b,2],[c,3],[d,4],[e,8],[a,9],[b,10]], a, B).

如果该键不在列表中,我想输出一个空列表。

首先,您的基本情况是错误的,您需要写:

kv_find([], _, []).
因为对于空列表,只有空输出列表应该成功

然后,解决方案中的另一个问题是,您正在编写:

kv_find([[K,V|_]|Rest], K, Result) :- 
    kv_find(Rest, K, [V|Result]).
而你应该写一些像:

kv_find([[K,V|_]|Rest], K, [V | Result]) :- 
    kv_find(Rest, K, Result).
kv_find([[K,V]|Rest], K, [V|Result]) :- 
    kv_find(Rest, K, Result).

kv_find([[Ks,_]|Rest], K, Result) :-
    dif(Ks, K) ,
    kv_find(Rest, K, Result).

kv_find([], _, []).
上面的规则使用了错误的基本情况,使得您的谓词对于任何第三个列表总是成功的

此外,通过一些修改,我将写下如下内容:

kv_find([[K,V|_]|Rest], K, [V | Result]) :- 
    kv_find(Rest, K, Result).
kv_find([[K,V]|Rest], K, [V|Result]) :- 
    kv_find(Rest, K, Result).

kv_find([[Ks,_]|Rest], K, Result) :-
    dif(Ks, K) ,
    kv_find(Rest, K, Result).

kv_find([], _, []).

你能解释一下你的基本情况背后的原因吗?例如,
kv_应该找到什么([],a,X)
绑定到
X
(如果有的话)?对于这个任务,我们可以假设第一个参数是一个有效的键/值列表,格式如我所示。但是您的示例可能会导致
X=[]
“可能”?可能是别的什么?你的代码不是这样运行的。但我直到现在才想到这种情况,因为我的练习没有指定这种情况。@JohnnyKonfetti“我的练习没有指定这种情况。”这不是真的,当你有递归时,你需要始终考虑正确的基本情况,因为错误的基本情况可能导致错误的整体谓词。。。