Программирование на языке Пролог для искусственного интеллекта | страница 49



>  июль, авг, сент, окт, ноябрь, дек]).


>Месяц1 = апр

>Месяц2 = июнь

Более того, мы сможем, например, удалить из некоторого списка L1 все, что следует за тремя последовательными вхождениями элемента z в L1 вместе с этими тремя z. Например, это можно сделать так:

>?- L1 = [a, b, z, z, c, z, z, z, d, e],

> конк( L2, [z, z, z | _ ], L1).


>L1 = [a, b, z, z, c, z, z, z, d, e]

>L2 = [a, b, z, z, c]

Мы уже запрограммировали отношение принадлежности. Однако, используя >конк, можно было бы определить это отношение следующим эквивалентным способом:

>принадлежит1( X, L) :-

> конк( L1, [X | L2], L).

Рис. 3.3. Процедура >принадлежит1 находит элемент в заданном списке, производя по нему последовательный поиск.

В этом предложении сказано: "X принадлежит L, если список L можно разбить на два списка таким образом, чтобы элемент X являлся головой второго из них. Разумеется, >принадлежит1 определяет то же самое отношение, что и >принадлежит. Мы использовали другое имя только для того, чтобы различать таким образом две разные реализации этого отношения, Заметим, что, используя анонимную переменную, можно записать вышеприведенное предложение так:

>принадлежит1( X, L) :-

> конк( _, [X | _ ], L).

Интересно сравнить между собой эти две реализации отношения принадлежности. >Принадлежит имеет довольно очевидный процедурный смысл:

 Для проверки, является ли X элементом списка L, нужно

 (1) сначала проверить, не совпадает ли голова списка L с X, а затем

 (2) проверить, не принадлежит ли X хвосту списка L.

С другой стороны, >принадлежит1, наоборот, имеет очевидный декларативный смысл, но его процедурный смысл не столь очевиден.

Интересным упражнением было бы следующее: выяснить, как в действительности >принадлежит1 что-либо вычисляет. Некоторое представление об этом мы получим, рассмотрев запись всех шагов вычисления ответа на вопрос:

>?-  принадлежит1( b, [а, b, с] ).

На рис. 3.3 приведена эта запись. Из нее можно заключить, что >принадлежит1 ведет себя точно так же, как и >принадлежит. Он просматривает список элемент за элементом до тех пор, пока не найдет нужный или пока не кончится список.

Упражнения

3.1. (а) Используя отношение >конк, напишите цель, соответствующую вычеркиванию трех последних элементов списка L, результат — новый список L1. Указание: L — конкатенация L1 и трехэлементного списка.

(b) Напишите последовательность целей для порождения списка L2, получающегося из списка L вычеркиванием его трех первых и трех последних элементов.