【问题标题】:Prolog : Combining DCG grammars with other restrictionsProlog:将 DCG 语法与其他限制相结合
【发布时间】:2011-09-25 08:48:10
【问题描述】:

Prolog 的 DCG 给我留下了深刻的印象,我能够以多快的速度生成适合特定语法的所有可能结构。

但我想将此搜索与其他约束结合起来。例如,定义一个复杂的语法并要求 Prolog 生成所有不超过 10 个单词的句子。或者所有不重复同一个词两次的句子。

是否可以将这样的额外约束添加到 DCG 语法?还是我基本上必须将 DCG 翻译回普通的 Prolog 子句并开始修改它们?

【问题讨论】:

    标签: prolog grammar dcg


    【解决方案1】:

    如果你只想查看所有生成的句子,使用以下非常方便:

    ?- length(Xs, N), phrase(mynonterminal, Xs).
    

    当然,这会生成所有句子。但它非常有用,它可以节省您考虑具体限制的时间。如果您想进一步限制,请在前面添加目标between(0,10,N)

    如果你想在语法中说某个非终结符应该占用一定的长度,最好明确地说出来:

    seq([]) --> [].
    seq([E|Es]) --> [E], seq(Es).
    
    a --> {length(Es,10)}, seq(Es), {phrase(mynonterminal,Es)}.
    

    如果你还是不开心,那么你想表达两个非终结符的交集。这无异于询问两种上下文无关语言的交集,这在一般情况下是不可判定的。但在更早的时候,您将遇到终止问题。因此请注意以下内容:

    :- op( 950, xfx, &).
    
    (NT1 & NT2) -->
         call(Xs0^Xs^(phrase(NT1,Xs0,Xs),phrase(NT2,Xs0,Xs))).
    

    只有在不使用library(lambda)时才需要以下内容:

    ^(V0, Goal, V0, V) :-
          call(Goal,V).
    
    ^(V, Goal, V) :-
         call(Goal).
    

    所以这允许你现在表达两个非终结符的交集。但是请注意,这里的终止非常脆弱。特别是,第一个非终结符的终止不一定限制第二个。

    【讨论】:

    • 我认为处理“seq”的前面部分是我需要的(即一个非终结符是一个有限列表)。但我并没有完全让它发挥作用,也许是因为我不明白。第一个示例中的“短语”是什么?
    • 在理解(&)//2的定义之前,试着理解DCGs在Prolog中是如何编码的。 Pereira 和 Shieber 的 Prolog and Natural Language Analysis 是一本很好的书。 mtome.com/Publications/PNLA/pnla.html(免费)
    • 您好假,感谢您的参考书。会有用的。在我的特定问题上,我认为您的解决方案是“a --> {length(Es,10)}, seq(Es), {phrase(mynonterminal,Es)}。”看起来几乎正是我想要的。我只是不明白,在我的程序中,我应该在你写“短语”的地方写什么。我可以看到那部分的目的是说序列是由非终结符组成的。但是那个“短语”谓词本身是什么?
    • 啊。不行。对不起。我看到它是一个内置关键字。
    • phrase/2 是一个干净的接口,用于谓词调用非终结符。您也可以直接调用它们,但是如果调用谓词或非终结符,则并不明显。所以严格来说它是不需要的,但阅读起来更清晰。
    【解决方案2】:

    好吧,您始终可以使用 {} 并在两者之间编写任何类型的序言谓词,例如:

    foo(X)-->
        { valid(X) },
        [a].
    foo(X)-->
        [b].
    

    所以你可以添加某种字数计数器。当然,如果每个标记都是一个单词,你可以简单地写成:length(L,N), N

    另一方面,根据约束的复杂性,将它们编码到不同的部分可能会更好。类似于 parser-> 编译器中的语义检查器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-27
      • 2016-05-03
      • 1970-01-01
      • 1970-01-01
      • 2014-08-13
      • 2016-12-12
      相关资源
      最近更新 更多