NLP PROLOG语法

NLP PROLOG语法,prolog,nlp,grammar,Prolog,Nlp,Grammar,我们有正式的语言 G 1 = { V , T , S , P }, where V = { S , E } T = { x , y , z } P = { S->E , E->xE , E->yE , E->z } 我们能接受七个句子{xz,xy,xyz,xyz,z,xxyz,xyz}以及格式良好的公式吗?用Prolog验证这一点 这是我的密码: s --> e. e --> [x], e. e --> [y], e. e --> [z]. 它

我们有正式的语言

G 1 = { V , T , S , P }, where
V = { S , E }
T = { x , y , z }
P = { S->E , E->xE , E->yE , E->z }
我们能接受七个句子{xz,xy,xyz,xyz,z,xxyz,xyz}以及格式良好的公式吗?用Prolog验证这一点

这是我的密码:

s --> e.
e --> [x], e.
e --> [y], e.
e --> [z].
它只能识别s[z],R。为什么

?- s([z], R).
R = [].

?- s([xz], R).
false.

?- s([x], R).
false.
根据上面的评论

句子中的每个元素都需要用逗号分隔。字符串按原子方式处理,而不是按字符序列处理

?- s([x,z], R).
R = [] .

?- s([x,y,x,z], R).
R = [] .

?- s([x,y], R).
false.
根据上面的评论

句子中的每个元素都需要用逗号分隔。字符串按原子方式处理,而不是按字符序列处理

?- s([x,z], R).
R = [] .

?- s([x,y,x,z], R).
R = [] .

?- s([x,y], R).
false.

首先,正如@Lourger在评论中指出的,在调用DCGs时始终使用短语/2或短语/3。其次,正如@TomasBy和@WillBeason所指出的,您的DCG描述了一个包含原子x、y和z的列表,用逗号分隔。所以,为了测试xz是否是一个实际的句子,我假设根据你的语法,s代表什么,你可以询问:

?- phrase(s,[x,z]).
true ;
false.
的确如此。现在让我们来看看最一般的查询,也就是说,问哪些句子存在? 那不太顺利。原因是DCG规则的顺序:调用s//0会导致调用e//0的第一条规则,该规则会再次递归调用e//0,也就是说,e//0的第一条规则,因此循环将继续,直到Prolog耗尽堆栈。因此,让我们通过将非递归规则放在第一位来改变规则的顺序

s --> e.

e --> [z].          % <- moved here from last position
e --> [x], e.
e --> [y], e.
现在我们得到了实际的解决方案。因此,DCG规则的顺序确实很重要。然而,列出答案是不公平的,因为e//0的最后一条规则,即处理y的规则,实际上从未被调用。这可以通过在目标长度/2前加前缀来解决。查询

?- length(S,_).
S = [] ;
S = [_G3671] ;
S = [_G3671, _G3674] ;
S = [_G3671, _G3674, _G3677] ;
.
.
.
?- phrase(s,[X,y,z]).
X = x ;
X = y ;
false.
…生成包含所有可能长度的列表,因此在DCG调用前加上前缀,将使Prolog在继续长度1之前查找长度为0的所有解决方案,然后再继续长度2,依此类推

?- length(S,_), phrase(s,S).
S = [z] ;                    % <- solutions of length 1 from here
S = [x, z] ;                 % <- solutions of length 2 from here
S = [y, z] ;
S = [x, x, z] ;              % <- solutions of length 3 from here
S = [x, y, z] ;
S = [y, x, z] ;
S = [y, y, z] ;
S = [x, x, x, z] ;           % <- solutions of length 4 from here
.
.
.
。。。这将产生所有七个句子,最多由3个单词组成。请注意,您的示例{xz,xy,xyz,xyz,z,xxyz,xyz}并不完全是您的语法描述的句子集。根据语法规则,元素xy根本不是一个句子。句子xyxz和xxyz由您的语法指定,但要求最长至少四个单词,这将产生十六个答案。七个句子中的最后一个,xyz,在你的例子中出现两次,除非你是指这个查询

?- length(S,_).
S = [] ;
S = [_G3671] ;
S = [_G3671, _G3674] ;
S = [_G3671, _G3674, _G3677] ;
.
.
.
?- phrase(s,[X,y,z]).
X = x ;
X = y ;
false.
。。。这就产生了两句话,第一句仍然是重复的

最后,如果你真的非常需要得到原子作为答案,你可以改变DCG,把对应于x,y和z的代码放到列表中,而不是实际的原子。然后,您可以使用atom_codes/2将句子作为单个原子而不是单词列表获取:

s --> e.

e --> [0'z].      % 0'z denotes the code corresponding to z
e --> [0'x], e.   % 0'x denotes the code corresponding to x
e --> [0'y], e.   % 0'y denotes the code corresponding to y

?- between(1,3,N), length(S,N), phrase(s,S), atom_codes(A,S).
N = 1,
S = [122],
A = z ;
N = 2,
S = [120, 122],
A = xz ;
N = 2,
S = [121, 122],
A = yz ;
N = 3,
S = [120, 120, 122],
A = xxz ;
N = 3,
S = [120, 121, 122],
A = xyz ;
N = 3,
S = [121, 120, 122],
A = yxz ;
N = 3,
S = [121, 121, 122],
A = yyz ;
false.

首先,正如@Lourger在评论中指出的,在调用DCGs时始终使用短语/2或短语/3。其次,正如@TomasBy和@WillBeason所指出的,您的DCG描述了一个包含原子x、y和z的列表,用逗号分隔。所以,为了测试xz是否是一个实际的句子,我假设根据你的语法,s代表什么,你可以询问:

?- phrase(s,[x,z]).
true ;
false.
的确如此。现在让我们来看看最一般的查询,也就是说,问哪些句子存在? 那不太顺利。原因是DCG规则的顺序:调用s//0会导致调用e//0的第一条规则,该规则会再次递归调用e//0,也就是说,e//0的第一条规则,因此循环将继续,直到Prolog耗尽堆栈。因此,让我们通过将非递归规则放在第一位来改变规则的顺序

s --> e.

e --> [z].          % <- moved here from last position
e --> [x], e.
e --> [y], e.
现在我们得到了实际的解决方案。因此,DCG规则的顺序确实很重要。然而,列出答案是不公平的,因为e//0的最后一条规则,即处理y的规则,实际上从未被调用。这可以通过在目标长度/2前加前缀来解决。查询

?- length(S,_).
S = [] ;
S = [_G3671] ;
S = [_G3671, _G3674] ;
S = [_G3671, _G3674, _G3677] ;
.
.
.
?- phrase(s,[X,y,z]).
X = x ;
X = y ;
false.
…生成包含所有可能长度的列表,因此在DCG调用前加上前缀,将使Prolog在继续长度1之前查找长度为0的所有解决方案,然后再继续长度2,依此类推

?- length(S,_), phrase(s,S).
S = [z] ;                    % <- solutions of length 1 from here
S = [x, z] ;                 % <- solutions of length 2 from here
S = [y, z] ;
S = [x, x, z] ;              % <- solutions of length 3 from here
S = [x, y, z] ;
S = [y, x, z] ;
S = [y, y, z] ;
S = [x, x, x, z] ;           % <- solutions of length 4 from here
.
.
.
。。。这将产生所有七个句子,最多由3个单词组成。请注意,您的示例{xz,xy,xyz,xyz,z,xxyz,xyz}并不完全是您的语法描述的句子集。根据语法规则,元素xy根本不是一个句子。句子xyxz和xxyz由您的语法指定,但要求最长至少四个单词,这将产生十六个答案。七个句子中的最后一个,xyz,在你的例子中出现两次,除非你是指这个查询

?- length(S,_).
S = [] ;
S = [_G3671] ;
S = [_G3671, _G3674] ;
S = [_G3671, _G3674, _G3677] ;
.
.
.
?- phrase(s,[X,y,z]).
X = x ;
X = y ;
false.
。。。这就产生了两句话,第一句仍然是重复的

最后,如果你真的非常需要得到原子作为答案,你可以改变DCG,把对应于x,y和z的代码放到列表中,而不是实际的原子。然后,您可以使用atom_codes/2将这些句子作为一个单独的at om而不是单词列表:

s --> e.

e --> [0'z].      % 0'z denotes the code corresponding to z
e --> [0'x], e.   % 0'x denotes the code corresponding to x
e --> [0'y], e.   % 0'y denotes the code corresponding to y

?- between(1,3,N), length(S,N), phrase(s,S), atom_codes(A,S).
N = 1,
S = [122],
A = z ;
N = 2,
S = [120, 122],
A = xz ;
N = 2,
S = [121, 122],
A = yz ;
N = 3,
S = [120, 120, 122],
A = xxz ;
N = 3,
S = [120, 121, 122],
A = xyz ;
N = 3,
S = [121, 120, 122],
A = yxz ;
N = 3,
S = [121, 121, 122],
A = yyz ;
false.
试着用s[x,z],R.代替。您的规则不允许s->[x]。请尝试s[x,z],R。而不是。您的规则不允许使用s->[x]。对于DCG,请使用短语[x,z]。例如,对于DCG,使用短语[x,z]。例如