Проблема с определением инфиксного бинарного оператора в прологе

Я просто новичок в прологе. Я хочу определить инфиксный бинарный оператор «rA», который дает мне площадь прямоугольника, когда я задаю ширину и ширину прямоугольника. Это код, который у меня есть:

:-op(300, xfy, rA).

rA(X,Y,R) :- R is X*Y.

Код отлично работает, когда я делаю это:

1 ?- rA(3,4,A).
A = 12. 

Чего я не могу понять, так это определить его как инфиксный бинарный оператор. Я получаю эту ошибку:

2 ?- A is 3 rA 4.
ERROR: evaluable `3 rA 4' does not exist 

Спасибо


person BuddyW    schedule 18.11.2013    source источник


Ответы (2)


У вас есть хороший ответ от Пауло, в любом случае вот пример деталей, необходимых для указания SWI-Prolog вашей функции:

22 ?- [user].
|: :- arithmetic_function(rA/2).
|: rA(X,Y,Z) :- Z is X*Y.
% user://1 compiled 0.07 sec, 3 clauses
true.

23 ?- F is rA(3,6).
F = 18.

24 ?- [user].
|: :-op(300,xfx,rA).
% user://2 compiled 0.02 sec, 1 clauses
true.

25 ?- F is 3 rA 6.
F = 18.
person CapelliC    schedule 18.11.2013

Вы не можете сделать это в стандартном Прологе. Тем не менее, SWI-Prolog использовался для поддержки пользовательских определений арифметических функций, но я считаю, что эта функция устарела в последних выпусках. Проверьте документацию. Возможная альтернатива состоит в том, чтобы воспользоваться механизмом расширения терминов, который определяют несколько систем Prolog (включая SWI-Prolog) и is/2 цели расширения целей для работы с вызовами, использующими определяемые пользователем арифметические функции. Что-то вроде:

goal_expansion(X is Expression, X is ExpandedExpression) :-
    % traverse and transform Expression

Но помните, что goal_expansion/2 вызывается неоднократно, пока не будет достигнута фиксированная точка. Итак, помните о бесконечных циклах, возникающих при попытке расширить уже развернутое арифметическое выражение. Один из способов ее решения — кэшировать результаты расширения с помощью динамического предиката, который проверяется при вызове goal_expansion/2. Динамический предикат кэширования можно отменить, например. когда конец файла, который вы обрабатываете:

term_expansion(end_of_file, _) :-
    abolish(...), % the argument will be the predicate indicator of the caching predicate
    fail.

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

person Paulo Moura    schedule 18.11.2013
comment
Работает не везде. Например, кажется, что gprolog 1.4.4 не имеет target_expansion/2 и expand_goal/2. - person Mostowski Collapse; 12.06.2014
comment
Механизм расширения терминов не является ни универсальным, ни стандартным (поэтому я написал несколько систем Prolog, а не все или большинство). системы. - person Paulo Moura; 12.06.2014
comment
Да, конечно. В случае, если ваше определенное выражение нуждается в вызове предиката, X is E будет преобразовано в G, X is E'. Только что перешел сегодня к старому примеру, где SWI-Prolog позволял определять оцениваемые функции, см. здесь: курсы.ece.ubc.ca/571f/randoml.html . Например, боксу Мюллеру понадобится гол. - person Mostowski Collapse; 12.06.2014