DCG用于惯用语短语偏好

时间:2012-12-08 21:53:11

标签: prolog dcg iso-prolog

我有一个手动制作的DCG规则来选择惯用语 单词。 DCG规则如下:

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

第一个子句是手动制作的,因为使用的是(:-)/2 (-->)/2。我可以替换这个手工制作的子句吗? 一些使用标准DCG的条款?

最好的问候

P.S。:以下是一些测试数据:

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

以下是一些测试用例,重要的测试用例是第一个测试用例,因为它只是 提供n3而不是缺点(n1,n2)。第一个测试用例的行为是特别需要的:

?- 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

1 个答案:

答案 0 :(得分:6)

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

  

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

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

预期含义

但是,让我从你的计划的意图开始。你说你想选择一个单词的习惯用语。你的程序真的这样做吗?或者,换句话说,你的定义真的很独特吗?我现在可以构建一个反例,但让Prolog做出这样的想法:

nouns --> [] | noun(_), nouns.

?- length(Ph, N), phrase(nouns,Ph),
   dif(X,Y), phrase(nounseq(X),Ph), phrase(nounseq(Y),Ph).
Ph = [trojan, horse, trojan],
N = 3,
X = cons(n1, cons(n2, n1)),
Y = cons(n3, n1) ;
... ;
Ph = [trojan, horse, war],
N = 3,
X = cons(n3, n4),
Y = cons(n1, cons(n2, n4)) ...

所以你的定义含糊不清。你真正想要的(可能)是某种重写系统。但这些很少以确定的方式定义。如果两个单词像额外的noun(n5) --> [horse, war].等重叠,那该怎么办?


一致性

预先免责声明:目前,DCG文件仍在开发中 - 非常欢迎评论!找到所有材料in this place。严格地说,目前在DCG没有一致性概念。

的坚守

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

?- Ph = [], phrase(nounseq(cons(n4,n4)),Ph0,Ph).
Ph = [],
Ph0 = [war, war] ;
false.

?- phrase(nounseq(cons(n4,n4)),Ph0,Ph), Ph = [].
false.

?- phrase(nounseq(cons(n4,n4)),Ph0,Ph).
false.

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

受发生 - 检查属性

但情况更糟:

?- set_prolog_flag(occurs_check,error).
true.

?- phrase(nounseq(cons(n4,n4)),Ph0,Ph).
ERROR: noun/3: Cannot unify _G968 with [war|_G968]: would create an infinite tree

所以你的程序依赖于STO-unifications(subject-to-occurred-check unifications),其结果明确未定义

  

ISO/IEC 13211-1子条款7.3.3受制于支票(STO)且不受支票发生(NSTO)

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

:- op(  950,  xfx, //\\).  % ASCII approximation for ∩ - 2229;INTERSECTION

(NT1 //\\ NT2) -->
     call(Xs0^Xs^(phrase(NT1,Xs0,Xs),phrase(NT2,Xs0,Xs))).

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

^(V0, Goal, V0, V) :-
      call(Goal,V).

^(V, Goal, V) :-
     call(Goal).

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

?- phrase(([a]//\\[a,b]), Ph0,Ph).
ERROR: =/2: Cannot unify _G3449 with [b|_G3449]: would create an infinite tree

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

?- set_prolog_flag(occurs_check,false).
true.

?- phrase(([a]//\\[a,b]), Ph0,Ph).
Ph0 = [a|_S1], % where
    _S1 = [b|_S1],
Ph = [b|_S1].

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