с предикатом (выписать_список), после чего про-
верьте следующую цель:
write_a_list([2,4,6,8,10])
Добавление одного списка к другому,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
декларативное и процедурное программирование
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Предикат member, рассмотренный нами в программе 11, может
работать двумя способами. Посмотрим на соответствующие ему
предложения еще раз:
member(Name,[Name|_]).
member(Name,[_|Tail]) if member(Name,Tail).
Об этих предложениях можно говорить с двух разных точек зре-
ния. С декларативной точки зрения здесь говорится, что имеет-
ся список, переменная Name есть член этого списка, если его
голова - это Name; если же нет, то Name есть член списка, ес-
ли Name - член его остатка. С процедурной точки зрения эти
предложения можно было бы интерпретировать так: чтобы найти
член списка, найдите его голову, а если не удалось, то найди-
те член остатка списка.
Эти две точки зрения соответствуют целям
member(2,[1,2,3,4]).
и
member(X,[1,2,3,4]).
так как, на самом деле, первая цель просит Турбо Пролог про-
верить, что нечто является истиной, в то время как вторая
цель просит его отыскать все члены списка [1,2,3,4].
Прелесть Турбо Пролога часто заключается в том, что если
мы строим предложения для некоторого предиката с одной точки
зрения, то работать они будут совсем с другой. В качестве
примера, подтверждающего это, мы построим сейчас предикат,
служащий для присоединения одного списка к другому. Давайте,
например, соединим списки [1,2,3] и [4,5], чтобы получить
список [1,2,3,4,5]. Определим предикат append (присоединить),
имеющий три аргумента:
append(List1,List2,List3)
Этот предикат объединяет списки List1 и List2 в список List3.
В данном случае мы еще раз пользуемся рекурсией (с процедур-
ной точки зрения).
Если список List1 пуст, то результат соединения списков
List1 b List2 , будет совпадать со списком List2. На Турбо
Прологе это выглядит следующим образом:
append([],List2,List2)
В противном случае мы можем объединить списки List1 и List2 в
список List3,сделав голову списка List1 головой списка List3.
(Ниже в качестве общей головы списков List1 и List3 использу-
ется переменная Х). Оставшаяся часть списка List3 (его оста-
ток) получается за счет объединения оставшейся части списка
List1 и всего списка List2. (Остаток списка List3 - это L3,
что является результатом объединения оставшейся части списка
List1, именуемой L1, и всего списка List2.). На Турбо Прологе
это записывается следующим образом:
append([X|L1],List2,[X|L3]) if
append(L1,List2,L3)
Таким образом, предикат append (присоединить) действует так:
пока список List1 не пуст, рекурсивное правило каждый раз пе-
реводит один его элемент в список List3. Когда список List1
оказывается пустым, первое предложение обеспечивает подсоеди-
нение списка List2 к хвосту списка List3.
Упражнение. В программе на Турбо Прологе, приведенной ни-
же, определены два предиката append и writelist (вывод_спис-
ка). Набейте эту программу и выполните ее со следующей целью: