diff --git a/TaskF01/Makefile b/TaskF01/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/TaskF01/run b/TaskF01/run new file mode 100644 index 0000000..7d835d8 --- /dev/null +++ b/TaskF01/run @@ -0,0 +1,2 @@ +#!/bin/bash +python TaskF01/run.py "$@" \ No newline at end of file diff --git a/TaskF01/run.py b/TaskF01/run.py new file mode 100644 index 0000000..a9b6623 --- /dev/null +++ b/TaskF01/run.py @@ -0,0 +1,225 @@ +import sys +import os + +#filename = sys.argv[1] +# filename = 'test1.arg' +#path = os.path.join(os.getcwd(), filename) +#file = open(path, 'r').readlines() + + +class FSA(): + def __init__(self): + self.initial_state = '0' + self.current_letter = None + self.current_state = self.initial_state + self.alphabet = ['a', 'b', 'c'] + self.transition_function = [ + {'in': '0', 'letter': 'a', 'out': ['0']}, + {'in': '0', 'letter': 'b', 'out': ['0', '1']}, + {'in': '0', 'letter': 'c', 'out': ['0']}, + {'in': '1', 'letter': 'a', 'out': ['2']}, + {'in': '1', 'letter': 'b', 'out': ['2']}, + {'in': '1', 'letter': 'c', 'out': ['2']} +] + self.end_state = ['2'] + self.all_states = ['0', '1', '2'] + self.is_nfa = 0 + + def add_letter_to_alphabet(self, letter): + self.alphabet.add(letter) + + def add_transition_to_transition_function(self, input_state, output_state, letter): + self.all_states.add(input_state) + self.all_states.add(output_state) + if len(self.transition_function) > 0: + for x, function in enumerate(self.transition_function): + if function['in'] == input_state and function['letter'] == letter: + self.transition_function[x]['out'].append(output_state) + return + obj = {'in': input_state, 'letter': letter, 'out': [output_state]} + self.transition_function.append(obj) + else: + obj = {'in': input_state, 'letter': letter, 'out': [output_state]} + self.transition_function.append(obj) + # add letter to alphabet + + def specify_end_state(self, end_state): + self.end_state.append(end_state) + + + def nfa_to_dfa(self): + nfa = dict() + for x in FSA.all_states: + nfa[x] = {} + for a in FSA.alphabet: + a_dict = {a: None} + nfa[x].update(a_dict) + + for function in self.transition_function: + nfa[function['in']][function['letter']] = function['out'] + + trap_state_in = str(int(sorted(FSA.all_states, reverse=True)[0]) + 1) + trap_state = {trap_state_in: {}} + for a in FSA.alphabet: + a_dict = {a: trap_state_in} + trap_state[trap_state_in].update(a_dict) + + dfa = {} + dfa_keys = [] + new_states_list = [] + + dfa.update(trap_state) + + # first row + state = FSA.initial_state + nfa_function = nfa[state] + dfa_keys.append(state) + dfa_function = dict() + for letter in FSA.alphabet: + if not nfa_function[letter]: + dfa_function[letter] = trap_state_in + continue + if nfa_function[letter] and len(nfa_function[letter]) > 1: + new_state_in = ''.join(nfa_function[letter]) + for i in self.end_state: + if i in nfa_function[letter]: + self.specify_end_state(new_state_in) + break + dfa_function[letter] = new_state_in + new_states_list.append(new_state_in) + continue + if len(nfa_function[letter]) == 1: + new_state = nfa_function[letter][0] + dfa_function[letter] = new_state + if new_state not in new_states_list: + new_states_list.append(new_state) + continue + dfa[state] = dfa_function + + while len(new_states_list) != 0: + new_dfa_state = new_states_list.pop(0) + dfa_function = dict() + + + if len(new_dfa_state) == 1: + nfa_function = nfa[new_dfa_state] + + for letter in FSA.alphabet: + if not nfa_function[letter]: + dfa_function[letter] = trap_state_in + continue + if nfa_function[letter] and len(nfa_function[letter]) > 1: + new_state_in = ''.join(nfa_function[letter]) + for i in self.end_state: + if i in nfa_function[letter]: + self.specify_end_state(new_state_in) + break + dfa_function[letter] = new_state_in + if new_state_in not in dfa_keys and new_state_in not in new_states_list: + new_states_list.append(new_state_in) + continue + if len(nfa_function[letter]) == 1: + new_state_in = nfa_function[letter][0] + dfa_function[letter] = new_state_in + if new_state_in not in dfa_keys and new_state_in not in new_states_list: + new_states_list.append(new_state_in) + continue + dfa[new_dfa_state] = dfa_function + else: + dfa_func = {} + for letter in FSA.alphabet: + dfa_func[letter] = None + + for let in FSA.alphabet: + new_letter = '' + for state in new_dfa_state: + nfa_letter = nfa[state][let] + if nfa_letter: + x = ''.join(nfa_letter) + new_letter += x + + if new_letter not in dfa_keys and new_letter not in new_states_list: + dfa_keys.append(new_letter) + new_states_list.append(new_letter) + + for i in self.end_state: + if i in new_letter: + self.specify_end_state(new_letter) + break + + + if new_letter == '': + new_letter = trap_state_in + + + dfa_func[let] = new_letter + dfa[new_dfa_state] = dfa_func + self.transition_function = dfa + + + def check_text(self, text): + + if self.is_nfa == 0: + for letter in text: + if letter not in self.alphabet: + return 'NO' + + found_function = None + + for func in self.transition_function: + if func['in'] == self.current_state and func['letter'] == letter: + found_function = func + + if not found_function: + return 'NO' + self.current_state = found_function['out'][0] + else: + + for letter in text: + if letter not in self.alphabet: + return 'NO' + + found_function = self.transition_function[self.current_state][letter] + self.current_state = found_function + + + if self.current_state in self.end_state: + return 'YES' + else: + return 'NO' + + +FSA = FSA() + +# for line in file: +# if '#' in line: +# continue +# line = line.rstrip('\n').split(' ') +# if len(line) > 1: +# FSA.add_transition_to_transition_function(line[0], line[1], line[2]) +# FSA.add_letter_to_alphabet(line[2]) +# else: +# FSA.specify_end_state(line[0]) + +for function in FSA.transition_function: + if len(function['out']) > 1: + FSA.is_nfa = 1 + FSA.nfa_to_dfa() + break + + +lines = ['abc', +'abbc', +'bca', +'b', +'abaa', +'aaacbb' +] + +for line in lines: + line = line.rstrip('\n') + FSA.current_state = FSA.initial_state + print(FSA.check_text(line)) + + +