F04
This commit is contained in:
parent
6b4b283e8e
commit
64748874ff
0
TaskF04/Makefile
Normal file
0
TaskF04/Makefile
Normal file
2
TaskF04/run
Normal file
2
TaskF04/run
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
python TaskF04/run.py "$@"
|
240
TaskF04/run.py
Normal file
240
TaskF04/run.py
Normal file
@ -0,0 +1,240 @@
|
|||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
filename = sys.argv[1]
|
||||||
|
# filename = 'simple1.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 = set()
|
||||||
|
self.transition_function = []
|
||||||
|
self.end_state = []
|
||||||
|
self.all_states = set()
|
||||||
|
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 'FALSE'
|
||||||
|
|
||||||
|
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:
|
||||||
|
for func in self.transition_function:
|
||||||
|
if func['in'] == self.current_state and func['letter'] == '<eps>':
|
||||||
|
self.current_state = func['out'][0]
|
||||||
|
for func in self.transition_function:
|
||||||
|
if func['in'] == self.current_state and func['letter'] == letter:
|
||||||
|
self.current_state = func['out'][0]
|
||||||
|
break
|
||||||
|
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
return 'FALSE'
|
||||||
|
else:
|
||||||
|
self.current_state = found_function['out'][0]
|
||||||
|
else:
|
||||||
|
|
||||||
|
for letter in text:
|
||||||
|
if letter not in self.alphabet:
|
||||||
|
return 'FALSE'
|
||||||
|
|
||||||
|
found_function = self.transition_function[self.current_state][letter]
|
||||||
|
self.current_state = found_function
|
||||||
|
|
||||||
|
|
||||||
|
if self.current_state in self.end_state:
|
||||||
|
return 'TRUE'
|
||||||
|
else:
|
||||||
|
for func in self.transition_function:
|
||||||
|
if func['in'] == self.current_state and func['letter'] == '<eps>':
|
||||||
|
self.current_state = func['out'][0]
|
||||||
|
break
|
||||||
|
if self.current_state in self.end_state:
|
||||||
|
return 'TRUE'
|
||||||
|
else:
|
||||||
|
return 'FALSE'
|
||||||
|
|
||||||
|
|
||||||
|
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 = ['a',
|
||||||
|
'ab',
|
||||||
|
'abc',
|
||||||
|
'abcd',
|
||||||
|
'aaaaab',
|
||||||
|
'abc',
|
||||||
|
'xyz',
|
||||||
|
'0'
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
for line in sys.stdin:
|
||||||
|
line = line.rstrip('\n')
|
||||||
|
FSA.current_state = FSA.initial_state
|
||||||
|
print("{} {}".format(FSA.check_text(line), line))
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user