【问题标题】:parsing with CHR (Constraint handling rules)使用 CHR 解析(约束处理规则)
【发布时间】:2021-01-09 20:44:21
【问题描述】:

尝试使用 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(is),w(on),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 混合的信息。什么都找不到!!

【问题讨论】:

    标签: parsing prolog constraints dcg chr


    【解决方案1】:

    我认为这不一定是个好主意。我特别认为这不会比使用 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),
    w(the, 0, 1).
    

    鉴于这种格式,您可以增强匹配规则以仅组合相邻的输入(其中每个组件的结束标记与“下一个”组件的开始标记相同):

    w(the, S, M), w(X, M, E) <=> w([the,X], S, E).
    w(L, S, M1), w(on, M1, M2), w(R, M2, E) <=> w(on(L,R), S, E).
    w(L, S, M1), w(is, M1, M2), w(R, M2, E) <=> w(is_(L,R), S, E).
    

    (我使用is_ 而不是is,因为is 是一个内置运算符,而is(X, Y) 事实将被打印为X is Y,这在接下来的内容中令人困惑。)

    这可以让你取得一些进步:

    ?- parse([the, box, is, on, the, table]).
    w([the, table], 4, 6),
    w(is_([the, box], on), 0, 4).
    

    我们看到thetable在位置4到5和5到6被合并成一个短语the, table在位置4到6。还有单词thebox、@987654343 @,on,被合并为一个对象,覆盖位置 0 到 4。但这不正确:“盒子打开”不是一个有效的短语。 “is”右边的短语必须是位置或其他情况。您需要有关短语中子短语类型的更多信息。您需要正确的语法信息,即通过定义不同名称的规则在 DCG 中编码的那种信息。

    这是一个扩展版本:

    :- chr_constraint noun_phrase/3, situation/3, sentence/3.
    
    w(the, S, M), w(X, M, E) <=>
        noun_phrase([the,X], S, E).
    w(on, S, M), noun_phrase(R, M, E) <=>
        situation(on(R), S, E).
    noun_phrase(L, S, M1), w(is, M1, M2), situation(R, M2, E) <=>
        sentence(is_(L,R), S, E).
    

    这很有效:

    ?- parse([the, box, is, on, the, table]).
    sentence(is_([the, box], on([the, table])), 0, 6).
    

    但此时您正在编写一个语法丑陋的 DCG,并且您必须手动跟踪大量额外信息。为什么不写 DCG 呢?

    noun_phrase([the, X]) -->
        [the],
        [X].
    
    situation(on(Place)) -->
        [on],
        noun_phrase(Place).
    
    sentence(is_(Thing, Where)) -->
        noun_phrase(Thing),
        [is],
        situation(Where).
    

    这同样有效:

    ?- phrase(sentence(Sentence), [the, box, is, on, the, table]).
    Sentence = is_([the, box], on([the, table])).
    

    如果您想将此信息放入 CHR 约束中,您可以通过调用该约束来实现。例如,上面的 DCG:

    :- chr_constraint sentence/1.
    
    parse(Tokens) :-
        phrase(sentence(Sentence), Tokens),
        sentence(Sentence).
    

    这会得到与上面相同的 CHR 结果,但没有不再需要的位置标记:

    ?- parse([the, box, is, on, the, table]).
    sentence(is_([the, box], on([the, table]))).
    

    【讨论】:

    • 哇,还在阅读……Swi 是否支持 CHR 语法
    • 我一直在思考如何解析 DCG 样式并使用 CHR 为特殊情况等编写约束。诱拐获得越来越好的表示...请注意,这只是想法。我刚刚发现了关于 CHR 的信息
    • .. 在我习惯了之后甚至更疯狂的想法...找出基本的解析操作员!然后传递句子 结构示例并让约束驱动工作语法的发现。 (F.e. Sequitur 压缩算法对单行文法(即 Sentence -to-> Grammar)反向工作,但它是预先确定的结构)
    • 这听起来是一个有趣的想法,但你应该只在你的积木世界使用一些更简单的语法时才尝试它:-)
    • 是的..我仍然需要学习 CHR.. CHRG 看起来也很有希望,但是没有太多实用的文档和教程。我发现的论文太技术性了
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多