问题描述
尝试使用 CHR(约束处理规则)进行某种解析 我想出了这个(仍在学习中)
w(the),w(X) <=> w([the,X]).
w(L),w(on),w(R) <=> w(on(L,R)).
w(L),w(is),w(R) <=> w(is(L,R)).
这是我得到的:
?- w(the),w(Box),w(the),w(table).
w(table),w([the,on(is,[the,Box])]).
应该是:
is([the,Box],on([the,table]))
为了使它工作,我必须弄清楚如何对“on”和后来的“is”进行某种后期绑定,所以 the-X 已经被“收集”
第二个问题是如何编写 CHR 规则,以便它们解析列表,而不是制定 w(..) 目标。
PS> 也欢迎任何有关将 DCG 与 CHR 混合的信息。找不到任何东西!!
解决方法
我认为这不一定是个好主意。我特别不认为它会比使用 DCG 更容易。您仍然需要编写某种正确的语法,该语法比“组合某些单词序列”更了解输入的结构。也就是说,有一些关于 CHR 解析的工作,例如参见 CHR Grammars。
您的第一个问题是 CHR 约束是无序的。当您尝试匹配 w(L),w(on),w(R)
时,您无法保证 L
实际上位于输入中 R
的左侧。不会为您记录此信息。
所以你能做的就是自己记录下来。您可以将每个 w(X)
替换为 w(X,Start,End)
约束,其中 Start
和 End
是某种输入位置标记。例如,简单地从左到右对标记进行编号:
:- use_module(library(chr)).
:- chr_constraint w/3.
parse(Tokens) :-
parse(Tokens,0).
parse([],_Position).
parse([Token | Tokens],Position) :-
NextPosition is Position + 1,w(Token,Position,NextPosition),parse(Tokens,NextPosition).
您可以按如下方式使用它:
?- parse([the,box,is,on,the,table]).
w(table,5,6),w(the,4,5),w(on,3,4),w(is,2,3),w(box,1,2),1).
鉴于这种格式,您可以增强匹配规则以仅组合相邻的输入(其中每个组件的结束标记与“下一个”组件的开始标记相同):
w(the,S,M),w(X,M,E) <=> w([the,X],E).
w(L,M1),M1,M2),w(R,M2,E) <=> w(on(L,R),E) <=> w(is_(L,E).
(我使用 is_
而不是 is
因为 is
是一个内置运算符,is(X,Y)
事实将打印为 X is Y
,即以下内容令人困惑。)
这可以让您取得一些进展:
?- parse([the,table]).
w([the,table],w(is_([the,box],on),4).
我们看到位置 4 到 5 和 5 到 6 处的 the
和 table
在位置 4 到 6 处合并成一个短语 the,table
。还有单词 {{1} }、the
、box
、is
被合并为一个对象,覆盖位置 0 到 4。但这不正确:“the box is on”不是一个有效的短语。 “是”右边的短语必须是位置或其他情况。您需要有关短语中子短语种类的更多信息。您需要正确的语法信息,即通过定义不同名称的规则在 DCG 中编码的类型。
这是一个扩展版本:
on
这有效:
:- chr_constraint noun_phrase/3,situation/3,sentence/3.
w(the,E) <=>
noun_phrase([the,E).
w(on,noun_phrase(R,E) <=>
situation(on(R),E).
noun_phrase(L,situation(R,E) <=>
sentence(is_(L,E).
但此时您正在以丑陋的语法编写 DCG,并且您必须手动跟踪大量额外信息。为什么不写 DCG 呢?
?- parse([the,table]).
sentence(is_([the,on([the,table])),6).
这同样有效:
noun_phrase([the,X]) -->
[the],[X].
situation(on(Place)) -->
[on],noun_phrase(Place).
sentence(is_(Thing,Where)) -->
noun_phrase(Thing),[is],situation(Where).
如果您想将此信息放入 CHR 约束中,您可以通过调用该约束来实现。例如,对于上面的 DCG:
?- phrase(sentence(Sentence),[the,table]).
Sentence = is_([the,table])).
这将获得与上述相同的 CHR 结果,但没有不再需要的位置标记:
:- chr_constraint sentence/1.
parse(Tokens) :-
phrase(sentence(Sentence),Tokens),sentence(Sentence).