5

I have a manually made DCG rule to select idiomatic phrases over single words. The DCG rule reads as follows:

seq(cons(X,Y), I, O) :- noun(X, I, H), seq(Y, H, O), \+ noun(_, I, O).
seq(X) --> noun(X).

The first clause is manually made, since (:-)/2 is used instead of (-->)/2. Can I replace this manually made clause by some clause that uses standard DCG?

Best Regards

P.S.: Here is some test data:

noun(n1) --> ['trojan'].
noun(n2) --> ['horse'].
noun(n3) --> ['trojan', 'horse'].
noun(n4) --> ['war'].

And here are some test cases, the important test case is the first test case, since it does only deliver n3 and not cons(n1,n2). The behaviour of the first test case is what is especially desired:

?- phrase(seq(X),['trojan','horse']).
X = n3 ;
No
?- phrase(seq(X),['war','horse']).
X = cons(n4,n2) ;
No
?- phrase(seq(X),['trojan','war']).
X = cons(n1,n4) ;
No
4

1 回答 1

5

(为避免与其他非终端冲突,我将您重命名seq//1nounseq//1

我可以用一些使用标准 DC​​G 的子句替换这个手工制作的子句吗?

不,因为它不坚定,它是 STO(详情如下)。

预期意义

但是,让我从您的程序的预期含义开始。您说您要选择惯用短语而不是单个单词。你的程序真的这样做了吗?或者,换一种说法,你的定义真的很独特吗?我现在可以构建一个反例,但让 Prolog 来思考:

名词 --> [] | 名词(_),名词。

?- 长度(Ph,N),短语(名词,Ph),
   差异(X,Y),短语(名词序列(X),Ph​​),短语(名词序列(Y),Ph)。
Ph = [特洛伊木马,木马,特洛伊木马],
N = 3,
X = cons(n1, cons(n2, n1)),
Y = 缺点(n3,n1);
... ;
Ph = [特洛伊木马,战争],
N = 3,
X = 缺点(n3,n4),
Y = cons(n1, cons(n2, n4)) ...

所以你的定义是模棱两可的。您本质上想要的(可能)是某种重写系统。但这些很少以明确的方式定义。什么,如果两个词像附加词一样重叠noun(n5) --> [horse, war].等等。


一致性

预先声明:目前,DCG 文档仍在开发中——非常欢迎评论!你可以在这个地方找到所有的材料。所以严格来说,目前还没有 DCG 的一致性概念。

坚定不移

一个符合标准的定义必须保持的核心属性是坚定不移的属性。因此,在查看您的定义之前,我将比较两个目标phrase/3(在默认模式下运行 SWI)。

?- Ph = [],短语(名词序列(cons(n4,n4)),Ph0,Ph)。
PH = [],
Ph0 = [战争,战争];
错误的。

?- 短语(名词序列(cons(n4,n4)),Ph0,Ph),Ph = []。
的。

?- 短语(名词序列(cons(n4,n4)),Ph0,Ph)。
的。

在最后移动目标Ph = [],删除唯一的解决方案。因此,您的定义并不坚定。这是由于您处理的方式(\+)/1:变量O不能出现在(\+)/1. 但另一方面,如果它没有出现在(\+)/1你只能检查句子的开头。而不是整个句子。

以发生检查财产为准

但情况更糟:

?- set_prolog_flag(occurs_check,error)。
真的。

?- 短语(名词序列(cons(n4,n4)),Ph0,Ph)。
错误:名词/3:无法将 _G968 与 [war|_G968] 统一:将创建无限树

所以你的程序依赖于 STO-unifications (subject-to-occurs-check unifications),其结果在

ISO/IEC 13211-1子条款 7.3.3 接受发生检查 (STO) 和不接受发生检查 (NSTO)

这是因为您打算定义两个非终端的交集。考虑以下表达方式:

:- op(950, xfx, //\\)。∩ - 2229;INTERSECTION 的 % ASCII 近似值

(NT1 //\\ NT2) -->
     调用(Xs0^Xs^(短语(NT1,Xs0,Xs),短语(NT2,Xs0,Xs)))。

% 以下是在 中预定义的library(lambda)

^(V0,目标,V0,V):-
      呼叫(目标,V)。

^(V, 目标, V) :-
     呼叫(目标)。

已经有了这个定义,我们可以进入 STO 情况:

?- 短语(([a]//\\[a,b]), Ph0,Ph)。
错误:=/2:无法将 _G3449 与 [b|_G3449] 统一:将创建无限树

事实上,当使用有理树时,我们得到:

?- set_prolog_flag(occurs_check,false)。
真的。

?- 短语(([a]//\\[a,b]), Ph0,Ph)。
Ph0 = [a|_S1], % 其中
    _S1 = [b|_S1],
Ph = [b|_S1]。

所以有一个无限的列表,对于自然语言句子来说肯定没有多大意义(除了无限资源和能力的人......)。

于 2012-12-09T15:19:43.030 回答