在SWI-prolog中定义包括竖线(|)的运算符

时间:2016-10-28 20:12:52

标签: prolog operators swi-prolog

我正在尝试编码Prolog中的基本逻辑推理,我想定义一些自定义运算符来简化表示法。如果我可以输入|-作为would,那将会很方便。所以我试过

:- 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 个答案:

答案 0 :(得分:7)

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

我意识到这不是你所要求的,我也意识到只有你能找到一种在文本编辑器和顶层输入这些字符的简单方法,这才有用。

答案 1 :(得分:3)

你不能这样做。无论是在ISO Prolog还是在SWI中。虽然竖条用作运算符 - 如果存在相应的运算符声明,则不能将其作为具有两个或更多字符长度的运算符的一部分使用。您可以获得的最佳状态是声明一个运算符|-并以引用的形式使用它。在下面的两种情况下,都严格要求报价。

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

a '|-' b.

看起来不太吸引人。单独作为单个字符,条形作为中缀操作符。

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

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

|在列表中还有另一种用作头尾分隔符的用法。由于中缀栏可以采取的优先级限制,[A|As]和以上使用之间没有歧义。

请注意[a|-].是有效的Prolog文本。即使gamma |- a.在SWI中有效,甚至在ISO中也是有效的Prolog文本,只要有操作员声明即可!

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

答案 2 :(得分:1)

管道'|'符号具有表示列表的“语法糖”的特殊作用。 为了使用[a | [b,c]]而不是。(a,。(b,。(c,[])。prolog解析器在解析表达式的其他部分之前对它进行不同的处理。

您仍然可以定义谓词'|-',然后将其声明为运算符,但您必须在a '|-' b之类的引号中使用它,这有点违背了目的。

答案 3 :(得分:0)

在ISO核心Prolog中,垂直条属于该类别 独奏人物特别是ISO的6.5.3节 核心标准定义了独奏角色。在名单中 我们找到所谓的头尾分隔符char:

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

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

Prolog的扫描仪会对待这样的独奏人物 他们被认为是自我代币。

意味着他们不与其他角色联系。因此,如果 有人写| - ,就像两个字符一样 被分开,有人写道 - 在Prolog文本中。

结果是|不能与其他角色合并 然后定义为运营商。 Prolog系统将是公正的 无法将其视为组合符号,例如| - 。

另一个问题是所谓的引用原子,当然可以 使用&#39; | - &#39;,即将字符括在引号中,然后将其括起来 然后Prolog扫描仪将它们识别为一个完整的原子。