Определение операторов, включая вертикальные полосы (|) в SWI-prolog

Я пытаюсь кодировать основные логические выводы в Prolog, и я хочу определить некоторые пользовательские операторы для оптимизации нотации. Было бы удобно, если бы я мог напечатать |- for ⊢. Поэтому я попытался

:- op(1150, xfy, [ '|-' ]).
gamma |- a.
Gamma |- or(A,_) :- Gamma |- A.
Gamma |- or(_,A) :- Gamma |- A.

но когда я пытаюсь запрос gamma |- or(a,X), Я получаю сообщение об ошибке

ERROR: '<meta-call>'/1: Undefined procedure: gamma/0

вместо true Я ожидал.

проблема заключается в том, что определенный оператор включает символ вертикальной полосы. Если я изменю базу знаний к

:- op(1150, xfy, [ imp ]).
gamma imp a.
Gamma imp or(A,_) :- Gamma imp A.
Gamma imp or(_,A) :- Gamma imp A.

тогда Prolog не имеет проблем с ответом на запрос gamma imp or(a,X). Является ли вертикальная полоса зарезервированным символом, который мне не разрешено использовать в определениях? Или есть какой-то способ обойти это?

4 ответов


вы не можете сделать это. Ни в прологе ISO, ни в SWI. Хотя вертикальная полоса служит оператором-при условии наличия соответствующего объявления оператора, она не может использоваться без кавычек как часть оператора с длиной двух или более символов. Лучшее, что вы можете получить в своей ситуации, это объявить оператора |- и используйте его в кавычках. В обоих случаях ниже, цитаты строго необходимы.

:- op(1200, xfx, '|-').  

a '|-' b.

выглядит не слишком привлекательно. Один, как единый персонаж, бар служит оператором infix.

?- ( a | b ) = '|'(a, b).
true.

?- current_op(Pri,Fix,'|').
Pri = 1105,
Fix = xfy.

есть еще одно использование | в качестве разделителя head-tail в списках. Из-за ограничений на приоритет, который может принимать infix-бар, нет никакой двусмысленности между [A|As] и выше использовать.

отметим, что [a|-]. допустимый текст пролога. Даже gamma |- a. действителен в SWI и даже действительный текст Пролога в ISO, при условии, что есть объявление оператора!

?- write_canonical((gamma|-a)).
'|'(gamma,-(a))

SWI-Prolog поддерживает Unicode

может быть, только может быть, вы можете использовать сам символ? Используя u22A2, я могу ввести следующий исходный файл:

:-op(1150, xfy, ⊢).
gamma ⊢ a.
Gamma ⊢ or(A,_) :- Gamma ⊢ A.
Gamma ⊢ or(_,A) :- Gamma ⊢ A.

и я могу, без каких-либо проблем, загрузить его и запросить его:

?- gamma ⊢ or(a,X).
true ;
X = a ;
X = or(a, _2484) . % and so on

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


символ трубы ' / ' играет особую роль как "синтаксический сахар" для представления списков. Чтобы использовать [a / [b, c]] вместо .(ля. ,(си. ,(с.)][ , Анализатор пролога обрабатывает его по-разному, прежде чем он разрешает другие части выражения.

вы все еще можете определить предикат '|-' а затем объявите его как оператор, но вам придется использовать его в кавычках, таких как a '|-' b который своего рода побеждает цель.


в прологе ISO core вертикальная полоса относится к категории сольных персонажей. В частности раздел 6.5.3 ИСО основной стандарт определяет сольных персонажей. Среди списка сольные персонажи мы находим так называемый head tail separator char:

solo char (* 6.5.3 *)
    = cut char
    ...
    | head tail separator char
    ... ;

cut char = "!" ;
...
head tail separator char = "|"
...

сканер пролога обрабатывает одиночные символы таким образом, что они считаются самостоятельными токенами.

означает, что они не вступают с другими персонажами. Так что если кто-то пишет |-, это то же самое, как если бы два письмена разделились и кто - то пишет | - в пролог текст.

в результате | не может быть объединен с другими символами а затем определяется как оператор. Система Prolog будет просто не сможете увидеть его как комбинированный символ, например |-.

другое дело так называемые атомах, можно конечно используйте '/ -', i.e заключите символы в кавычки, а Затем сканер Prolog распознает их как один целый атом.