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

时间:2016-10-26 09:30:50

标签: data-structures prolog syntactic-sugar unification

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

是否可以以类似的方式定义新语法?例如,是否可以定义[T~H]是以H结尾的列表以及其余元素在列表T中的位置,然后将其自由地用作{{1}在谓词的头部和主体中?是否也可以定义例如[H|T]与列表不同的结构?

2 个答案:

答案 0 :(得分:3)

人们可以从字面上解释你的问题。类似于列表的数据结构,可以在没有任何辅助谓词的情况下表示访问尾部。好吧,这些是已经在第一个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。但是,与约束非常相似,您将不得不面对如何在这些运算符上定义相等性。换句话说,你需要超越句法统一到E-unification。这个问题在开始时听起来很容易,但它很复杂。 Prolog IV中的一个简单例子:

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

显然这是不一致的。也就是说,系统应该回复false.根本没有这样的M,但是Prolog IV无法推断出这一点。你必须至少解决这些问题或以某种方式与它们相处。

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

  

自由半群中方程的可解性问题,Akad。 Nauk SSSR,vol.233,no.2,1977。

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

然而,与我们在Prolog中所拥有的,即DCG相比,不要期望这种扩展具有太多表现力。特别是,一般的左递归仍然是语法终止的问题。

答案 1 :(得分:1)

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

 :- op(Precedence, Type, Name).

如果Precedence是0到1200之间的数字,则类型描述操作符是否使用后缀,前缀或中缀:

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

最后名称是运营商的名称。

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

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

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

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

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

  

另请注意,定义预定义运算符不是很安全   例如[ ]~,因为您覆盖了他们现有的功能。   例如,如果您想查询[file]这样的文件。这将   因为你重新定义了运算符而返回false。