Первые элементы списка списка Пролог

Вопрос задан: 7 месяцев назад Последняя активность: 7 месяцев назад
up 1 down

Я изучаю Пролог и вижу этот код

foo([],[]).
foo([[A,_ ]|L], [A|P]) :-foo(L ,P).

В результате говорят, что этот код занимает N элемент списка списка, Пример объявления, если мы даем этот запрос:

?foo([[car],[house],[man]],X)
X= [c,h,m]

При первом прочтении я вижу, что что-то не так. Для меня этот код берет хвост списка списка и остальную часть первого элемента списка, поэтому для меня первое расширение будет (трассировка)

foo([[house],[man]], ar)
foo([[man]], ouse)
foo([], an)
false.

Я пытаюсь скомпилировать с swi-прологом и дать этот след:

[trace]  ?- trace,foo([[car],[house],[man]],X).
Call: (9) foo([[car], [house], [man]], _1016) ? creep
Fail: (9) foo([[car], [house], [man]], _1016) ? creep
false.

Что я не прав?

1 ответ

up 2 down accepted

Получение первых элементов

Шаблон [A, _] в вашей статье неправильно или, по крайней мере, не достаточно обобщенно. [A, _] объединяется со списком, который содержит ровно два элемента, но, таким образом, это не сработает для списков с более чем двумя элементами или с одним элементом, как вы выяснили.

Вам нужно использовать [A|_] шаблон: действительно список, где голова A, и нас не интересует остальное (хвост). лайк:

foo([],[]).
foo([[A|_]|L], [A|P]) :- foo(L, P).

При этом вы можете упростить это, внедрив предикат, который занимает заголовок списка:

head([H|_], H).

а затем использовать maplist/3 [SWI-документ]:

foo(A, B) :-
    maplist(head, A, B).

maplist призовет head лайк head(Ai, Bi), с Ai а также Bi элементы A а также B соответственно.

Получение подстроки с первым символом

но на основе примера вывода это не то, что вам нужно: вы также хотите получить первый «символ» атома, мы можем сделать это, используя string_chars/2 [SWI-документ]:

head_first([A|_], C) :-
    string_chars(A, [C|_]).

а затем определить foo/2 снова с maplist/3 [SWI-документ]:

foo(A, B) :-
    maplist(head_first, A, B).

тогда мы получим:

?- foo([[car],[house],[man]], X).
X = [c, h, m].