查看短语/ 3翻译的标准方法是什么?

时间:2013-01-03 14:19:04

标签: prolog dcg gnu-prolog iso-prolog

我正在尝试深入研究GNU Prolog的行为:

test(X,I,O) :- phrase(X,I,O).
?- test(("a",!,"b"),"ab","").

是否有标准的方法来查看/ 3翻译的短语?

根据ISO DCG提案(*),有要求 我们将有一个expand_term / 2。现在我可以用它来检查:

?- expand_term((foo --> "a", !, "b"),X).
X = (foo([97|A],B):-!,A=[98|B])

这是否告诉我在test / 3中如何使用短语/ 3?

(*) ISO / IEC DTR 13211-3:2006
明确的条款语法规则
Klaus Daessler
2012年11月20日
http://www.complang.tuwien.ac.at/ulrich/iso-prolog/dcgs/dcgsdin121120.pdf

2 个答案:

答案 0 :(得分:2)

  

是否有标准的方式来查看短语/ 3翻译的内容?

没有。 phrase/3的含义已定义,但后面的实际实现无法访问。有几种不同的方法,如何定义phrase/3。它可以像in YAP一样简单:

phrase(P, S0, S) :-
        call(P, S0, S).

或者它可以使用expand_term/2(或类似的东西)。那就是:

phrase(P, S0, S) :-
   expand_term(( pseudont --> P ), ( pseudont(CS0, CS) :- Goal) )),
   S0 = CS0,
   S = CS,
   Goal.

调用Goal后可以执行最终统一:

phrase(P, S0, S) :-
   expand_term(( pseudont --> P ), ( pseudont(CS0, CS) :- Goal) )),
   S0 = CS0,
   Goal,
   S = CS.

通过引入(依赖于实现的)约定,扩展谓词总是在最后一个参数中使用未实例化且未混淆的变量调用,这将允许在存在semicontext时进行尾递归。

完全取决于实施者。

  

这是否告诉我在test / 3中如何使用短语/ 3?

不,没有办法说明。

但是,你为什么这么问?或者,改写:

  

phrase/3的不同但符合要求的实施会产生什么影响?

资源消耗

这应该是显而易见的。考虑?- phrase([],Xs).,它在YAP中不会在堆上创建任何术语,但是对于上面的幼稚expand_term扩展也是如此。但是,资源消耗超出了现行标准的范围。

变量排序

在YAP中考虑规则..., phrase([], Xs, Xs), ...的主体:Xs仍然是局部变量,而基于expand_term的短语使其成为全局变量。在许多实现中,这将影响变量的相对顺序。现在,该标准在7.2.1中明确说明:

如果X和Y是不相同的变量,则为 X term_precedes Y应依赖于实现 除了在创建排序列表期间(7.1.6.5,
8.10.3.1 j)排序应保持不变。

所以这也不是问题,但这仍然很烦人。

NSTO属性

Prolog标准(即第1部分ISO / IEC 13211-1)仅定义执行,如果它是NSTO。也就是说,如果在执行期间发生的所有统一都是NSTO - 不受发生检查(见7.3.3)。

现在,考虑一下你的情况:phrase(("a",!,"b"), Xs, Ys)。乍一看,这相当于phrase("ab", Xs, Ys)。但现在考虑假设set_prolog_flag(double_quotes,chars)

?- Xs = [c|_], Xs = Ys, phrase(("a",!,"b"), Xs, Ys).

毫无疑问,此查询应该失败。但这是NSTO吗?天真地,我们可以假设这可以被替换为:

?- Xs = [c|_], Xs = Ys, Xs = [a,b|Ys].

这无异于:

?- Xs = [c|_], Xs = [a,b|Xs].

显然,仅Xs = [a,b|Xs]是STO(可能发生检查)。但是两者都是STO!要理解这一点,请考虑7.3.2中的Herbrand算法。实质上,它以“任何顺序”非确定地重写方程。这是一个这样的推导:

          Xs = [c|Zs], Xs = [a,b|Xs].
(7.3.2 f) Xs = [c|Zs], [c|Zs] = [a,b,c|Zs].
(7.3.2 d) Xs = [c|Zs], c = a, Zs = [b,c|Zs].
(7.3.2 g) failure (not unifiable, positive occurs-check)

当然,这种推导是不寻常的。通常,在c = a出现时会立即失败,但算法在这方面是不确定的。只有当所有可能的推导都不会导致7.3.2 g时,一组方程才是NSTO。引用7.3.3:

一组方程(或两个术语)“不受制于 发生 - 检查“(NSTO)iff无法继续进行 通过Herbrand算法的步骤使得 7.3.2克发生。

冻结/ 2和/ 2

这些结构也可能受到影响。虽然目前尚未涵盖现有标准文件,但了解潜在影响仍具有相关性。考虑:

?- freeze(L, (X=1;X=2)), phrase(("a",!,"b"),L).
L = [a, b],
X = 1.

B,SICStus,SWI,YAP都会产生这一答案。所以削减很重要。


无论如何,感谢您的提问 - 我在回答您的问题时才了解NSTO问题!这显然对DCG翻译的制定方式有一些影响。

答案 1 :(得分:1)

由于ISO DCG没有定义一种方法来确定哪个短语/ 3用作执行术语,唯一的解决方法是查阅源代码。它在这里找到:

http://sourceforge.net/projects/gprolog/

短语/ 3谓词在名为expand.pl的文件中定义。它的定义使用'$ dcg_trans_body'/ 4。我们可以检查一下:

GNU Prolog 1.4.2
By Daniel Diaz
Copyright (C) 1999-2012 Daniel Diaz
| ?- '$dcg_trans_body'(("a",!,"b"), In, Out1, Body).

Body = (!,A=[98|Out1])
In = [97|A]

所以第一个终端确实合并到了In参数中,类似于 foo规则。由于这是在调用短语/ 3时完成的,因此它应该不是问题。