Ilovepdf Merged 8
Ilovepdf Merged 8
Theory Of Computation
(3164203)
B.E. Semester 6
(Artificial Intelligence & Machine Learning)
2
Theory of Computation (3164203) Enrollment no:230280152068
CERTIFICATE
Place: ____________________
Date: _____________________
3
Theory of Computation (3164203) Enrollment no:230280152068
4
Theory of Computation (3164203) Enrollment no:230280152068
DTE’s Vision
Institute’s Vision
Institute’s Mission
• To impart affordable and quality education in order to meet the needs of industries and achieve
excellence in teaching-learning process.
• To create a conducive research ambience that drives innovation and nurtures scholars and
outstanding professionals.
• To collaborate with other academic & research institutes as well as industries in order to strengthen
education and multidisciplinary research.
• To promote equitable and harmonious growth of students, academicians, staff, society and
industries, thereby becoming a centre of excellence in technical education.
• To practice and encourage high standards of professional ethics, transparency and accountability.
Department’s Vision
Department’s Mission
• To produce graduates according to the needs of industry, government, society and scientific
community. To develop partnership with industries, research and development organizations and
government sectors for continuous improvement of faculties and students.
• To motivate students for participating in reputed conferences, workshops, seminars and technical
events to make them technocrats and entrepreneurs.
• To enhance the ability of students to address the real-life issues by applying technical expertise,
human values and professional ethics.
• To inculcate habit of using free and open-source software, latest technology and soft skills so that
they become competent professionals.
• To encourage faculty members to upgrade their skills and qualification through training and higher
studies at reputed universities
5
Theory of Computation (3164203) Enrollment no:230280152068
6
Theory of Computation (3164203) Enrollment no:230280152068
INDEX
(Progressive Assessment Sheet)
Asses Sign of
Date of Date of sment
Sr. Objective(s) of Experiment Page Teach Rem
Perfor Submis Mark
No. No. er arks
mance sion s
TOTAL
7
Theory of Computation (3164203) Enrollment no:230280152068
8
Theory of Computation (3164203) Enrollment No:230280152068
Objective : Implement a Python script to check if a given string matches a regular expression.
import re
pattern = r"1(0+1)*0$"
print("Target Pattern:", pattern)
print("Target Pattern:", pattern)
while True:
user_input = input("Enter a string to check: ").strip()
if user_input.lower() == "exit":
print("Exiting program")
break
if [Link](pattern, user_input):
print("SUCCESS!", user_input, "belongs to the language.")
else:
print("REJECTED!", user_input, "does not belong to the language.")
print("-" * 30)
9
Theory of Computation (3164203) Enrollment No:230280152068
10
Theory of Computation (3164203) Enrollment No:230280152068
def dfa_divisible_by_3(binary_string):
transition = {
0: {'0': 0, '1': 1},
1: {'0': 2, '1': 0},
2: {'0': 1, '1': 2}
}
state = 0
if state == 0:
return "Accepted"
else:
return "Rejected"
while True:
binary_input = input("\nEnter binary string: ")
if binary_input.lower() == "exit":
print("Program stopped.")
break
result = dfa_divisible_by_3(binary_input)
print(result)
11
Theory of Computation (3164203) Enrollment No:230280152068
12
Theory of Computation (3164203) Enrollment No:230280152068
dfa_states = []
dfa_transitions = {}
dfa_final_states = []
start = frozenset([start_state])
dfa_states.append(start)
unprocessed = [start]
while unprocessed:
current = [Link]()
dfa_transitions[current] = {}
next_state = frozenset(next_state)
dfa_transitions[current][symbol] = next_state
print("\nDFA States:")
for state in dfa_states:
print(set(state))
print("\nDFA Transitions:")
for state in dfa_transitions:
for symbol in alphabet:
print(f"{set(state)} --{symbol}--> {set(dfa_transitions[state][symbol])}")
13
Theory of Computation (3164203) Enrollment No:230280152068
Enter NFA states : q0,q1,q2
Enter alphabet symbols : 0,1
Enter number of transitions: 3
Enter transitions in format: state symbol next_states
q0 0 q0,q1
q0 1 q0
q1 0 q2
Enter start state: q0
Enter final states : q2
DFA States:
{'q0'}
{'q0', 'q1'}
{'q0', 'q1', 'q2'}
DFA Transitions:
{'q0'} --0--> {'q0', 'q1'}
{'q0'} --1--> {'q0'}
{'q0', 'q1'} --0--> {'q0', 'q1', 'q2'}
{'q0', 'q1'} --1--> {'q0'}
{'q0', 'q1', 'q2'} --0--> {'q0', 'q1', 'q2'}
{'q0', 'q1', 'q2'} --1--> {'q0'}
14
Theory of Computation (3164203) Enrollment No:230280152068
Objective: Implement a Python program that minimizes a given Deterministic Finite Automaton (DFA)
while True:
new_P = []
for group in P:
partition_map = {}
for i, p in enumerate(P):
if next_state in p:
[Link](i)
break
signature = tuple(signature)
partition_map[signature].append(state)
if new_P == P:
break
P = new_P
state_map = {}
for i, group in enumerate(P):
for state in group:
state_map[state] = f"Q{i}"
new_states = set(state_map.values())
new_start = state_map[start_state]
new_finals = {state_map[s] for s in final_states}
new_transitions = {}
for group in P:
rep = list(group)[0]
new_state = state_map[rep]
new_transitions[new_state] = {}
print("\nTransitions:")
for state in new_transitions:
for symbol in alphabet:
print(f"δ({state}, {symbol}) → {new_transitions[state][symbol]}")
# States
states = input("Enter states (comma separated): ").split(',')
# Alphabet
alphabet = input("Enter alphabet symbols (comma separated): ").split(',')
15
Theory of Computation (3164203) Enrollment No:230280152068
print("\nEnter transitions:")
transitions = {}
Enter transitions:
δ(A,0) = B
δ(A,1) = C
δ(B,0) = A
δ(B,1) = D
δ(C,0) = D
δ(C,1) = A
δ(D,0) = C
δ(D,1) = B
Transitions:
δ(Q0, 0) → Q3
δ(Q0, 1) → Q1
δ(Q1, 0) → Q2
δ(Q1, 1) → Q0
δ(Q2, 0) → Q1
δ(Q2, 1) → Q3
δ(Q3, 0) → Q0
δ(Q3, 1) → Q2
16
Theory of Computation (3164203) Enrollment No:230280152068
Objective: Implement a Python program to check if a given string belongs to a regular language using the Pumping Lemma.
import re
if not in_language(word):
return "Error: The initial word you entered is not even in the chosen language!"
# Split the word into parts xyz such that |y| > 0 and |xy| <= p.
for i in range(p): # 'i' is the end index of x (length of x)
for j in range(i + 1, p + 1): # 'j' is the end index of y
x = word[:i]
y = word[i:j]
z = word[j:]
valid_split = True
for k in range(6): # Test pumping y from 0 to 5 times
pumped_word = x + (y * k) + z
if not in_language(pumped_word):
print(f"Failed split: x='{x}', y='{y}', z='{z}'. Pumped {k} times -> '{pumped_word}' (NOT in
valid_split = False
break
# If a split survives all pumps, the language passes the lemma for this specific word
if valid_split:
print(f"Successful split: x='{x}', y='{y}', z='{z}'. All pumped variations stay in the language."
return "\nResult: Valid pumping split found! The language satisfies the pumping lemma for this wo
def is_an_bn(s):
"""Returns True if the string is exactly a^n b^n"""
n = len(s)
if n % 2 != 0:
return False
half = n // 2
return s[:half] == 'a' * half and s[half:] == 'b' * half
def main():
print("=== Pumping Lemma Interactive Checker ===")
if choice == '1':
lang_func = is_an_bn
lang_desc = "a^n b^n"
elif choice == '2':
lang_func = lambda s: bool([Link](r'a*b*', s))
lang_desc = "a* b*"
elif choice == '3':
user_regex = input("Enter your custom Python regex (e.g., a+b+c): ").strip()
try:
[Link](user_regex) # Validate regex
lang_func = lambda s: bool([Link](user_regex, s))
17
Theory of Computation (3164203) Enrollment No:230280152068
lang_desc = f"Regex: {user_regex}"
except [Link]:
print("Invalid Regular Expression.")
return
else:
print("Invalid choice. Exiting.")
return
try:
p = int(input("Enter the pumping length (p): ").strip())
except ValueError:
print("Pumping length must be an integer. Exiting.")
return
if __name__ == "__main__":
main()
Result: Valid pumping split found! The language satisfies the pumping lemma for this word.
18
Theory of Computation (3164203) Enrollment No:230280152068
Objective: Implement a Moore Machine that produces outputs based only on the current state.
class MooreMachine:
def __init__(self, states, alphabet, transitions, outputs, initial_state):
# Step 1: Define the Moore Machine
[Link] = states
[Link] = alphabet
[Link] = transitions
[Link] = outputs
self.initial_state = initial_state
# Step 4: Append the output corresponding to the current state before moving
output_sequence.append([Link][current_state])
# Step 6: Append the output of the final state after processing all symbols
[Link](current_state)
output_sequence.append([Link][current_state])
def main():
print("=== Interactive Moore Machine Simulator ===")
print("Select a Moore Machine to test:")
print("1. Machine A: Outputs '1' whenever the sequence ends with '10' (Alphabet: 0, 1)")
print("2. Machine B: Counts number of 'a's modulo 3 (Outputs 0, 1, or 2) (Alphabet: a, b)")
if choice == '1':
# Machine A: Detects sequence "10"
states = ['q0', 'q1', 'q2']
alphabet = ['0', '1']
initial_state = 'q0'
outputs = {'q0': '0', 'q1': '0', 'q2': '1'}
transitions = {
'q0': {'0': 'q0', '1': 'q1'},
'q1': {'0': 'q2', '1': 'q1'},
'q2': {'0': 'q0', '1': 'q1'}
}
machine = MooreMachine(states, alphabet, transitions, outputs, initial_state)
print("\n[Loaded Machine A: Sequence '10' detector]")
19
Theory of Computation (3164203) Enrollment No:230280152068
machine = MooreMachine(states, alphabet, transitions, outputs, initial_state)
print("\n[Loaded Machine B: 'a' Modulo 3 counter]")
else:
print("Invalid choice. Exiting.")
return
if status != "Success":
print(status)
return
if __name__ == "__main__":
main()
20
Theory of Computation (3164203) Enrollment No:230280152068
Objective: Implement a Mealy Machine that produces outputs based on the current state and input symbol.
class MealyMachine:
def __init__(self, states, input_alphabet, output_alphabet, transitions, outputs, initial_state):
# Define the Mealy Machine
[Link] = states
self.input_alphabet = input_alphabet
self.output_alphabet = output_alphabet
[Link] = transitions
[Link] = outputs
self.initial_state = initial_state
[Link](current_state)
def main():
print("=== Interactive Mealy Machine Simulator ===")
print("Select a Mealy Machine to test:")
print("1. Machine A: 1's Complement Generator (Flips 0s to 1s and 1s to 0s)")
print("2. Machine B: '101' Sequence Detector (Outputs 'Y' when '101' is found, else 'N')")
if choice == '1':
states = ['q0']
input_alphabet = ['0', '1']
output_alphabet = ['0', '1']
initial_state = 'q0'
transitions = {
'q0': {'0': 'q0', '1': 'q0'}
}
outputs = {
'q0': {'0': '1', '1': '0'} # If input is 0 output 1, if input is 1 output 0
}
21
Theory of Computation (3164203) Enrollment No:230280152068
transitions = {
'q0': {'0': 'q0', '1': 'q1'},
'q1': {'0': 'q2', '1': 'q1'},
'q2': {'0': 'q0', '1': 'q1'}
}
# Output is 'Y' ONLY when in state q2 (saw "10") and input is '1' (completing "101")
outputs = {
'q0': {'0': 'N', '1': 'N'},
'q1': {'0': 'N', '1': 'N'},
'q2': {'0': 'N', '1': 'Y'}
}
else:
print("Invalid choice. Exiting.")
return
if status != "Success":
print(status)
return
if __name__ == "__main__":
main()
22
Theory of Computation (3164203) Enrollment No:230280152068
Objective: Implement a parser for a simple arithmetic expression using Context- Free Grammar (CFG).
import re
class RecursiveDescentParser:
def __init__(self, expression):
# Lexer Step: Tokenize the input string
token_pattern = r'\d+|\+|\-|\*|\/|\(|\)'
# Remove spaces and extract tokens
[Link] = [Link](token_pattern, [Link](' ', ''))
[Link] = 0
self.current_token = [Link][[Link]] if [Link] else None
def advance(self):
"""Moves to the next token in the input."""
[Link] += 1
if [Link] < len([Link]):
self.current_token = [Link][[Link]]
else:
self.current_token = None
def parse(self):
"""Starts parsing and checks if the entire expression is valid."""
if not [Link]:
return False, "Empty expression"
try:
[Link]()
except Exception as e:
return False, f"Invalid: {str(e)}"
def expr(self):
"""Rule 1: E -> T ((+ | -) T)*"""
[Link]()
while self.current_token in ('+', '-'):
[Link]()
[Link]()
def term(self):
"""Rule 2: T -> F ((* | /) F)*"""
[Link]()
while self.current_token in ('*', '/'):
[Link]()
[Link]()
def factor(self):
"""Rule 3: F -> Number | ( E )"""
if self.current_token is None:
raise Exception("Unexpected end of expression.")
if self.current_token.isdigit():
[Link]()
if self.current_token == ')':
[Link]()
else:
raise Exception("Missing closing parenthesis ')'.")
else:
raise Exception(f"Syntax error near '{self.current_token}'. Expected a number or '('.")
23
Theory of Computation (3164203) Enrollment No:230280152068
def show_grammar():
print("\n--- Context-Free Grammar (CFG) Rules ---")
print("This parser uses the following rules to avoid left-recursion:")
print("1. Expression (E) -> T (+ T | - T)*")
print("2. Term (T) -> F (* F | / F)*")
print("3. Factor (F) -> Number | ( E )")
print("----------------------------------------")
def main():
while True:
print("\n=== CFG Parser for Arithmetic Expressions ===")
print("1. Parse a mathematical expression")
print("2. View Context-Free Grammar (CFG) rules")
print("3. Exit")
if choice == '1':
user_expr = input("\nEnter an arithmetic expression (e.g., 3 + 5 * (2 - 8)): ")
print("-" * 50)
print(f"Parsing: '{user_expr}'")
parser = RecursiveDescentParser(user_expr)
is_valid, message = [Link]()
if is_valid:
print(f"Result: [SUCCESS] {message}")
else:
print(f"Result: [FAILED] {message}")
print("-" * 50)
else:
print("Invalid choice. Please enter 1, 2, or 3.")
if __name__ == "__main__":
main()
24
Theory of Computation (3164203) Enrollment No:230280152068
Objective: Implement a Python program that converts a given Context-Free Grammar (CFG) into Chomsky Normal Form (CNF).
import itertools
def is_terminal(symbol):
print(f"{lhs} -> {' | '.join(productions)}")
"""Assume lowercase letters are terminals, uppercase are Non-terminals."""
return [Link]()
nullables = set()
for lhs, rhs_list in new_grammar.items():
if ['e'] in rhs_list:
[Link](lhs)
new_grammar[lhs] = new_rhs
return new_grammar
while True:
unit_found = False
for lhs, rhs_list in list(new_grammar.items()):
for production in rhs_list:
# If production is exactly one Non-terminal (Unit production)
if len(production) == 1 and not is_terminal(production[0]):
unit_found = True
unit_var = production[0]
new_grammar[lhs].remove(production)
if unit_var in new_grammar:
for unit_prod in new_grammar[unit_var]:
if unit_prod not in new_grammar[lhs]:
new_grammar[lhs].append(unit_prod)
if not unit_found:
break
return new_grammar
25
Theory of Computation (3164203) Enrollment No:230280152068
for lhs, rhs_list in [Link]():
new_grammar[lhs] = []
for production in rhs_list:
current_lhs = lhs
current_prod = list(production)
# Create a rule for the first symbol and the new variable
new_grammar.setdefault(current_lhs, []).append([current_prod[0], new_var])
current_lhs = new_var
current_prod = current_prod[1:]
new_grammar.setdefault(current_lhs, []).append(current_prod)
return new_grammar
def convert_mixed_terminals(grammar):
new_grammar = {}
terminal_vars = {} # Maps 'a' -> 'Y_a'
return new_grammar
grammar_no_e = remove_epsilon_productions(initial_grammar)
print_grammar(grammar_no_e, "After Removing Epsilon Productions")
grammar_no_unit = remove_unit_productions(grammar_no_e)
print_grammar(grammar_no_unit, "After Removing Unit Productions")
grammar_no_long = remove_long_productions(grammar_no_unit)
print_grammar(grammar_no_long, "After Eliminating Long Productions (>2 symbols)")
final_cnf_grammar = convert_mixed_terminals(grammar_no_long)
print_grammar(final_cnf_grammar, "Final Chomsky Normal Form (CNF)")
27
Theory of Computation (3164203) Enrollment No:230280152068
28
Theory of Computation (3164203) Enrollment No:230280152068
Objective: Implement a Pushdown Automaton (PDA) to recognize the language {a^n b^n | n ≥ 1}.
def simulate_pda(input_string):
# Initialize PDA with start state and empty stack
stack = []
current_state = 'q0'
if not input_string:
print("Error: String is empty. Language requires n >= 1.")
return False
if symbol == 'a':
if current_state == 'q0':
[Link]('a')
else:
print(" -> REJECTED: Encountered 'a' after 'b's started.")
return False
if current_state == 'q0':
current_state = 'q1'
if current_state == 'q1':
# Pop 'a' from the stack for each 'b' encountered
if len(stack) > 0:
[Link]()
else:
print(" -> REJECTED: Stack underflow (More 'b's than 'a's).")
return False
else:
print(f" -> REJECTED: Invalid symbol '{symbol}' found.")
return False
if __name__ == "__main__":
# Take input string and loop until 'exit' is entered
user_string = ""
while user_string.lower() != 'exit':
user_string = input("Enter an input string (e.g., aaabbb): for exit enter 'exit'").strip()
if user_string.lower() == 'exit':
print("Exiting program.")
break
print("\n")
is_valid = simulate_pda(user_string)
print("-" * 45)
if is_valid:
print(f"FINAL RESULT: The string '{user_string}' is ACCEPTED.")
else:
print(f"FINAL RESULT: The string '{user_string}' is REJECTED.")
29
Theory of Computation (3164203) Enrollment No:230280152068
---------------------------------------------
State: q0 | Symbol: 'a' | Stack before: []
-> Stack after: ['a']
---------------------------------------------
FINAL RESULT: The string 'aaabbb' is ACCEPTED.
Enter an input string (e.g., aaabbb): for exit enter 'exit'aabbbb
30