Пролог - скопировать часть списка

Мне нужно продублировать список в прологе.

У меня есть список:

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 ответа

Решение

Сопоставление с образцом используется для разложения аргументов: вы можете сделать

copy([],[]).
copy([a(H,_)|L1],[H|L2]) :- copy(L1,L2).

Редко использовать структуру 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).

Или, используя лямбды:

?- 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

Итак, мы достигли дна... Кажется, Пролог не любит термин a/2 в качестве первого аргумента.

Теперь добавьте

:- op(950,fx, *).

*_.

к вашей программе. Это своего рода упрощенный отладчик. И обобщить программу:

    COPY2([],[]).
    copy2([H|L1],[K|L2]):-
       Член (F (K,_), Н),
       * copy2 (L1, L2).

Участник только успешно с H существо формы [_|_], Но мы ожидаем, что это будет a(_,_),

Другие вопросы по тегам