Prolog 习语短语偏好的DCG
我有一个手动生成的DCG规则来选择惯用短语 超过一个单词。DCG规则内容如下:Prolog 习语短语偏好的DCG,prolog,dcg,iso-prolog,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的一些条款 致意 注意:以下是一些测试数据: noun(n1) --> ['trojan']. noun(n2)
seq(cons(X,Y), I, O) :- noun(X, I, H), seq(Y, H, O), \+ noun(_, I, O).
seq(X) --> noun(X).
第一个子句是手动生成的,因为使用了(:-)/2
属于(->)/2
。我可以用替换此手动生成的子句吗
使用标准DCG的一些条款
致意
注意:以下是一些测试数据:
noun(n1) --> ['trojan'].
noun(n2) --> ['horse'].
noun(n3) --> ['trojan', 'horse'].
noun(n4) --> ['war'].
这里有一些测试用例,重要的测试用例是第一个测试用例,因为它只
交付n3而非cons(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
(为了避免与其他非终端发生冲突,我将您的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)) ...
最后移动目标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情况:
?- phrase(([a]//\\[a,b]), Ph0,Ph).
ERROR: =/2: Cannot unify _G3449 with [b|_G3449]: would create an infinite tree
-短语(([a]/\\[a,b]),Ph0,Ph)。
错误:=/2:无法将_G3449与[b | _G3449]统一:将创建一个无限树
事实上,当使用rational树时,我们得到:
?- set_prolog_flag(occurs_check,false).
true.
?- phrase(([a]//\\[a,b]), Ph0,Ph).
Ph0 = [a|_S1], % where
_S1 = [b|_S1],
Ph = [b|_S1].
?-设置prolog标志(发生检查,错误)。
对。
-短语(([a]/\\[a,b]),Ph0,Ph)。
Ph0=[a | u S1],%其中
_S1=[b | U S1],
Ph=[b | u S1]。
因此,有一个无限的列表对自然语言句子(除了拥有无限资源和能力的人…)来说肯定没有太大意义。@CookieMoster:如果你添加足够多的假设,你可能会坚定不移。但在一般情况下,这是极不可能的,因为差异不能导致终止。想想
短语(名词,Xs,Xs)
,它只有一个答案,但并不终止“预期意义问题”在任何情况下都与具体实现无关。
^(V0, Goal, V0, V) :-
call(Goal,V).
^(V, Goal, V) :-
call(Goal).
?- 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].