Prolog - 复制一份清单

时间:2014-08-27 16:37:20

标签: list copy prolog

我需要在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). 

但它无法正常工作。

但我只需要原始列表中的字符串。有人可以帮忙吗?

2 个答案:

答案 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(_,_)