找到这种语言的下推自动机L = {A ^ i B ^ j C ^ k |具有一个堆叠的2k< = i< = 3k或j!=(i + k)}

时间:2017-11-14 14:49:49

标签: pushdown-automaton jflap

我无法找到自动机,因为我只能用多个堆栈或集理论的交叉来想象它。

1 个答案:

答案 0 :(得分:1)

语言:L = { A^i B^j C^k | 2k <= i <= 3k OR j != (i+k) }

此语言是两种语言L'L''

的结合
L'  = { A^i B^j C^k | 2k <= i <= 3k }
L'' = { A^i B^j C^k | j != (i+k) }

如果我们找出每种语言的NPDA,我们可以通过以下方式为这两种语言的联合写下新的NPDA:

  1. 引入新的开始状态q*
  2. 添加转化f(q*,e,Z) = (q0',Z)f(q*,e,Z) = (q0'',Z),其中e为epsilon / lambda,Z是堆叠符号的底部,q0'q0''L'L''的NPDA的起始状态。
  3. 我们已经将更难的问题分解为两个更简单的问题,并想出如何将更简单的问题的答案放在一起来回答更难的问题。对于计算机科学,数学以及计算机程序设计等正规科学而言,这是你可能开发的最重要的技能。

    L'的NPDA应该是什么样的?它可以读取任意数量的B,前提是它们介于AC之间。我们需要跟踪我们看到的A的数量,比如每次看到A时将A推到堆栈上;一旦我们开始看到C,我们需要将A从群集中弹出。假设我们想要通过空堆栈接受,我们需要删除所有2k = i s;但我们怎么知道要删除多少?如果我们有A,我们会为我们看到的每个C删除两个i = 3k。如果我们有A,我们会为我们看到的每个C删除三个A。事实上,我们介于两者之间。这在概念上是困难的。 nondeterminism 的概念 - NPDA中的N--在这里至关重要。我们不需要确切知道字符串将如何被接受;我们只需要一个可以接受该语言中的字符串的过程,并且不能接受不在该语言中的字符串。我们可以猜测是否需要在任何特定时刻从堆栈中删除两个或三个2k;这将保证我们不会超过3kQ s S Q' S' ------------------------ // read A's and push onto stack q0 A Z q0 AZ q0 A A q0 AA // begin reading B's q0 B Z q1 Z q0 B A q1 Z // begin reading C's if no B's q0 C A q2 - q0 C A q3 - // read B's q1 B Z q1 Z q1 B A q1 A // begin reading C's if B's q1 C A q2 - q1 C A q3 - // pop the final A for the last C read q2 - A q4 - // if popping three A's, pop the middle A q3 - A q2 - // pop the first A for each C read after the first C q4 C A q2 - q4 C A q3 - // transition to separate accepting state if stack empty q4 - Z qA - 界限,并且它还允许我们在两者之间获得任何结果。为了使这项工作成功,我们可以简单地崩溃或拒绝所有失败的有效字符串执行,只要其中一个可能的执行通过。

    这是基于此描述的NPDA,假设接受空堆栈并接受状态:

    qR

    在上述NPDA中,未显示导致“死”状态的转换。如果要显示它,请添加这些转换并调用状态L'。如果没有那些明确的过渡,NPDA通常被理解为“崩溃”并拒绝输入。对于NPDA中的任何字符串,此qA将以状态L''结束,并显示空堆栈。

    对于另一种语言,我们可以进一步细分。 R'是两种语言R''R' = { A^i B^j C^k | j < i + k } R'' = { A^i B^j C^k | j > i + k } 的结合:

    L''

    使用上述相同的结构,我们可以通过查找R'R''的NPD并将这些答案放在一起来为R'创建NPDA。

    对于A,我们可以在阅读A时将A推入堆栈;我们可以弹出B s,如果有的话,或者在阅读B时推送B;最后,我们可以弹出C s,如果有的话,或者在阅读C时推送j < i + k。当且仅当我们完成时,堆栈顶部有AC,我们才会A。然后,我们可以移动到接受状态并从堆栈中弹出CR''以获得空堆栈。

    对于B,我们可以做同样的事情,并在堆栈顶部寻找B。我们可以移动到接受状态并弹出 R' R'' Q s S Q' S' Q s S Q' S' ----------------------- ----------------------- // count A's, first B/C // count A's, first B/C q0' A Z q0' AZ q0'' A Z q0'' AZ q0' A A q0' AA q0'' A A q0'' AA q0' B Z q1' BZ q0'' B Z q1'' BZ q0' B A q1' - q0'' B A q1'' - q1' C Z q2' CZ q0'' C A q2'' CZ q1' C A q2' CA q0'' C Z q2'' CA // count B's, first C // count B's, first C q1' B Z q1' BZ q1'' B Z q1'' BZ q1' B A q1' - q1'' B A q1'' - q1' B B q1' BB q1'' B B q1'' BB q1' C Z q2' CZ q1'' C Z q2'' CZ q1' C A q2' CA q1'' C A q2'' CA q1' C B q2' CB q1'' C B q2'' CB // count C's // count C's q2' C Z q2' CZ q2'' C Z q2'' CZ q2' C A q2' CA q2'' C A q2'' CA q2' C B q2' - q2'' C B q2'' - q2' C C q2' CC q2'' C C q2'' CC // accept if A's or C's // accept if B's q2' - A qA' - q2'' - B qA'- - q2' - C qA' - // accept if A's or C's // accept if B's qA' - A qA' - qA'' - B qA'' - qA' - C qA' - 以清除堆栈。

    Q    s    S    Q'    S'
    -----------------------
    q*   -    Z    q0    Z
    q*   -    Z    q0'   Z
    q*   -    Z    q0''  Z
    

    原始语言的NPDA如下:

    qA

    将前面给出的所有其他转换添加到此处,并在三个接受状态qA'qA''或{{1}}中的任何一个中定义接受为空堆栈。