Анонимные предикаты

Материал из wikiru.visual-prolog.com

Анонимные предикаты - новая возможность компилятора, которая реализована начиная с версии 7.2

Вступление

Пример использования:

interface авто
properties
    цена : unsigned(o).
end interface авто
 
class выборАвтомобиля
predicates
    неДорогие : () -> авто* Результат.
...
implement выборАвтомобиля
clauses
    неДорогие() = list::filter({(Авто) :- Авто:цена <= 10000, !}, списокАвтомобилей).
...


Казалось бы ничего нового, ведь то же самое можно записать при помощи дополнительного предиката. Например так

predicates
    фильтрДляНедорогих : (авто Авто).
clauses
    фильтрДляНедорогих(Авто) :- Авто:цена <= 10000, !.
clauses
    неДорогие() = list::filter(фильтрДляНедорогих, списокАвтомобилей).

Но сегодня для нас сумма 10000 является пределом мечтаний, а завтра 12000, как быть? Есть два решения, или менять константу, или добавить факт-переменную. Анонимный предикат позволит сделать это изящней.

predicates
    неДорогие2 : (unsigned НашиВозможности).
clauses
    неДорогие2(НашиВозможности) = list::filter({(Авто) :- Авто:цена <= НашиВозможности, !}, списокАвтомобилей).

Если внимательно присмотреться, то тут мы наблюдаем картину, ранее недоступную невооружённым глазом. Переменная НашиВозможности из предиката 'неДорогие2' перекочевала во внутрь другого предиката - фильтра! Вот это уже нельзя сделать использую дополнительный предикат, как раньше.

Погружение

Давайте еще усложним наш пример, не сильно отрываясь от реальности. Представим, что у нас есть следующий интерфейс:

interface покупатель
properties
    зарплата : unsigned(o).
    фильтрМашин : () -> list::filter.
end interface покупатель

Попробуем написать реализацию

implement покупатель
facts
    зарплата : unsigned.
clauses
    фильтрМашин() = 
 
{(Авто) :- Авто:цена <= НашиВозможности, !}, списокАвтомобилей)
implement покупатель

Детали реализации

Где использовать

Это неоконченная статья