Пролог - скопировать часть списка
Мне нужно продублировать список в прологе.
У меня есть список:
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(_,_)
,