我要做的是将两个列表中的元素追加到另一个列表中,最后在控制台中获取新列表的值。 我的清单是:A = [a,b]; B(对列表)= [(c,cc),(a,aa),(b,bb)] 如果第一个元素匹配pair的第一个元素(字典原则),我想添加列表B对的第二个元素。我希望所有这些元素都添加到控制台输出的空列表中。 到目前为止我所拥有的是(X将是空列表):
aa(_, [], _) :-
true.
aa([H|T], [(A, B)|T2], X) :-
H == A ->
append([B], X, X2), aa([H|T], T2, X2);
aa([H|T], T2, X).
在控制台中输入:read(X), trace,aa([a, b], [(c, cc), (a, aa), (b, bb)], X), write(X).
但是它一直返回X的[]值。如果我要求X,我怎样才能得到X2的值作为输出? 这是跟踪输出:
Call:aa([a, b], [(c,cc), (a,aa), (b,bb)], [])
Call:a==c
Fail:a==c
Redo:aa([a, b], [(c,cc), (a,aa), (b,bb)], [])
Call:aa([a, b], [(a,aa), (b,bb)], [])
Call:a==a
Exit:a==a
Call:lists:append([aa], [], _2110)
Exit:lists:append([aa], [], [aa])
Call:aa([a, b], [(b,bb)], [aa])
Call:a==b
Fail:a==b
Redo:aa([a, b], [(b,bb)], [aa])
Call:aa([a, b], [], [aa])
Exit:aa([a, b], [], [aa])
Exit:aa([a, b], [(b,bb)], [aa])
Exit:aa([a, b], [(a,aa), (b,bb)], [])
Exit:aa([a, b], [(c,cc), (a,aa), (b,bb)], [])
Call:write([])
[]
Exit:write([])
答案 0 :(得分:1)
将;
放在一行的末尾并不是一个好主意,很容易忽略它。我更喜欢不同的格式,见下文。至于你的问题,你有append/3
的错误顺序的参数。 X2
是递归调用的中间结果,您希望"返回"是此X2
与元素B
:
aa(_, [], _) :-
true.
aa([H|T], [(A, B)|T2], X) :-
( H == A
-> append([B], X2, X), aa([H|T], T2, X2)
; aa([H|T], T2, X) ).
目标append([B], X2, X)
可以更清晰地写为X = [B|X2]
。
这解决了眼前的问题,但还不是整个谓词:
?- aa([a, b], [(c, cc), (a, aa), (b, bb)], X).
X = [aa|_G22] ;
false.
您将第一个参数分解为[H|T]
但实际上并未对此列表进行递归,因此您永远不会在b
及其对应列表中查看其对应的元素。
这是完成整个事情的简单方法:
aa([], _Pairs, []).
aa([Key|Keys], Pairs, Values) :-
( member((Key, Value), Pairs)
-> aa(Keys, Pairs, Values0),
Values = [Value|Values0]
; aa(Keys, Pairs, Values) ).
这里的主要见解是,一旦您知道Key
,就可以在对话列表中查找一对(Key, Value)
。 Value
尚未绑定到值,如果列表包含第一个元素为member/2
的对,则Key
将对其进行实例化。这是统一的力量!
这似乎有效:
?- aa([a, b], [(c, cc), (a, aa), (b, bb)], X).
X = [aa, bb].
最后,您可能不希望在此之前拥有read(X)
,因为这意味着用户必须预测解决方案!