📜  检查语言是否是上下文无关的

📅  最后修改于: 2021-09-27 14:49:44             🧑  作者: Mango

先决条件 – Pumping Lemma,如何识别语言是否规则
我们通常会面临一些问题,以确定哪些给定的语言是上下文无关的。对于常规语言,回答这个问题相对容易,但对于上下文无关语言,有时会很棘手。 Pumping Lemma 为我们提供了执行否定测试的能力,即如果一种语言不满足泵引理,那么我们可以肯定地说它不是上下文无关的,但如果它满足,则该语言可能是也可能不是上下文无关的。 Pumping Lemma 更像是一个数学证明,需要更多时间,将其应用于上下文无关语言是一项乏味的任务,并且为复杂的语言表达式找出反例并不多。根据常见的观察和分析,我们可以非常快速地解决这个问题:

  1. 每种常规语言都是上下文无关的。
    示例 – { a^mb^lc^kd^n | m, l, k, n >= 1 } 是上下文无关的,因为它也是常规的。
  2. 给定一个表达式,使得可以在字符串中获得中心点或中点,因此我们可以使用堆栈进行左右子部分的比较。
    示例 1 – L = { a^nb^n | n >= 1} 是上下文无关的,因为我们可以推送 a,然后我们可以在每次出现 b 时弹出 a。

    示例 2 – L = { a^mb^nc^{(m+n)} } 是上下文无关的。我们可以将其改写为 { a^mb^nc^nc^m }.

    示例 3 – L = { a^nb^{(2n)} } 是上下文无关的,因为我们可以在每次出现 b 时压入两个 a 并弹出一个 a。因此,我们在这里也得到了一个中点。

    示例 4 – L = { a^nb^nc^n } 不是上下文无关的。

  3. 给定表达式是多个带有中点的表达式的组合,这样每个子表达式都独立于其他子表达式,则它是上下文无关的。
    示例 1 – L = { a^mb^mc^nd^n } 是上下文无关的。它包含多个表达式,每个表达式都有一个中点。

    示例 2 – L = { a^mb^nc^md^n } 不是上下文无关的。

  4. 给定的表达式包含一个操作,其中可以找到中点以及中间的一些独立的正则表达式,结果为上下文无关语言。
    示例 – L = { a^mb^ic^md^k } 是一种上下文无关语言。
    这里,我们有 b^i 和 d^k 作为独立的正则表达式,这不会影响堆栈。
  5. 不形成可以使用堆栈进行线性比较的模式的表达式不是上下文无关语言。
    示例 1 – L = { a^mb^n^2 } 不是上下文无关的。
    示例 2 – L = { a^nb^2^n } 不是上下文无关的。
    示例 3 – L = { a^n^2 } 不是上下文无关的。
    示例 4 – L = { a^m | m 是素数 } 不是上下文无关的。
  6. 涉及独立计算和比较三个或更多变量的表达式不是上下文无关语言,因为堆栈一次只允许比较两个变量。
    示例 1 – L = { a^nb^nc^n } 不是上下文无关的。

    示例 2 – L = { w | na(w) = nb(w) = nc(w) } 不是上下文无关的。

    示例 3 – L = { a^ib^jc^k | i > j > k } 不是上下文无关的。

  7. 需要记住的一点是计数和比较只能在下推自动机中使用堆栈顶部而不是堆栈底部进行,因此表现出涉及与堆栈底部比较的特征的语言不是上下文无关语言。
    示例 1 – L = { a^mb^nc^md^n } 不是上下文无关的。
    先推a,然后推b。现在,我们将无法将 c 与 a 进行比较,因为堆栈顶部有 b。

    示例 2 – L = { WW | W 属于 {a, b}* } 不是上下文无关的。
    有人可能会想绘制一个非确定性下推自动机,但这无济于事,因为第一个符号将位于堆栈底部,而当第二个 W 开始时,我们将无法将其与堆栈底部进行比较。

  8. 如果我们甚至可以以非确定性的方式在表达式中找到中点,那么它就是上下文无关语言。
    示例 1 – L = { W W^r | W 属于 {a, b}* } 是上下文无关语言。

    示例 2 – L = { a^ib^jc^kd^l | i=k 或 j=l } 是一种上下文无关语言。