?-  findall( Буква, класс( Буква, Класс), Буквы).

        Буквы= [a, b, c, d, e, f]

Если не существует ни одного объекта X, удовлетворяющего P, то findall все равно имеет успех и выдает L = [ ].

Если в используемой реализации Пролога отсутствует встроенный предикат findall, то его легко запрограммировать следующим образом. Все решения для Р порождаются искусственно вызываемыми возвратами. Каждое решение, как только оно получено, немедленно добавляется к базе данных, чтобы не потерять его после нахождения следующего решения. После того, как будут получены и сохранены все решения, их нужно собрать в список, а затем удалить из базы данных при помощи retract. Весь процесс можно представлять себе как построение очереди из порождаемых решений. Каждое вновь порождаемое решение добавляется в конец этой очереди при помощи assert. Когда все решения собраны, очередь расформировывается. Заметим также, что конец очереди надо пометить, например, атомом 'дно' (который, конечно, должен отличаться от любого ожидаемого решения). Реализация findall в соответствии с описанным методом показана на рис. 7.4.

findall( X, Цель, ХСпис) :-

    саll( Цель),                                 % Найти решение

    assert( очередь( X) ),                % Добавить егo

    fail;                 % Попытаться найти еще решения

    assertz( очередь( дно) ),

                         % Пометить конец решений

    собрать( ХСпис).                     % Собрать решения в список

собрать( L) :-

     retract( очередь(Х) ),  !,

                         % Удалить следующее решение

    ( Х == дно,  !,  L = [ ];

                         % Конец решений?

    L = [X | Остальные], собрать( Остальные) ).

                         % Иначе собрать остальные

Рис. 7. 4.  Реализация отношения findall.

Упражнения

7. 8.    Используя bagof, определите отношение

        множподмножеств( Мн, Подмн)

для вычисления множества всех подмножеств данного множества (все множества представлены списками).

7. 9.    Используя bagof, определите отношение

        копия( Терм, Копия)

чтобы Копия представляла собой Терм, в котором все переменные переименованы.

Резюме

В любой реализации Пролога обычно предусматривается набор встроенных процедур для выполнения различных полезных операций, несуществующих в чистом Прологе. В данной главе мы рассмотрели подобное множество предикатов, имеющееся во многих реализациях.

Тип терма можно установить при помощи следующих предикатов:

        var( X)                     Х - (неконкретизированная) переменная

Вы читаете Prolog
Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату