0% found this document useful (0 votes)
6 views9 pages

DFA and Turing Machine Examples

The document discusses the theory of computation, focusing on constructing a DFA that accepts strings with an even number of 0s, proving that the language L = {an bn | n ≥ 0} is not regular using the Pumping Lemma, and designing a Turing Machine for the language L = {0n 1n | n ≥ 1}. It includes examples of DFA construction, Pumping Lemma proof, and Turing Machine design with detailed state transitions and traces. Additionally, it covers lexical analysis using regular expressions for tokens in a simplified programming language.

Uploaded by

webrbnb
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views9 pages

DFA and Turing Machine Examples

The document discusses the theory of computation, focusing on constructing a DFA that accepts strings with an even number of 0s, proving that the language L = {an bn | n ≥ 0} is not regular using the Pumping Lemma, and designing a Turing Machine for the language L = {0n 1n | n ≥ 1}. It includes examples of DFA construction, Pumping Lemma proof, and Turing Machine design with detailed state transitions and traces. Additionally, it covers lexical analysis using regular expressions for tokens in a simplified programming language.

Uploaded by

webrbnb
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

19/06/2025, 22:10 Google Gemini

1. Theory of Computation

Example 1.1: DFA Construction

Problem: Construct a DFA that accepts the language of all strings over Σ = {0, 1} that contain an
even number of 0s.

Solution:

We need to keep track of the parity of 0s encountered.


States (Q):
q0 : Represents having seen an even number of 0s (initial state).

q1 : Represents having seen an odd number of 0s.


Alphabet (Σ): {0, 1}


Start State (q0 ): q0 (since 0 zeros is an even number).
​ ​

Final States (F): F = {q0 } (strings with an even number of 0s are accepted).

Transition Function (δ ):
δ(q0 , 0) = q1 (If we are in an even-0s state and see a '0', we move to an odd-0s state).
​ ​

δ(q0 , 1) = q0 (If we are in an even-0s state and see a '1', the parity of 0s doesn't change,
​ ​

so we stay in the even-0s state).


δ(q1 , 0) = q0 (If we are in an odd-0s state and see a '0', we move to an even-0s state).
​ ​

δ(q1 , 1) = q1 (If we are in an odd-0s state and see a '1', the parity of 0s doesn't change,
​ ​

so we stay in the odd-0s state).

DFA Diagram:

+-----+
| | 1
+--| q0 |<--+ (Start and Accept State)
| +-----+ |
| | |
| 0 | | 0
+----->+-----+<--+
| q1 |
+-----+
| 1
+--+

Trace for "1010":


1. Start at q0 . ​

2. Input '1': δ(q0 , 1) ​


= q0 . ​

3. Input '0': δ(q0 , 0) ​ = q1 . ​

[Link] 1/9
19/06/2025, 22:10 Google Gemini

4. Input '1': δ(q1 , 1) ​ = q1 .​

5. Input '0': δ(q1 , 0) = q0 . End at q0 , which is an accept state. So, "1010" is accepted (it has two
​ ​ ​

0s, an even number).

Trace for "001":


1. Start at q0 . ​

2. Input '0': δ(q0 , 0) ​


= q1 .​

3. Input '0': δ(q1 , 0) ​ = q0 .​

4. Input '1': δ(q0 , 1) = q0 . End at q0 , which is an accept state. So, "001" is accepted (it has two
​ ​ ​

0s, an even number).

Trace for "010":


1. Start at q0 . ​

2. Input '0': δ(q0 , 0) ​


= q1 .​

3. Input '1': δ(q1 , 1) ​ = q1 .​

4. Input '0': δ(q1 , 0) = q0 . End at q0 , which is an accept state. So, "010" is accepted (it has two
​ ​ ​

0s, an even number).

Example 1.2: Pumping Lemma Proof

Problem: Prove that the language L = {an bn ∣ n ≥ 0} is not regular using the Pumping Lemma.
Solution:

Proof by Contradiction:
1. Assume L is Regular: Assume, for the sake of contradiction, that L is a regular language.
2. Apply Pumping Lemma: By the Pumping Lemma for regular languages, there exists a
pumping length p ≥ 1 such that any string s ∈ L with ∣s∣ ≥ p can be divided into three parts
s = xyz satisfying the following conditions:
i) ∣y∣ > 0 (The middle part y is non-empty).
ii) ∣xy∣ ≤ p (The combined length of x and y is at most p).
iii) For all i ≥ 0, the string xy i z is also in L.
3. Choose a String: Let's choose a string s ∈ L that is long enough, specifically s = ap bp .
This string s has length ∣s∣ = 2p, which is clearly ≥ p.
Since s ∈ L, it consists of p 'a's followed by p 'b's.
4. Analyze the Division s = xyz :
According to condition (ii), ∣xy∣ ≤ p. Since the string s starts with p 'a's, the substring xy
must consist entirely of 'a's.
This implies that x consists only of 'a's, and y consists only of 'a's. So, y = ak for some
integer k .
According to condition (i), ∣y∣ > 0, so k > 0.
[Link] 2/9
19/06/2025, 22:10 Google Gemini

Since y contains only 'a's, z must contain the remaining 'a's and all the 'b's. So, s =
xak z = ap bp .
5. Pump the String (i = 2):
Now, consider the string s′ = xy 2 z .
s′ = x(ak )(ak )z = xa2k z .
Since s = xak z = ap bp , and y = ak , when we replace y with y 2 , we are effectively adding
another k 'a's to the string.

The new string s′ will have p + k 'a's and p 'b's. (i.e., s′ = ap+k bp ).
Because k > 0, we have p + k = p.
6. Contradiction:
The language L = {an bn ∣ n ≥ 0} requires the number of 'a's to be equal to the number
of 'b's.
However, our pumped string s′ = ap+k bp has p + k 'a's and p 'b's. Since k > 0, p + k = p.
Therefore, s′ ∈/ L.
This contradicts condition (iii) of the Pumping Lemma, which states that xy i z must be in L
for all i ≥ 0.
7. Conclusion: Our initial assumption that L is regular must be false. Therefore, L = {an bn ∣
n ≥ 0} is not a regular language.

Example 1.3: Turing Machine Design

Problem: Design a Turing Machine that accepts the language L = {0n 1n ∣ n ≥ 1} over Σ =
{0, 1}.
(This means strings like "01", "0011", "000111" are accepted).

Solution:

Tape Alphabet (Γ): {0, 1, X, Y , ⊔} (where X, Y are marking symbols, ⊔ is blank).


States (Q): q0 , q1 , q2 , q3 , qaccept , qreject (implicitly, any configuration not leading to qaccept or qreject
​ ​ ​ ​ ​ ​ ​ ​

is a reject state due to non-halting).


Start State (q0 ): ​

Logic:
The TM will work by matching a '0' with a '1'.
1. Scan for the leftmost '0'. Mark it as 'X'.
2. Scan right for the leftmost '1'. Mark it as 'Y'.
3. If a match is found, go back to the beginning to repeat.
4. If all '0's are matched with '1's, verify no extra '1's or '0's.

Transition Function (δ ):
A transition is of the form: (CurrentState, ReadSymbol) →
(N extState, W riteSymbol, M oveDirection)
q0 (Initial state, look for leftmost '0'):

[Link] 3/9
19/06/2025, 22:10 Google Gemini

δ(q0 , 0) → (q1 , X, R) : Found a '0', mark it 'X', move right to find a '1'.
​ ​

δ(q0 , Y ) → (q3 , Y , R) : All '0's processed, now scan past 'Y's to check for remaining '1's
​ ​

(should be none).
δ(q0 , ⊔) → (qreject , ⊔, R) : Empty string or string starting with '1' (n=0 not accepted by
​ ​

problem, must be n >= 1). (Alternatively, we could set qaccept for empty string if n ≥ 0 was

allowed.)
δ(q0 , 1) → (qreject , 1, R) : String starts with '1' but no '0's.
​ ​

q1 (Scan right to find '1' to match the '0'):


δ(q1 , 0) → (q1 , 0, R) : Skip '0's.


​ ​

δ(q1 , Y ) → (q1 , Y , R) : Skip 'Y's (already matched '1's).


​ ​

δ(q1 , 1) → (q2 , Y , L) : Found a '1', mark it 'Y', move left to find the next '0'.
​ ​

δ(q1 , ⊔) → (qreject , ⊔, L) : Ran out of 1s to match the 0s.


​ ​

q2 (Scan left to find the next 'X' or beginning):


δ(q2 , X) → (q0 , X, R) : Found the marked '0', move right to q0 to find the next available
​ ​ ​

'0'.
δ(q2 , 0) → (q2 , 0, L) : Skip '0's.
​ ​

δ(q2 , Y ) → (q2 , Y , L) : Skip 'Y's.


​ ​

δ(q2 , ⊔) → (q2 , ⊔, L) : Reached the beginning of the tape. (Could also just transition to
​ ​

q0 from X ).

q3 (All '0's matched, check if all '1's are also matched):


δ(q3 , Y ) → (q3 , Y , R) : Skip 'Y's (matched '1's).


​ ​

δ(q3 , ⊔) → (qaccept , ⊔, R) : All '0's matched with '1's, and no extra '1's remaining. Accept.
​ ​

δ(q3 , 1) → (qreject , 1, R) : Extra '1's remaining (e.g., "011"). Reject.


​ ​

Trace for "0011":


1. (q0 , 0011⊔)
​ ​

2. δ(q0 , 0) → (q1 , X, R)
​ ​

3. (q1 , X 011⊔)
​ ​

4. δ(q1 , 0) → (q1 , 0, R)
​ ​

5. (q1 , X011⊔)
​ ​

6. δ(q1 , 1) → (q2 , Y , L)
​ ​

7. (q2 , X 0Y 1⊔)
​ ​

8. δ(q2 , 0) → (q2 , 0, L)
​ ​

9. (q2 , X 0Y 1⊔)
​ ​

10. δ(q2 , X) → (q0 , X, R)


​ ​

11. (q0 , X 0Y 1⊔) (Loop back to q0 to find the next '0')


​ ​ ​

[Link] 4/9
19/06/2025, 22:10 Google Gemini

12. δ(q0 , 0) → (q1 , X, R)


​ ​

13. (q1 , XX Y 1⊔)


​ ​

14. δ(q1 , Y ) → (q1 , Y , R)


​ ​

15. (q1 , XXY 1⊔)


​ ​

16. δ(q1 , 1) → (q2 , Y , L)


​ ​

17. (q2 , XX Y Y ⊔)
​ ​

18. δ(q2 , Y ) → (q2 , Y , L)


​ ​

19. (q2 , X X YY ⊔)
​ ​

20. δ(q2 , X) → (q0 , X, R)


​ ​

21. (q0 , XX Y Y ⊔) (All 0s are marked 'X')


​ ​

22. δ(q0 , Y ) → (q3 , Y , R) (Transition to state q3 to check for extra 1s)


​ ​ ​

23. (q3 , XXY Y ⊔)


​ ​

24. δ(q3 , Y ) → (q3 , Y , R)


​ ​

25. (q3 , XXYY ⊔)


​ ​

26. δ(q3 , ⊔) → (qaccept , ⊔, R) ACCEPT


​ ​

2. Compiler Design

Example 2.1: Lexical Analysis using Regular Expressions


Problem: Define regular expressions for the following tokens in a simplified programming language
and show how a lexer would tokenize the input if (count <= 100) { .

Tokens:
KEYWORD (e.g., if , else , while , int )

IDENTIFIER (starts with letter or underscore, followed by letters, digits, or underscores)

INTEGER_LITERAL (sequence of digits)

RELOP (relational operators: <= , >= , == , != , < , > )

LPAREN ( ( )
RPAREN ( ) )

LBRACE ( { )

RBRACE ( } )

Solution:

Regular Expressions:
KEYWORD : if | else | while | int

IDENTIFIER : [a-zA-Z_][a-zA-Z0-9_]*
INTEGER_LITERAL : [0-9]+
[Link] 5/9
19/06/2025, 22:10 Google Gemini

RELOP : <= | >= | == | != | < | >

LPAREN : \( (Backslash escapes the parenthesis as it's a special character in regex)

RPAREN : \)
LBRACE : \{

RBRACE : \}

WHITESPACE : [ \t\n\r]+ (to be ignored by the lexer)

Tokenization of if (count <= 100) { :

The lexer scans the input character by character, attempting to match the longest possible prefix of
the input with one of the defined regular expressions.
1. Input: if (count <= 100) {
The lexer reads i . It could be part of an IDENTIFIER or if .
It reads f . Now it's if . This matches the KEYWORD pattern.
Since if is a full keyword, it's recognized.
Token: ( KEYWORD , "if")
Remaining Input: (count <= 100) {
2. Input: (count <= 100) {
The lexer reads a space. This matches WHITESPACE . It's typically ignored.
Remaining Input: (count <= 100) {
3. Input: (count <= 100) {
The lexer reads ( . This matches LPAREN .
Token: ( LPAREN , "(")
Remaining Input: count <= 100) {
4. Input: count <= 100) {
The lexer reads c . Could be IDENTIFIER .
Reads o , u , n , t . count matches IDENTIFIER .
Token: ( IDENTIFIER , "count")
Remaining Input: <= 100) {
5. Input: <= 100) {
Reads a space (whitespace, ignored).
Reads <= . This matches RELOP . It's the longest match for < followed by = .
Token: ( RELOP , "<=")
Remaining Input: 100) {
6. Input: 100) {
Reads a space (whitespace, ignored).
Reads 1 . Could be INTEGER_LITERAL .
Reads 0 . 10 .
Reads 0 . 100 . This matches INTEGER_LITERAL .

[Link] 6/9
19/06/2025, 22:10 Google Gemini

Token: ( INTEGER_LITERAL , "100")


Remaining Input: ) {
7. Input: ) {
Reads ) . This matches RPAREN .
Token: ( RPAREN , ")")
Remaining Input: {
8. Input: {
Reads a space (whitespace, ignored).
Reads { . This matches LBRACE .
Token: ( LBRACE , "{")
Remaining Input: `` (End of input)

Final Token Stream:


( KEYWORD , "if")
( LPAREN , "(")
( IDENTIFIER , "count")
( RELOP , "<=")
( INTEGER_LITERAL , "100")
( RPAREN , ")")
( LBRACE , "{")

Example 2.2: Parsing with a CFG (Parse Tree)


Problem: Given the following Context-Free Grammar for simple arithmetic expressions:

E →E+T ∣ T
T → T ∗F ∣ F
F → (E) ∣ id
Draw the parse tree for the input string id + id * id .

Solution:

We perform a leftmost derivation and construct the parse tree simultaneously.

Derivation Steps:
1. E (Start symbol)
2. ⇒ E + T (Using production E → E + T )
3. ⇒ T + T (Using production E → T )
4. ⇒ id + T (Using production T → F , then F → id)
5. ⇒ id + T ∗ F (Using production T → T ∗ F )
6. ⇒ id + id ∗ F (Using production T → F , then F → id)
7. ⇒ id + id ∗ id (Using production F → id)
[Link] 7/9
19/06/2025, 22:10 Google Gemini

Parse Tree:

E
/|\
E + T
/ /|\
T T * F
| | |
F F id
| |
id id

Explanation:
The parse tree visually represents the derivation.
The root is the start symbol E .
Each internal node is a non-terminal, and its children correspond to a production rule applied
to that non-terminal. For example, E expands to E + T .
The leaves of the tree, read from left to right, form the input string id + id * id .

This parse tree correctly shows the precedence of multiplication over addition, as id * id forms a
T first, before being combined with the + id .

Example 2.3: Intermediate Code Generation (Three-Address Code)


Problem: Generate three-address code (TAC) for the following C-like statement:

result = (a + b) * (c - d) / 2;

Solution:

Three-address code statements typically have the form x = y op z , where op is an operator,


and x, y, z are operands. Temporaries (e.g., t1, t2 ) are introduced for intermediate results.

1. a + b : This is the first sub-expression.


t1 = a + b

2. c - d : This is the second sub-expression.


t2 = c - d
3. (a + b) * (c - d) : Now multiply the results of the previous two operations.
t3 = t1 * t2
4. ... / 2 : Finally, divide the result by 2.
t4 = t3 / 2
5. result = ... : Assign the final result to the result variable.
result = t4

Complete Three-Address Code:

[Link] 8/9
19/06/2025, 22:10 Google Gemini

t1 = a + b
t2 = c - d
t3 = t1 * t2
t4 = t3 / 2
result = t4

[Link] 9/9

You might also like