Реализация определяемых пользователем арифметических функций

Как я могу добавить функцию (например, hammingweight) и использовать ее в выражениях, встречающихся в правой части, это некоторая (is)/2 цель?

Может ли здесь помочь что-то вроде target_expansion или term_expansion?

Я признаю, что это небольшая функция, но она может повысить читабельность некоторых моих программ на Прологе.

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


person repeat    schedule 04.03.2015    source источник


Ответы (3)


В ISO Prolog нет такого положения ни для расширения (is)/2, ни для использования расширения цели. И, глядя на различные особенности реализации, предлагаемые некоторыми реализациями для этой цели, не существует общепринятого способа сделать это. Так что реализация собственного (my_is)/2 кажется лучшим способом.

Также обратите внимание, что это повлияет не только на (is)/2, но и на все другие встроенные функции, которые используют вычисляемые функторы. В частности, все встроенные функции арифметического сравнения (8.7 Арифметическое сравнение) (см. этот обзор) будет затронут.

person false    schedule 04.03.2015

Мой простой (~20 LOC) синтаксический сахар, lifter, это основано на target_expansion.

С подъемником пункт

longer(A,B) :-
    length(A,º) > length(B,º).

расширяется до

longer(A, B) :-
    length(A, C),
    length(B, D),
    C > D.
person CapelliC    schedule 04.03.2015
comment
Решение аккуратное, но, учитывая, что вопрос помечен как общий для Пролога и iso-prolog, неплохо отметить в ответе, что представленное решение нацелено на конкретную реализацию Пролога (по-видимому, в данном случае SWI-Prolog). В противном случае пользователь, пробующий решение в другой реализации Пролога, может прийти к ложному восприятию того, что эта реализация сломана, а не просто предоставляет другой набор функций. - person Paulo Moura; 04.03.2015
comment
@PauloMoura: ты прав. Я публиковал свое решение только для того, чтобы предоставить рабочий образец target_expansion. - person CapelliC; 04.03.2015
comment
Который постер, вероятно, может использовать или адаптировать для своих целей :-) - person Paulo Moura; 04.03.2015
comment
наверняка SICStus будет поддерживать target_expansion, не так ли? - person CapelliC; 05.03.2015

Вы можете использовать переносимый механизм расширения терминов Logtalk, который работает с двенадцатью поддерживаемыми компиляторами Prolog (*). Компиляция Logtalk и предикаты загрузки и загрузки принимают файлы Prolog и выводят соответствующие расширенные файлы Prolog. Например, предположив, что файл, который вы хотите расширить, называется source.pl и что ваши определения предикатов term_expansion/2 и goal_expansion/2 находятся в файле с именем expansions.pl, вы можете сделать что-то вроде:

% first, load the expansion hooks:
| ?- [expansions].
...

% second, expand a file using those hooks:
| ?- logtalk_compile(source, [hook(user)]).
...

Вы получите расширенный файл, который будет (по умолчанию) называться source_pl.pl (в каталоге, который будет зависеть от значения флага scratch_directory Logtalk). Если расширения содержатся в модуле Prolog, используйте над именем модуля вместо user. Если файл source.pl содержит модуль вместо простого кода Пролога, вам нужно будет определить некоторые предложения для предиката term_expansion/2, чтобы Logtalk не компилировал модуль как объект. Но в более простом случае, когда вы не используете модули, двух приведенных выше запросов должно быть достаточно.

Одна из полезных функций механизма расширения терминов Logtalk заключается в том, что вы можете пометить термин или цель, которые не следует расширять или расширять дальше, обернув их управляющей конструкцией {}/1.

(*) Обратите внимание, что механизм расширения терминов не является стандартным, предоставляется не всеми реализациями Пролога и имеет значительные различия между реализациями.

person Paulo Moura    schedule 04.03.2015