Определение операторов, включая вертикальные полосы (|) в 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 распознает их как один целый атом.