Search code examples
pythonfsm

Python State Machine: Resetting Loop?


I need my FSM to read the binary, compare to the states and transitions. Then, say if it is accepted or rejected. The accept state is a simple 010. Right now, the loop starts over from the start no matter what I do. I have tried several variations of indentation.

import sys
import os


try:
    Tfile = open("transistions2.txt","r")
except IOError:
    print "Could not open file", "transitions.txt"
    sys.exit()
Transitions = []


ReadLine = Tfile.readline()
while ReadLine != "":
    ReadLine = ReadLine.rstrip()
    CS, IN, NS = ReadLine.split(",")
    Transitions.append((CS, IN, NS))
    ReadLine = Tfile.readline()

print "Transitions:\n", Transitions, "\n"
Tfile.close()


try:
    Sfile = open("states.txt","r")
except IOError:
    print "Could not open file", "states.txt"
    sys.exit()
States = []

ReadLine = Sfile.readline()
while ReadLine != "":
    SN, SS, AS = ReadLine.split(",")
    States.append((SN, bool(int(SS)), bool(int(AS))))
    ReadLine = Sfile.readline()

print "States:\n", States, "\n"
Sfile.close()

try:
    Strfile = open("strings2.txt","r")
except IOError:
    print "Could not open file", strings2.txt
    sys.exit()
Strings = []

ReadLine = Strfile.readline()
while ReadLine != "":
    Readline = ReadLine.rstrip()
    Strings.append(Readline)
    ReadLine = Strfile.readline()

print "Strings:\n", '\n'.join(Strings), '\n'
Strfile.close()

CurrentState = ''
Start ='State1' 


for S in Strings:
    if S != '':
            print "String:", S
            for C in S:
                print "Number:", C
                CurrentState =Start
                for  Transitions in (CS, IN, NS):
                    print Transitions
                    if CS == CurrentState and IN == C:
                           CurrentState = NS
                           print NS
                           break
                for  States in (SN,SS,AS):
                    if SN == CurrentState:
                        print S, "is accepted"
                    elif  AS == CurrentState:
                        print S, " is rejected"
                    else:
                        print S,"Doesnt work"

My several read in text files are:

Transitions:
[('State3', '1', 'State3'), ('State3', '0', 'State4'), ('State2', '1', 'State3'), ('State2', '0', 'State2'), ('State1', '1', 'State1'), ('State1', '0', 'State2')] 

States:
[('State1', True, False), ('State2', False, False), ('State3', False, False), ('State4', False, True)] 

Strings:
01010
1001
010 

Solution

  • You're making your FSM implementation more complicated than necessary by trying to use the states.txt file — here's what it could look like without it:

    import sys
    
    try:
        Tfile = open("transitions2.txt", "r")
    except IOError:
        print "Could not open file transitions2.txt"
        sys.exit()
    Transitions = []
    
    ReadLine = Tfile.readline()
    while ReadLine != "":
        ReadLine = ReadLine.rstrip()
        CS, IN, NS = ReadLine.split(",")
        Transitions.append((CS, IN, NS))
        ReadLine = Tfile.readline()
    
    print "Transitions:\n", Transitions, "\n"
    Tfile.close()
    
    
    try:
        Strfile = open("strings2.txt", "r")
    except IOError:
        print "Could not open file strings2.txt"
        sys.exit()
    Strings = []
    
    ReadLine = Strfile.readline()
    while ReadLine != "":
        Readline = ReadLine.rstrip()
        Strings.append(Readline)
        ReadLine = Strfile.readline()
    
    print "Strings:\n", '\n'.join(Strings), '\n'
    Strfile.close()
    
    
    Start = 'State1'
    Accept = 'State4'
    
    for S in Strings:
        CurrentState = Start
        print "String:", S
        for C in S:
            print " Number:", C
            # find matching state and and input number
            for CS, IN, NS in Transitions:
                if CS == CurrentState and IN == C:
                    CurrentState = NS  # make transition to next state
                    print " NS ->", NS
                    break
    
        if CurrentState == Accept:
            print " "+S, "Is accepted"
        else:
            print " "+S, "Doesn't work"
        print
    

    Output:

    Transitions:
    [('State3', '1', 'State3'), ('State3', '0', 'State4'), ('State2', '1', 'State3'), 
     ('State2', '0', 'State2'), ('State1', '1', 'State1'), ('State1', '0', 'State2')]
    
    Strings:
    01010
    1001
    010
    
    String: 01010
     Number: 0
     NS -> State2
     Number: 1
     NS -> State3
     Number: 0
     NS -> State4
     Number: 1
     Number: 0
     01010 Is accepted
    
    String: 1001
     Number: 1
     NS -> State1
     Number: 0
     NS -> State2
     Number: 0
     NS -> State2
     Number: 1
     NS -> State3
     1001 Doesn't work
    
    String: 010
     Number: 0
     NS -> State2
     Number: 1
     NS -> State3
     Number: 0
     NS -> State4
     010 Is accepted
    

    Since there are no transitions from the Accept state, you could break out of the for C in S: loop as soon as it has been reached and get exactly the same results.