我需要在prolog中复制列表。
我有清单:
L = [a(string1,value1),a(string2,value2),a(string3,value3),a(string4,value4)].
输出将是:L = [string1, string2, string3, string4]
。
我该怎么做?
我可以按代码复制整个列表:
copy([],[]).
copy([H|L1],[H|L2]) :- copy(L1,L2).
我尝试过类似的事情:
copy2([],[]).
copy2([H|L1],[K|L2]) :- member(f(K,_),H), copy2(L1,L2).
但它无法正常工作。
但我只需要原始列表中的字符串。有人可以帮忙吗?
答案 0 :(得分:4)
模式匹配用于分解参数:你可以做
copy([],[]).
copy([a(H,_)|L1],[H|L2]) :- copy(L1,L2).
答案 1 :(得分:4)
为此目的使用结构a/2
并不常见。更常见的是,(-)/2
用于此目的。 Key-Value
被称为(键值)对。
这个名字本身也不是很自我揭示。这根本不是副本。相反,从第一个参数的名称开始,然后是第二个参数的名称。让我们试试:list_list/2
。这个名字有点过于笼统,所以也许apairs_keys/2
。
?- apairs_keys([a(string1,value1),a(string2,value2)], [string1, string2]).
以下是一些定义:
apairs_keys([], []).
apairs_keys([a(K,_)|As], [K|Ks]) :-
apairs_keys(As, Ks).
或者,而是使用maplist:
apair_key(a(K,_),K).
?- maplist(apair_key, As, Ks).
或者,使用lambdas:
?- maplist(\a(K,_)^K^true, As, Ks).
也许您还想了解如何在原始程序中快速本地化错误。为此,请从有问题的程序和查询开始:
copy2([],[]).
copy2([H|L1],[K|L2]) :-
member(f(K,_),H),
copy2(L1,L2).
| ?- copy2([a(string1,value1),a(string2,value2),a(string3,value3),a(string4,value4)], [string1, string2, string3, string4]).
no
现在,概括查询。也就是说,用新的新变量替换术语:
| ?- copy2([a(string1,value1),a(string2,value2),a(string3,value3),a(string4,value4)], [A, B, C, D]).
no
| ?- copy2([a(string1,value1),a(string2,value2),a(string3,value3),a(string4,value4)], L).
no
| ?- copy2([a(string1,value1),B,C,D], L).
no
| ?- copy2([a(string1,value1)|J], L).
no
| ?- copy2([a(S,V)|J], L).
no
| ?- copy2([A|J], L).
A = [f(_A,_B)|_C],
L = [_A|_D] ?
yes
所以我们触底了......似乎Prolog不喜欢术语a/2
作为第一个参数。
现在,添加
:- op(950,fx, *).
*_.
到你的程序。它是一种简单的调试器。并概括了该计划:
copy2([],[]). copy2([H|L1],[K|L2]) :- member(f(K,_),H), *copy2(L1,L2).
会员仅在H
格式为[_|_]
时才会成功。但我们希望它是a(_,_)
。