Reputation: 15
I have been trying to draw this Non-Deterministic Finite automaton:
NFA with the number of states not exceeding 3 for the language {ab, abc}*, and I reached the solution in the picture below:
The issue seems to be the code logic since my code always prints "rejected. I will appreciate it if someone can give some hints on how to code this algorithm.
print("Insert below the string: ")
string = str(input())
def state_q0(string):
if len(string) == 0:
print("string not accepted")
else:
if string[0] == "a":
state_q1(string[1:])
elif string[0] == "b":
print("rejected")
def state_q1(string):
if len(string) == 0:
print("string not accepted")
else:
if string[1] == "b":
state_q2(string[2:])
else:
print("rejected")
def state_q2(string):
if len(string) == 0:
print("string not accepted")
else:
if string[2] == "c":
print("accepted -> q0")
elif string[2] == "b":
print("rejected")
state_q0(string)
Upvotes: 1
Views: 1361
Reputation: 117771
You should always look at the first character of the string, and call recursive calls using everything except the first character.
Also it's not noted in your diagram, but I assume that q0
is the accepting state since that corresponds to (ab + abc)*
.
So in your style (which I personally wouldn't use, but ok):
def q0(s):
if not s: return "accept" # Accepting state.
if s[0] == "a": return q1(s[1:])
return "reject"
def q1(s):
if not s: return "reject"
# NFA, must try both edges.
if (s[0] == "b" and q0(s[1:]) == "accept" or
s[0] == "b" and q2(s[1:]) == "accept"):
return "accept"
return "reject"
def q2(s):
if not s: return "reject"
if s[0] == "c": return q0(s[1:])
return "reject"
How I would code the NFA however is like such:
transitions = [
{"a": {1}},
{"b": {0, 2}},
{"c": {0}}
]
starting_state = 0
accepting_states = {0}
def nfa(w):
cur_states = {starting_state}
for c in w:
if not cur_states: return "reject"
cur_states = set.union(*
(transitions[s].get(c, set()) for s in cur_states))
return "accept" if cur_states & accepting_states else "reject"
Upvotes: 2