Prolog 中的自定义数据结构语法

Custom data structure syntax in Prolog

在 Prolog 中,[H|T] 是以 H 开头的列表,其余元素在列表 T 中(内部用 '.'(H, '.'(…)) 表示)。

是否可以用类似的方式定义新语法?例如,是否可以定义[T~H]是以H结尾的列表,其余元素在列表T中的列表,然后像[=10]一样自由使用=] 在谓词的头部和主体中?是否也可以定义例如<H|T> 与列表结构不同?

可以使用 iso 谓词扩展或重新定义 Prolog 的语法

 :- op(Precedence, Type, Name).

其中 Precedence 是一个介于 0 和 1200 之间的数字,类型描述操作符是使用后缀、前缀还是中缀:

infix: xfx, xfy, yfx
prefix: fx, fy
suffix: xf, yf

最后name是运营商的名字。

运算符定义不指定运算符的含义,而仅描述如何在句法上使用它。它只是扩展 Prolog 语法的定义。它不提供有关谓词何时成功的任何信息。因此,您还需要描述谓词何时成功。要回答您的问题并举一个您可以定义的示例:

:- op( 42, xfy, [ ~ ]).

在其中声明一个中缀运算符 [ ~ ]。这并不意味着它是一个列表的表示(还)。您可以定义子句:

[T ~ H]:-is_list([H|T]).

将 [T~H] 与以 H 结尾的列表匹配,其余元素在列表 T 中。

Note also that it is not very safe to define predefined operators like [ ] or ~ because you overwrite their existing functionality. For example if you want to consult a file like [file]. this will return false because you redefined operators.

可以从字面上解释你的问题。一种类似列表的数据结构,可以在没有任何辅助谓词的情况下表达对尾部的访问。好吧,这些是已经在第一个 Prolog 系统中使用的负列表——有时被称为 Prolog 0 并且是用 Algol-W 编写的。来自 the original report, p.32 音译成 ISO Prolog 的示例:

t(X-a-l, X-a-u-x). 

?- t(nil-m-e-t-a-l, Pluriel).
Pluriel = nil-m-e-t-a-u-x.

所以基本上你采用任何左结合运算符。

但是,我怀疑这不是您想要的。您可能想要列表的扩展。

已多次尝试这样做,最近的一次是 Prolog III/Prolog IV. However, quite similar to constraints, you will have to face how to define equality over these operators. In other words, you need to go beyond syntactic unification into E-unification。这个问题一开始听起来很简单,但它却复杂得可怕。 Prolog IV 中的一个简单示例:

>> L = [a] o M, L = M o [z].
M ~ list,
L ~ list.

显然这是不一致的。也就是说,系统应该响应 false. There is simply no such M,但 Prolog IV 无法推断出这一点。你至少要解决这样的问题,或者以某种方式与他们相处。

如果您真的想深入研究这个问题,请考虑从 J. Makanin 的开创性工作开始的研究:

The Problem of Solvability of Equations in a Free Semi-Group, Akad. Nauk SSSR, vol.233, no.2, 1977.

也就是说,可能有更简单的方法来获得您想要的东西。也许不需要完全关联的列表运算符。

尽管如此,与我们在 Prolog 中拥有的东西(即 DCG)相比,不要期望这种扩展具有太多的表现力。特别是,一般的左递归仍然是文法终止的问题。