4

Exam tomorrow and the prof let us know a question that would be on it :).

In the context of this diagram, L is epsilon (The empty string), and Z0 is the stack empty symbol.

I've made some progress in determining a few rules about the words the language generates, but haven't been able to pin down the entire language.

Thanks!

PDA Diagram

DJSunny
  • 1,970
  • 3
  • 19
  • 27
  • I know the X/Y refers to the stack, but can you remind me which side means push and which side means pop? – Nayuki Aug 10 '11 at 21:38
  • Sure! So a, a/aa would mean on input character a, we replace the top of the stack if its an 'a', with 'aa'. i.e. adds one 'a' to the stack. So its more of a 'top of stack/replace with' syntax. – DJSunny Aug 10 '11 at 21:40

3 Answers3

4

This PDA is not nearly as non-deterministic as it appears at first glance... Consider the following cases.

  1. Suppose the input starts with ab. Then we go to state 2 with an empty stack, so the "L" rule does not match, so we are only in state 2.

  2. Suppose the input starts with (a^n)b for n > 1. Then we go to state 2 with a^(n-1) on the stack, and the "L" rule triggers taking us back to state 1 with a^(n-2) on the stack. But since the stack in state 2 is a^(n-1) (and n>1), the loop-back arrows on state 2 cannot match... So here again, we are (effectively) only in one state: state 1.

  3. Suppose the input starts with ba. Then again we go to state 2 with an empty stack, and as in case (1), the "L" rule does not match so we are only in state 2.

  4. Finally, suppose the input starts with (b^n)a for n > 1. Then we go to state 2 with with b^n on the stack, so the "L" rule does not trigger and we are only in state 2.

In other words, any time the "L" rule creates a "fork" of the PDA into state 1, it only does so because "a" was on top of the stack... Which implies that the fork remaining in state 2 must die on the very next input symbol. So in effect there is no non-determinism here, and you can model this PDA as if it is always in just one state.

With this observation in hand, I think it is pretty easy to see that @Nayuki is correct: This PDA accepts any string with twice as many a's as b's.

First, show that when the PDA is in state 1, the stack always consists entirely of a's or entirely of b's (or is empty). And when the PDA is in state 2, the stack consists entirely of b's (or is empty). This is a simple case analysis similar to the four cases above; e.g. "state 1, stack=a^n, next character b => state 1, stack=a^(n-2)". (Taking care for the cases of n=0 or n=1.)

Think of each b as "wanting to be partnered with 2 as". State 1, stack=a^n means n as are waiting for partners. State 1, stack=b^n means n bs are waiting for partners. State 2, stack=b^n means one b was partnered with one a and n bs are still waiting for partners.

Prove that what I just wrote is true, and the result follows.

agf
  • 171,228
  • 44
  • 289
  • 238
Nemo
  • 70,042
  • 10
  • 116
  • 153
2

Playing with some test cases in my head and not proving anything rigorously, I think there exists an accepting computation for this (non-deterministic) PDA if and only if the input string has twice the number of a's compared to the number of b's.

Nayuki
  • 17,911
  • 6
  • 53
  • 80
  • Yeah that was my initial thought as well. I further narrowed it down to the fact that (possibly |2b| = |a|), as well as the fact that the string must end in an 'a'. (I was working on a few other guesses but they didn't pan out) – DJSunny Aug 10 '11 at 22:14
  • 1
    The string need not end in `a`. Consider the string `aab`: State 1, consume `a` push `a`, state 1, consume `a` push `a`, state 1, consume `b` pop `a`, state 2, consume L pop `a`, state 1, consume L and stack is empty, state 3. – Nayuki Aug 10 '11 at 22:24
  • I don't think the language is strictly all words such that there are twice the a's as b's. I.e. "bbaa". – DJSunny Aug 10 '11 at 22:51
  • Your stack is not empty at the end of `bbaa`, so you can't go to state 3. – Nayuki Aug 10 '11 at 23:07
  • Exactly, so it crashes on that input. So the language isn't "all strings with twice as many a's as b's", due to that counterexample. So its still some more restricted subset... – DJSunny Aug 10 '11 at 23:12
  • It doesn't crash on the input; there is just no accepting computation. What's wrong with "all strings with twice as many a's as b's"? `bbaa` doesn't have enough a's, don't you agree? – Nayuki Aug 11 '11 at 00:44
  • So the language we want is the language that is accepted by the PDA, i.e. results in the accepting state. So bbaa doesn't satisfy that. – DJSunny Aug 11 '11 at 01:22
  • Oh my bad I totally misread your post, yes I agree with you :). Sorry its been a long long day. – DJSunny Aug 11 '11 at 01:28
1

Number of 'a' is twice the number of 'b's.

Exact Grammar:

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

N_a(X) means Number of 'a's in X. etc.

At any point in time, the stack can either be all 'a's or all 'b's. Why? because, there are no transitions of a/xxbxx or b/xxaxx.

Case 1: Stack is all 'a's.

You can see cycle will be of the form:

  1. a(a*b)+ , if last we take the transition L,a/L in (2->1)

  2. a(a*b)+a, if last we take the transition a,Z0/Z0 in (2->1). and the last 'a' will not pop anything from stack.

in each cycle, the number of 'a's popped are two. and number of cycle is same as number of 'b' (except when a,Z0/Z0 occured at the last)

we'll take the last transition L,a/L iff number of 'a' is even before last 'b'

we'll take the last transition a,Z0/Z0 iff number of 'a' is odd before last 'b'. a,Z0/Z0 accepts one more 'a'

Thus,

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

This will reduce to:

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

(we'll be state 1, and stack empty)

Case 2: Stack is all 'b's.

Similarly, you can see that each cycle will be of the form: b*ab*a. and in each cycle, exactly one 'b' will be popped off. Whenever a 'b' is accepted, a 'b' is pushed onto the stack. Thus when the stack is empty, and we're back to state 1, number of times the cycle is taken is equal to number of 'b's we accepted/pushed onto stack.Thus,

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

But you can see, n = N_a(B)/2. Thus,

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

This will reduce to:

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

And since there are only two possible paths (A or B), and the cycle can be taken 0 or 1 times,

Thus,

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)

This will reduce to:

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

which will reduce to:

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

Q.E.D.

agf
  • 171,228
  • 44
  • 289
  • 238
  • When you use `+` in this context `B=b(b|a)+` what do you mean? Are you referring to the 1 or more times operator kind of like kleene star, or are you referring to a regular expression "or". The grammar is a mesh of CFG and Regex so I'm not totally clear on that. – DJSunny Aug 11 '11 at 01:25
  • Fixed. Regarding "bbaa": bbaa will take the transition ( a,b/b) and will reach state 1, and stack will have 'b' on top. So it can't take L,Z0/Z0 and reach accept state. Thus bbaa will not be accepted by the DPDA. Also, since N_a(bbaa)!=2*N_b(bbaa), it doesn't contradict Nayuki's solution as well. So Nayuki is right. ( I'm not able to comment under his answer) – Deepak Ravi Aug 11 '11 at 01:30
  • + => one or more like Kleene plus. – Deepak Ravi Aug 11 '11 at 01:31
  • What about `aaabba`? 4 a's, 2 b's, no transition on the second b. – DJSunny Aug 11 '11 at 01:36
  • at second 'b', stack will have two 'a's, and is in state '2' right? From there, it'll take L,a/L transition, and move to state '1'. and then it'll take: b,a/L. Got it? After that it'll a,Z0/Z0 to reach state 1, and then to state 3. – Deepak Ravi Aug 11 '11 at 01:52
  • So I was/am under the impression that the transition `L, a/L` can only be taken when there is no remaining input (i.e. that first `L` represents the empty string is left in terms of a character being eaten). I do see you're point that if we can interpret it as "choose not to eat a character of input, and transition". – DJSunny Aug 11 '11 at 01:57
  • @csjohn: Yes, that is what the empty string means; do not consume any input, but transition. And this rule is "non-deterministic"; any time an epsilon transition occurs it "forks" the PDA (including the stack) into two copies of itself. – Nemo Aug 11 '11 at 02:12
  • L,x/y has a semantics similar to L(epsilon) transition in NFA. You have multiple possible transitions and if _any_ of the transitions can get you to final state, then you accept the string (Nondeterministic). Can you try writing a simple DPDA for wcw and a simple NPDA for ww? You'll see L,a/a transitions for NPDA :-) – Deepak Ravi Aug 11 '11 at 02:28
  • No need :P I totally understand the nondeterminism, it was an issue with the notation while running some examples. Now that I've been slapped in the face with the correction its very obvious. Merci! – DJSunny Aug 11 '11 at 02:33