Prolog 习语短语偏好的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)

我有一个手动生成的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) --> ['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].