def compileItem(self): c = self.readToken() startPosition = self.tokenStartIndex if c == '(': fsa = self.compileExpr() if self.readToken() != ')': raise ParseError("unmatched '('", startPosition) elif c == '~': fsa = FSA.complement(self.compileItem()) else: positions = None if self.recordSourcePositions: positions = range(startPosition, self.index) fsa = FSA.singleton(c, arcMetadata=positions) while self.peekChar() and self.peekChar() in '?*+': c = self.readChar() if c == '*': fsa = FSA.closure(fsa) elif c == '?': fsa = FSA.union(fsa, FSA.EMPTY_STRING_FSA) elif c == '+': fsa = FSA.iteration(fsa) else: raise 'program error' return fsa
def test_accepts(word): # copy paste because parsing is easier with transition tuple states = set() for x in range(random.randint(0, 20)): states.add("".join(random.choice(string.ascii_letters))) length = len(states) # pick initial I = set(random.sample(states, random.randint(0, length))) # pick final F = set(random.sample(states, random.randint(0, length))) # pick transition T = [] # dictionary for parsing trans = {} for x in range(random.randint(0, length)): cur = random.sample(states, 1)[0] l = "".join(random.choice(string.ascii_letters)) next = random.sample(states, 1)[0] T.append((cur, l, next)) trans[cur] = trans.get(cur, {}) temp = trans[cur].get(l, set()) temp.add(next) trans[cur][l] = temp tester = FSA(I, F, T) if word == "": # empty string condition # true if initial and final contains a state that is the same truth = True if tester.INITIAL.intersection(tester.FINAL) else False else: def check_initial(): """ Returns true if there is a valid path through the transition dictionary for the word. """ def parse(start, word): if word == "": return True else: next = trans.get(cur, {}).get(word[0], {}) while next: if parse(next.pop(), word[1:]): return True return False I = tester.INITIAL.copy() while I: if parse(I.pop(), word): return True return False truth = check_initial() assert tester.accepts(word) == truth
def compileConjunction(self): fsa = None while self.peekToken() and self.peekToken() not in (')', '|'): sequence = self.compileSequence() fsa = fsa and FSA.intersection(fsa, sequence) or sequence self.skipTokens(['&']) return fsa
def testDeterminization(self): states = [0, 1, 2, 3] alphabet = ['a'] transitions = [(0, 1, 'a'), (0, 2, 'a'), (1, 0, 'b'), (1, 3, 'a'), (2, 0, 'a'), (2, 2, 'b'), (2, 3, 'a')] initialState = 0 finalStates = [3] fsa = FSA(states, alphabet, transitions, initialState, finalStates) self.assertTrue(fsa.accepts('aba')) dfa = fsa.determinized() self.assertTrue(dfa.accepts('aba'))
def build_machine(self): machine = FSA() machine.states = self.states machine.alphabet = self.alphabet machine.final_states = self.final_states machine.initial_state = self.initial_state return machine
def compileItem(self): startPosition = self.index c = self.readToken() if c == '(': fsa = self.compileExpr() if self.readToken() != ')': raise "missing ')'" elif c == '~': fsa = FSA.complement(self.compileItem()) else: fsa = FSA.singleton(c, arcMetadata=self.recordSourcePositions and [startPosition]) while self.peekChar() and self.peekChar() in '?*+': c = self.readChar() if c == '*': fsa = FSA.closure(fsa) elif c == '?': fsa = FSA.union(fsa, FSA.EMPTY_STRING_FSA) elif c == '+': fsa = FSA.iteration(fsa) else: raise 'program error' return fsa
def read_file(path): """ Returns the fsa defined by the input file """ f = open(path) lines = f.readlines() f.close() # first 2 lines are initial and final states I = lines[0].strip().split(" ") F = lines[1].strip().split(" ") # the rest are transition relations T = [] for line in lines[2:]: # only the first 3 are looked at cur, l, next = tuple(line.strip().split(" ")[:3]) T.append((cur, l, next)) return FSA(I, F, T)
def random_fsa(): """ Returns a random valid fsa. """ states = set() for x in range(random.randint(0, 20)): states.add("".join(random.choice(string.ascii_letters))) length = len(states) # pick initial I = set(random.sample(states, random.randint(0, length))) # pick final F = set(random.sample(states, random.randint(0, length))) # pick transition T = [] for x in range(random.randint(0, length)): cur = random.sample(states, 1)[0] l = "".join(random.choice(string.ascii_letters)) next = random.sample(states, 1)[0] T.append((cur, l, next)) return FSA(I, F, T)
"""Module PatternScanner -- methods that construct grammars, and that use them
# Module FSChartParser -- finite-state chart parser and grammar compilation utilities
cur, l, next = tuple(line.strip().split(" ")[:3]) T.append((cur, l, next)) return FSA(I, F, T) # To define your FSA # You can play around with these variables. # Note I and F should be a set # and T is an array of tuples of the form (current_state, label, next_state) I = {"X"} # Initial F = {"Y"} # Final T = [("X", "a", "Y"), ("Y", "b", "Z"), ("Z", "a", "X")] # Transition relations my_fsa = FSA(I, F, T) my_fsa1 = read_file("INPUT/example.txt") words_to_test = ["aab", "aba", "a", "abaa", ""] # should be [False, False, True, True, False] print("my_fsa") for word in words_to_test: print(f"'{word}': {my_fsa.accepts(word)}") print("my_fsa1 read from example.txt") for word in words_to_test: print(f"'{word}': {my_fsa1.accepts(word)}") # You can also try the under methods to manipulate your fsa without having to # change the variables are the start
# intro.py #load the FSA module import FSA #Create Appleton A and Appleton B -- Question 1 a = FSA.singleton('Enter AT') b = FSA.singleton('Leave AT') ba = FSA.concatenation(b,a) ab_star = FSA.closure(ba) at_door = FSA.concatenation(a,ab_star) min_at_door = FSA.minimize(at_door) #min_at_door.view() show1 = min_at_door.checkQ1() #print(show1) #Coffee_and_Notes -- Question 2 c = FSA.singleton('Pick up lecture notes') d = FSA.singleton('Return lecture notes') e = FSA.singleton('Have a coffee') cd = FSA.concatenation(c,d) cd_star = FSA.closure(cd) e_star = FSA.closure(e) coffee = FSA.concatenation(e_star, c) dcoffee = FSA.concatenation(d,coffee)
def empty(): """ Returns an empty fsa. """ return FSA(set(), set(), [])
def compileSequence(self): fsa = FSA.EMPTY_STRING_FSA while self.peekToken() and self.peekToken() not in (')', '|', '&'): fsa = FSA.concatenation(fsa, self.compileItem()) return fsa
def main(): inp = "fsa.txt" out = "result.txt" output = open(out, "w") data = parser.parse_input(inp, out) machine = FSA.FSA() incomplite = False # Filling states and transitions for state in data[0]: machine.add_state(state) for transition in data[1]: machine.add_transition(transition) # If initial state does not defined in input the error if machine.get_state(data[2]) == -1: error = "E1: A state '" + data[2] + "' is not in set of states" output.write("Error:\n" + error) output.close() exit(0) else: machine.initial = machine.get_state(data[2]) # If final state not defined the warning3 if len(data[3]) == 0: machine.warnings.append(W1) else: # If final state does not exist then error for fin_state in data[3]: state = machine.get_state(fin_state) if state == -1: error = "E1: A state '" + fin_state + "' is not in set of states" output.write("Error:\n" + error) output.close() exit(0) else: machine.final.append(state) # Parsing transitions and what they will do for path in data[4]: elements = path.split(">") # Checking for existing if (machine.get_state(elements[0]) == -1): error = "E1: A state '" + elements[0] + "' is not in set of states" output.write("Error:\n" + error) output.close() exit(0) elif (machine.get_state(elements[2]) == -1): error = "E1: A state '" + elements[0] + "' is not in set of states" output.write("Error:\n" + error) output.close() exit(0) else: state_left = machine.get_state(elements[0]) state_right = machine.get_state(elements[2]) # If transition does not defined then error if (machine.get_transition(elements[1]) == -1): error = "E3: A transition '" + elements[ 1] + "' is not represented in the alphabet" output.write("Error:\n" + error) output.close() exit(0) else: trans = machine.get_transition(elements[1]) trans.from_state = state_left trans.to_state = state_right state_left.commands[elements[1]] = state_right if (state_right.state != state_left.state): state_left.outputs.append(state_right) state_right.inputs.append(state_left) state_left.outputs = list(set(state_left.outputs)) state_right.inputs = list(set(state_right.inputs)) # Loop to handle possible error and warnings for state in machine.states.values(): if (len(state.inputs) == 0) and (len( state.outputs) == 0) and (len(machine.states.keys()) > 1): error = E2 output.write("Error:\n" + error) output.close() exit(0) if len(state.commands.keys()) < len(machine.transitions): incomplite = True if (len(state.inputs) == 0) and (len(machine.states.keys()) != 1): machine.warnings.append(W2) if len(state.commands.keys()) != len(list(set(state.commands.keys()))): machine.warnings.append(W3) # Printing finite results machine.warnings = list(set(machine.warnings)) machine.warnings.sort() if incomplite: output.write(R2) if len(machine.warnings) > 0: output.write("\nWarning:") for i in machine.warnings: output.write("\n" + i) output.close() exit(0) else: output.write(R1) if len(machine.warnings) > 0: output.write("\nWarning:") for i in machine.warnings: output.write("\n" + i) output.close() exit(0)
#Welcome to the Game #Importing FSA import FSA guard = FSA.singleton("Pass Guard" , "There is a guard blocking your entrance") leave = FSA.singleton("Leave Main Area" , "Go past the guard, who's asleep") office = FSA.singleton("To office" , "There's a door to an office") exitoffice = FSA.singleton("Leave office" , "Back to the entrance") seePlane = FSA.singleton("To plane" , "In the office, you see a plane") leavePlane = FSA.singleton("Leave plane" , "Back to the office") inspectPlane = FSA.singleton("Inspect plane" , "You need a key to operate this") askGuard = FSA.singleton("Ask Guard a question" , "There is a key in the office...snore...") takeKey = FSA.singleton("Take the key" , "You thief!")
if __name__ == "__main__": from pprint import pprint """TESTING BOOLEAN MATRICES methods """ fsa = {"I": {"X"}, "F": {"Y"}, "T": [ ("X", "a", "Y"), ("Y", "b", "Z"), ("Z", "a", "X") ] } test = FSA(fsa["I"], fsa["F"], fsa["T"]) print("CHECKING GETTERS") print("STATES") print(test.STATES) print(f"Initials {test.INITIAL}") print("Inital matrix") print(test.get_initial_matrix()) print("Final matrix") print(f"Initials {test.FINAL}") print(test.get_final_matrix()) print("'a' matrix") print("Transitions")
def compileExpr(self): fsa = FSA.NULL_FSA while self.peekToken() and self.peekToken() != ')': fsa = FSA.union(fsa, self.compileConjunction()) self.skipTokens(['|']) return fsa
# Example.py # 20070920 LHK: created # load the FSA module import FSA # Create two basic FSAs with labels 'a' and 'b' ... a = FSA.singleton('a') b = FSA.singleton('b') # ... combine them through concatenation ... ab = FSA.concatenation(a,b) # ... and add a Kleene star! ab_star = FSA.closure(ab) ######################################### ## Please note that ab_star models ## ## the following regular expression: ## ## ## ## (a b)* ## ######################################### # Now show 'a' ... raw_input('Please press <enter> to see "a"') a.view() # ... show 'b' ... raw_input('Please press <enter> to see "b"') b.view()
#Welcome to the Game #Importing FSA import FSA guard = FSA.singleton("Pass Guard" , "There is a guard blocking your entrance") leave = FSA.singleton("Leave Main Area" , "Go past the guard, who's asleep") office = FSA.singleton("To office" , "There's a door to an office") exitoffice = FSA.singleton("Leave office" , "Back to the entrance") seePlane = FSA.singleton("To plane" , "In the office, you see a plane") leavePlane = FSA.singleton("Leave plane" , "Back to the office") test = FSA.minimize((FSA.closure (FSA.concatenation (seePlane,leavePlane) ) )) test2 = FSA.minimize(FSA.preInterleave(everything,test)) entrance = FSA.minimize(FSA.concatenation(leave, guard)) everything = FSA.minimize(FSA.closure(FSA.concatenation(guard,(FSA.closure(FSA.preinterleave(test, (FSA.concatenation(office, exitoffice)))), leave))) #everything.view() test2.view()