在Prolog中,[H|T]
是以H
开头的列表,其余元素位于列表T
中(内部用'.'(H, '.'(…))
表示)。
是否可以以类似的方式定义新语法?例如,是否可以定义[T~H]
是以H
结尾的列表以及其余元素在列表T
中的位置,然后将其自由地用作{{1}在谓词的头部和主体中?是否也可以定义例如[H|T]
与列表不同的结构?
答案 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。