This commit is contained in:
Adam 2021-01-04 15:05:26 +01:00
parent 1d1a048572
commit 6b4b283e8e
3 changed files with 227 additions and 0 deletions

0
TaskF01/Makefile Normal file
View File

2
TaskF01/run Normal file
View File

@ -0,0 +1,2 @@
#!/bin/bash
python TaskF01/run.py "$@"

225
TaskF01/run.py Normal file
View File

@ -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))