CS507 Spring 2003
Problem Set 2



5.11 Let L be the language of "balanced" strings of parentheses, i.e.
all strings that are the string of parentheses in legal algebraic expressions.
For example, Lambda.gif, ()(), and ((()())) are in L, and (() and ())(() are not.

Describe the equivalence classes of I_L.

1.0: they are [)] which includes all strings which are not prefixes of strings in L (this is basically a dead-state class) for each i in.gif naturals.gif, [(^i] which includes, strings such as ()(^^i+k^^^)^k (this is a "waiting for i )'s" class) most brief 1.0 answer: {[)], [(^i] | i in.gif naturals.gif } 0.75: something less formal, but correct 0.5: missed some essential point 0: bad syntax errors or major errors
5.30. Use the pumping lemma to show that each language is not regular: b. pal = {x in.gif {0,1}* | x is a palindrome }. c. L = { xy | x,y in.gif {0,1}* and y is either x or x^r}.
1.0: (b) Supppose pal is regular. Then exists.gif n satisfying the p.l. Consider x = 0^^n^^^10^n in.gif pal. The p.l. guarantees some u,v,w, s.t. x = uvw, |uv|<n, |v|>0, forall.gif i: uv^^i^^^w in.gif pal. So exists.gif k>0: v = 0^k, so uw is not in pal. This is a contradiction, so pal is not regular. (c) Supppose L is regular. Then exists.gif n satisfying the p.l. Consider x = 0^n 1 0^n 1 in.gif L. The p.l. guarantees some u,v,w, s.t. x = uvw, |uv|<n, |v|>0, forall.gif i: uv^^i^^^w in.gif L. So exists.gif k>0: v = 0^k, so uw is not in L. This is a contradiction, so L is not regular. 0.5-0.9: if you didn't say where n comes from. score depends on rest of the structure of the proof. you could get less if you chose x badly. note that 1.0 was often assigned to each part, but this was changed so that b&c together were worth 1.0.
6.1. In each case, say what language is generated by the grammar with the indicated productions: a. S rightarrow.gif aSa | bSb | Lambda.gif b. S rightarrow.gif aSa | bSb | a | b c. S rightarrow.gif aSa | bSb | A A rightarrow.gif aBb | bBa B rightarrow.gif aBa | bBb | a | b | Lambda.gif
1.0: (a) even palindromes, or {xx^r | x in.gif {a,b}*} (b) odd palindromes, or {xax^r, xbx^r | x in.gif {a,b}*} (c) non-palindromes with exactly one mistake,
or {xaybx^r, xbyax^r | x,y in.gif {a,b}*, y=y^r }
6.17a. Find a CFG generating {a^i b^j c^k | i = j+k }
1.0: S rightarrow.gif A | aSc A rightarrow.gif aAb | Lambda.gif no penalty for adding S rightarrow.gif Lambda.gif
7.5c. Give the transition table for a PDA recognizing {a^n x | n geq.gif 0, x in.gif {a,b}*, |x| leq.gif n }.
1.0: draw a diagram, or specify accepting states, specify transitions allowing acceptance of Lambda.gif, a, ab, and aab, etc. several machines will work, including one where there are two states, {q_0, q_1}, q_0 starting, {q_0,q_1} accepting.
stateinputstackrightarrow.gifstatestack
q_0aZ_0q_0aZ_0
q_0aaq_0aa
q_0baq_1Lambda.gif
q_1baq_1Lambda.gif
q_1aaq_1Lambda.gif
all other combinations are undefined
note that this machine only pushes a's on the stack, and only pops when a b in the input matches an a on the stack. the move to q_1 marks that a b has been seen in the input. the machine crashes without emptying its input if there are too many b's. 0.5: PROVISIONAL didn't specify accepting states. i will return 0.5 to you if you can specify them and the machine works. OR if your machine works by emptying the stack, and you say so. TAKE all appeals to the TA's. 0.5: at least one of the strings we tested is missing.
7.8. Show that if L is accepted by a PDA in which no symbols are ever removed from the stack, then L is regular.
1.0: The idea is to make NFA states 2-tuples which encode the PDA's state and top-of stack. Suppose PDA (Q,Sigma.gif,Gamma.gif,q_0,Gamma.gif_0,A,delta.gif). Construct NFA-Lambda.gif
(Q prod.gif Gamma.gif, Sigma.gif, (q_0,Z_0), A prod.gif Gamma.gif, delta.gif'), where
(((p,z),a),(q,func.gif(alpha.gif))) in.gif delta.gif' iff
((p,a,z),(q,alpha.gif)) in.gif delta.gif where func.gif returns the first character of a string: func.gif(s) = c for all s = cx, c in.gif Sigma.gif. Note that func.gif(Lambda.gif) need not be defined since the PDA does not pop. Since the PDA never removes symbols from the stack, there is a 1-1 correspondence between configurations for accepting computations.
7.11. Show that if L is accepted by a PDA, then L is accepted by a PDA that never crashes (i.e., the stack never empties and no configuration is reached from which there is no move defined).
Assume the PDA accepts by final state. There are two things to worry about: crashing by undefined transition, and crashing by empty stack. Suppose PDA (Q,Sigma.gif,Gamma.gif,q_0,Gamma.gif_0,A,delta.gif). First, make delta.gif a total function by adding a dead state: q_d. Second, add a new start state q_n which inserts a Z_1 under Z_0. For q_n, q_d, Z_1: q_n notin.gif Q, q_d notin.gif Q, Z_1 notin.gif Gamma.gif construct
(Q union.gif {q_d, q_n}, Sigma.gif, Gamma.gif union.gif {Z_1}, q_n, Gamma.gif_0, A, delta.gif') where delta.gif' = delta.gif union.gif
{ ((q_n,Lambda.gif,Z_0),(q_0,Z_0 Z_1)) } union.gif
{ ((q,a,c),(q_d,c)) | notexists.gif q,a,c: (q,a,c) in.gif delta.gif } union.gif
{ ((q,Lambda.gif,Z_1),(q_d,Z_1)) | q in.gif Q } union.gif
{ ((q_d,b,d),(q_d,d) | forall.gif b in.gif Sigma.gif, d in.gif Gamma.gif union.gif {Z_1} } Those additions are: the transition for q_n to q_0 which inserts Z_1, transitions to the dead state if no transition is defined, transitions to the dead state if a Z_1 shows up, and transitions from the dead state to itself on any input/stack combination.
7.15. Show that if L is accepted by a PDA then there is PDA accepting the language {x#y | x in.gif L and xy in.gif L, where x and y do not contain #}.
1.0: The easiest thing to do is to create a transition on # from any accepting state into a doppelgaenger machine's corresponding state. From there, the machine is allowed to continue from the configuration that it is in, to try to accept y. Only the doppelgaenger machine's accepting states are accepting. Note that the original PDA must accept by final state. Suppose PDA M = (Q,Sigma.gif,Gamma.gif,q_0,Gamma.gif_0,A,delta.gif). We may make a copy of M,
M' = (Q',Sigma.gif,Gamma.gif,q_0',Gamma.gif_0,A',delta.gif'). where Sigma.gif, Gamma.gif, and Gamma.gif_0 are unchanged,
but Q intersect.gif Q' = phi.gif and A intersect.gif A' = phi.gif,
and ((p,a,c),(q,alpha.gif)) in.gif delta.gif iff ((p',a,c),(q',alpha.gif)) in.gif delta.gif'. We construct M'' = (Q' union.gif Q, Sigma.gif, Gamma.gif, q_0, Gamma.gif_0, A', delta.gif'') where
delta.gif'' = delta.gif union.gif delta.gif' union.gif {((q,#,c),(q',c)) | forall.gif q in.gif A }. That is, delta.gif'' contains the transitions of both machines, and adds a transition on # to the corresponding state of M', from any accepting state in M. Since the configuration of the machine is unchanged (except for the priming of the state), any x#y in.gif L will be accepted by this machine iff x in.gif L and xy in.gif L, as required. 1.0: specifying the # transition as a NOP in the original machine, but doing it formally and correctly. 0.1-0.5: you did not understand the use of # and did something reasonable, or at least complained in a reasonable way.
7.23. Show that if L is accepted by a PDA, then L is accepted by a PDA in which there are at most two stack symbols in addition to Z_0.
1.0: Suppose PDA M = (Q,Sigma.gif,Gamma.gif,q_0,Gamma.gif_0,A,delta.gif). Encode Gamma.gif with two bits, 0 and 1, using k=integer(log_2(|Gamma.gif|)+1) bits for each symbol. Now, Gamma.gif' = {0,1}. The function e(g): Gamma.gif rightarrow.gif {0,1}^k returns the encoding, and let e(Z_0) = 0^k. Then Gamma.gif_0' = 0. Increase the number of states for the purposes of decoding the stack symbol, so that it can be read, and for encoding the resulting stack symbols, so that they can be written.
Q' = Q { {0,1}^i | i leq.gif k } Sigma.gif { {0,1}^i | i leq.gif km }, where m is the length of the longest string pushed in any transition. That means we are using strings as states, and encoding in the string the information we need to make the transition. So a state such as "q_0 010 a 101" will be used for a transition out of
q_0 on input symbol a, on original stack symbol e^^-1^^^(010), writing e^^-1^^^(101), and progressing towards possibly writing an additionll encoded stack symbol, and toward the next state. For any transition in delta.gif, ((p,a,c),(q,alpha.gif)), if e(c)=b_1 ... b_k, then there are transitions in delta.gif' to do the decoding:
((p,Lambda.gif,0),(p0,Lambda.gif))
((p,Lambda.gif,1),(p1,Lambda.gif))
forall.gif p in.gif Q' and the interesting sequence of states is p, p b_1, p b_1 b_2, ..., to p b_1 ... b_k. For alpha.gif in.gif {0,1}^k, there may be a transition in delta.gif' to pick up the input symbol, alpha.gif = b_1 ... b_k:
((palpha.gif,a,x),(palpha.gifa,x))
forall.gif p in.gif Q, x in.gif {0,1}. If delta.gif contains ((p,a,e^^-1^^^(alpha.gif)),(q,beta.gif)), then there is a transition. For some beta.gif in.gif {0,1}^k^m there will be a transition from
((palpha.gifabeta.gif, Lambda.gif, x),(q,x)) which will complete the transition to q (the pure state), after beta.gif has been written onto the stack. 1.0: if you just mentioned the binary encoding and suggested you would need a lot more states, and then showed you could say something formally, you got full credit.