使用 CHR 解析约束处理规则

问题描述

尝试使用 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) 约束,其中 StartEnd 是某种输入位置标记。例如,简单地从左到右对标记进行编号:

:- 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 处的 thetable 在位置 4 到 6 处合并成一个短语 the,table。还有单词 {{1} }、theboxis 被合并为一个对象,覆盖位置 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).