这个Pushdown Automata(PDA)接受什么语言?

时间:2011-08-10 21:32:09

标签: context-free-grammar finite-automata pushdown-automaton

明天考试,教授让我们知道一个问题:)。

在此图的上下文中,L是epsilon(空字符串),Z0是堆栈空符号。

我在确定关于语言生成的单词的一些规则方面取得了一些进展,但却未能确定整个语言。

谢谢!

PDA Diagram

3 个答案:

答案 0 :(得分:4)

这个PDA并不像乍一看那样不确定......考虑以下情况。

  1. 假设输入以ab开头。然后我们使用空堆栈进入状态2,因此“L”规则不匹配,因此我们只处于状态2。

  2. 假设输入以(a^n)b开头,n> 1.然后我们在堆栈上以a^(n-1)进入状态2,并且“L”规则触发我们将堆栈中的a^(n-2)带回状态1。但是由于状态2中的堆栈是a^(n-1)(并且n> 1),状态2上的环回箭头不能匹配......所以再一次,我们(有效地)仅在一个状态:状态1。

  3. 假设输入以ba开头。然后我们再次使用空堆栈进入状态2,并且在情况(1)中,“L”规则不匹配,因此我们仅处于状态2.

  4. 最后,假设输入以(b^n)a开头,n> 1.然后我们在堆栈上使用b^n进入状态2,因此“L”规则不会触发,我们只处于状态2.

  5. 换句话说,任何时候“L”规则将PDA的“分叉”创建为状态1,它只会这样做,因为“a”位于堆栈顶部...这意味着分叉保留在状态2必须在下一个输入符号上死亡。所以实际上这里没有非确定性,你可以将这个PDA建模为好像它总是处于一种状态。

    有了这个观察结果,我认为很容易看出@Nayuki是正确的:这个PDA接受任何字符串的数量是b的两倍。

    首先,表明当PDA处于状态1时,堆栈总是完全由b或(或为空)组成。当PDA处于状态2时,堆栈完全由b组成(或为空)。这是一个类似于上述四种情况的简单案例分析;例如“状态1,堆栈= a ^ n,下一个字符b =>状态1,堆栈= a ^(n-2)”。 (注意n = 0或n = 1的情况。)

    将每个b视为“希望与2 a s合作”。状态1,stack = a^n表示n a正在等待合作伙伴。状态1,stack = b^n表示n b正在等待合作伙伴。状态2,stack = b^n表示一个b与一个a 合作,而 n b仍在等待合作伙伴。

    证明我刚写的是真的,结果如下。

答案 1 :(得分:2)

在脑海中玩一些测试用例并且没有严格证明,我认为这个(非确定性)PDA存在接受计算,当且仅当输入字符串的数量是a的两倍时b的数量

答案 2 :(得分:1)

'a'的数量是'b'的两倍。

精确语法:

S  = (a|b)*      where N_a(S)=2*N_b(S)

N_a(X)表示X中的'a'等数

在任何时候,筹码都可以是'a'或全部'b'。为什么?因为,没有/ xxbxx或b / xxaxx的转换。

案例1:堆栈全部是'a。

您可以看到循环形式为:

  1. a(a * b)+,如果最后我们采用过渡L,a / L在(2-> 1)

  2. a(a * b)+ a,如果最后我们采用转换a,Z0 / Z0在(2-> 1)中。最后一个'a'不会从堆栈弹出任何东西。

  3. 在每个周期中,'a'弹出的数量是两个。循环次数与'b'次数相同(除了a,Z0 / Z0最后出现)

    如果'a'的数字在最后'b'之前,我们将采用最后一次转换L,a / L

    如果'a'的数字在前一个'b'之前是奇数,我们将采用最后一个转换a,Z0 / Z0。 a,Z0 / Z0再接受一个'a'

    因此,

    A1=a(a*b)+a  where N_a(A1)=2*N_b(A1),     N_a(A1) is even
    A2=a(a*b)+   where N_a(A2)=2*N_b(A2),     N_a(A2) is even
    

    这将减少为:

    A=a(a|b)+    where N_a(A)=2*N_b(A),     N_a(A) is even
    

    (我们将状态为1,堆栈为空)

    案例2:堆栈全是'b'。

    同样,您可以看到每个周期的形式如下:b * ab * a。 并且在每个周期中,将弹出一个'b'。 每当接受'b'时,'b'被推到堆栈上。 因此,当堆栈为空,并且我们回到状态1时,循环的次数等于'b'我们接受/推入堆栈的数量。那么,

    B=b(b*ab*a)^n where N_b(B)=n
    

    但你可以看到,n = N_a(B)/ 2。因此,

    B=b(b*ab*a)+ where N_a(B)=2*N_b(B)
    

    这将减少为:

    B=b(b|a)+ where N_a(B)=2*N_b(B)
    

    由于只有两条可能的路径(A或B),循环可以采用0或1次,

    因此,

    S=(A|B)*
    A=a(a|b)+    where N_a(A)=2*N_b(A)
    B=b(b|a)+    where N_a(B)=2*N_b(B)
    

    这将减少为:

    S=((a|b)+)*   where N_a(S)=2*N_b(S)
    

    将减少到:

    S=(a|b)*      where N_a(S)=2*N_b(S)
    

    Q.E.D。