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.
| state | input | stack | rightarrow.gif | state | stack |
| q_0 | a | Z_0 | | q_0 | aZ_0 |
| q_0 | a | a | | q_0 | aa |
| q_0 | b | a | | q_1 | Lambda.gif |
| q_1 | b | a | | q_1 | Lambda.gif |
| q_1 | a | a | | q_1 | Lambda.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.