Skip to main content

12. Write a program to convert NFA to DFA.



Converting a Non-Deterministic Finite Automaton (NFA) to a Deterministic Finite Automaton (DFA) involves creating a new DFA where each state corresponds to a set of NFA states reachable under certain conditions. Below is a simple Python program to perform this conversion. I'll explain each line of code:


```python

from collections import defaultdict


def epsilon_closure(states, transitions, epsilon):

    closure = set(states)

    stack = list(states)

    

    while stack:

        state = stack.pop()

        for next_state in transitions[state].get(epsilon, []):

            if next_state not in closure:

                closure.add(next_state)

                stack.append(next_state)

    

    return closure


def nfa_to_dfa(nfa_states, nfa_transitions, alphabet, start_state, nfa_final_states):

    dfa_states = []

    dfa_transitions = defaultdict(dict)

    dfa_start_state = epsilon_closure({start_state}, nfa_transitions, 'epsilon')

    dfa_states.append(dfa_start_state)

    stack = [dfa_start_state]

    

    while stack:

        current_state = stack.pop()

        

        for symbol in alphabet:

            next_states = set()

            for nfa_state in current_state:

                next_states.update(nfa_transitions[nfa_state].get(symbol, []))

            

            epsilon_closures = epsilon_closure(next_states, nfa_transitions, 'epsilon')

            

            if epsilon_closures not in dfa_states:

                dfa_states.append(epsilon_closures)

                stack.append(epsilon_closures)

            

            dfa_transitions[current_state][symbol] = epsilon_closures

    

    dfa_final_states = [state for state in dfa_states if any(nfa_final in state for nfa_final in nfa_final_states)]

    

    return dfa_states, dfa_transitions, dfa_start_state, dfa_final_states


# Example NFA

nfa_states = {'q0', 'q1', 'q2'}

nfa_alphabet = {'0', '1'}

nfa_transitions = {

    'q0': {'epsilon': {'q1'}},

    'q1': {'0': {'q1'}, 'epsilon': {'q2'}},

    'q2': {'1': {'q2'}}

}

nfa_start_state = 'q0'

nfa_final_states = {'q2'}


# Convert NFA to DFA

dfa_states, dfa_transitions, dfa_start_state, dfa_final_states = nfa_to_dfa(

    nfa_states, nfa_transitions, nfa_alphabet, nfa_start_state, nfa_final_states

)


# Print DFA states and transitions

print("DFA States:", dfa_states)

print("DFA Transitions:", dfa_transitions)

print("DFA Start State:", dfa_start_state)

print("DFA Final States:", dfa_final_states)

```


**Explanation of the Code**:


1. Import the `defaultdict` class to create dictionaries with default values for non-existent keys.


2. Define a function `epsilon_closure(states, transitions, epsilon)` that calculates the ε-closure of a set of states in the NFA. It uses a stack-based approach to explore states reachable via ε-transitions.


3. Define a function `nfa_to_dfa(nfa_states, nfa_transitions, alphabet, start_state, nfa_final_states)` that converts an NFA to a DFA. It initializes the DFA's start state as the ε-closure of the NFA's start state.


4. The function uses a stack to iterate through DFA states and construct transitions.


5. Iterate over each symbol in the alphabet. For each symbol, calculate the ε-closure of states reachable via symbol transitions from the current DFA state.


6. If the calculated ε-closure is not already a DFA state, add it to the list of DFA states and the stack for further processing.


7. Identify DFA final states by checking if any NFA final state is included in the calculated DFA state.


8. An example NFA is defined with states, alphabet, transitions, start state, and final states.


9. The `nfa_to_dfa` function is called with the example NFA information to convert the NFA to a DFA.


10. Finally, the resulting DFA states, transitions, start state, and final states are printed.


This program demonstrates the process of converting an NFA to a DFA using the ε-closure concept and subset construction. Please note that this is a simplified example and might require further refinement for more complex NFAs.


Comments

Popular posts from this blog

6. Generate a YACC specification to recognize a valid arithmetic expression that uses operators +, – , *,/ and parenthesis.

Below is a YACC specification for recognizing valid arithmetic expressions that involve operators (+, -, *, /) and parentheses. I'll explain each line of the code afterward: ```yacc %{ #include <stdio.h> %} %token NUMBER %left '+' '-' %left '*' '/' %% expression: expression '+' expression            | expression '-' expression            | expression '*' expression            | expression '/' expression            | '(' expression ')'            | NUMBER            ; %% int yylex() {     // Code for tokenizing input and returning tokens } void yyerror(const char *s) {     fprintf(stderr, "Error: %s\n", s); } int main() {     yyparse();     return 0; } ``` Now, let's break down the YACC specification line by line: 1. `%{` ... `%}`: This is the C code section where y...

ktu 2019 Cse Complier programing Lab Syllabus

 1Design and implement a lexical analyzer using C language to recognize all valid tokens  in the input program. The lexical analyzer should ignore redundant spaces, tabs and  newlines. It should also ignore comments. 2. Implement a Lexical Analyzer for a given program using Lex Tool. 3. Write a lex program to display the number of lines, words and characters in an input text. 4. Write a LEX Program to convert the substring abc to ABC from the given input string. 5. Write a lex program to find out the total number of vowels and consonants from the given  input string. 6. Generate a YACC specification to recognize a valid arithmetic expression that uses  operators +, – , *,/ and parenthesis. 7. Generate a YACC specification to recognize a valid identifier which starts with a letter  followed by any number of letters or digits.   8. Implementation of Calculator using LEX and YACC  9. Convert the BNF rules into YACC form and write code to generat...

1, Design and implement a lexical analyzer using C language to recognize all valid tokens in the input program. The lexical analyzer should ignore redundant spaces, tabs and newlines. It should also ignore comments

#include <stdio.h> #include <ctype.h> int main() {     char c;     while ((c = getchar()) != EOF) {         if (isspace(c)) {             // Ignore whitespace, tabs, and newlines             continue;         }         if (c == '/') {             // Check for comments             char nextChar = getchar();             if (nextChar == '/') {                 while ((nextChar = getchar()) != '\n');         ...