为什么我需要复制我的 Prolog 谓词才能使我的程序运行?
Why do I need to duplicate my Prolog predicates in order to make my program work?
我正在使用 SICStus Prolog 4.0.8 编写一个程序来解析英文句子和 returns 句法树,以及 yes/no 根据编程的语法。这是一个例子(句子是 Larry 和 Carol meet their older neighbors Paul and Lillian):
s(s(N, V)) --> np(N), vp(V).
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np(np2(D, A, N)) --> det(D), adj(A), cn(N).
app(app(N1, N2)) --> np2(N1), np1(N2).
vp(vp1(V, A)) --> tv(V), app(A).
如果我 运行 这样的代码,它会抱怨 np2/3 没有定义,但是如果我把数字放在括号之前,它会抱怨 np/3 没有定义.我唯一的解决方案是将两个谓词都放入,如下所示:
s(s(N, V)) --> np(N), vp(V).
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np(np2(D, A, N)) --> det(D), adj(A), cn(N).
app(app(N1, N2)) --> np2(N1), np1(N2).
vp(vp1(V, A)) --> tv(V), app(A).
np1(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np2(np2(D, A, N)) --> det(D), adj(A), cn(N).
vp1(vp1(V, A)) --> tv(V), app(A).
然后编译执行成功。这种行为的原因是什么?
在您代码的第一个版本中,子句
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
定义谓词np/3
(并调用谓词pn/3
)。但是,子句
app(app(N1, N2)) --> np2(N1), np1(N2).
调用未定义的谓词 np2/3
和 np1/3
。这就是运行时错误的原因。
在您代码的第二个版本中,还定义了谓词np2/3
和np1/3
,因此没有错误。
有什么问题? 我认为你混淆了 np/3
和 pn/3
(它们是 谓词 ) np1/3
和 np2/3
( 项 表示语法树节点)。
np( np1(N1, C, N2) ) --> pn(N1), conj(C), pn(N2).
^ ^ ^
| | |
| | +--- predicate being called (must be defined)
| |
| +----------------------- term representing a syntax tree node (this is not a predicate)
|
+---------------------------- predicate being defined
我正在使用 SICStus Prolog 4.0.8 编写一个程序来解析英文句子和 returns 句法树,以及 yes/no 根据编程的语法。这是一个例子(句子是 Larry 和 Carol meet their older neighbors Paul and Lillian):
s(s(N, V)) --> np(N), vp(V).
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np(np2(D, A, N)) --> det(D), adj(A), cn(N).
app(app(N1, N2)) --> np2(N1), np1(N2).
vp(vp1(V, A)) --> tv(V), app(A).
如果我 运行 这样的代码,它会抱怨 np2/3 没有定义,但是如果我把数字放在括号之前,它会抱怨 np/3 没有定义.我唯一的解决方案是将两个谓词都放入,如下所示:
s(s(N, V)) --> np(N), vp(V).
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np(np2(D, A, N)) --> det(D), adj(A), cn(N).
app(app(N1, N2)) --> np2(N1), np1(N2).
vp(vp1(V, A)) --> tv(V), app(A).
np1(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
np2(np2(D, A, N)) --> det(D), adj(A), cn(N).
vp1(vp1(V, A)) --> tv(V), app(A).
然后编译执行成功。这种行为的原因是什么?
在您代码的第一个版本中,子句
np(np1(N1, C, N2)) --> pn(N1), conj(C), pn(N2).
定义谓词np/3
(并调用谓词pn/3
)。但是,子句
app(app(N1, N2)) --> np2(N1), np1(N2).
调用未定义的谓词 np2/3
和 np1/3
。这就是运行时错误的原因。
在您代码的第二个版本中,还定义了谓词np2/3
和np1/3
,因此没有错误。
有什么问题? 我认为你混淆了 np/3
和 pn/3
(它们是 谓词 ) np1/3
和 np2/3
( 项 表示语法树节点)。
np( np1(N1, C, N2) ) --> pn(N1), conj(C), pn(N2).
^ ^ ^
| | |
| | +--- predicate being called (must be defined)
| |
| +----------------------- term representing a syntax tree node (this is not a predicate)
|
+---------------------------- predicate being defined