-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfsm.py
142 lines (116 loc) · 4.46 KB
/
fsm.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# Original author : Omer Nguena Timo
# Modified by: Gaël Linkeu
from state import State
from transition import Transition
import os
class FSM :
def __init__(self, initState=None, data=None) :
self._initial = initState
self._statesById = dict()
self._inputSet =set()
self._outputSet =set()
self._transitionsById =dict()
def nextStateId(self) -> int :
return len(self._statesById.keys())
def nextTransitionId(self) -> int :
return len(self._transitionsById.keys())
def getInitialSate(self) -> State :
return self._initial
def addState(self, state: State) -> State :
id = self.nextStateId()
self._statesById[id] = state
state.setID(id)
if (self._initial==None) :
self._initial= state
return state
def getState(self,id:int) -> State :
return self._statesById[id]
def addTransition(self, idSrc, idTgt, input, output) -> Transition:
srcState = self.getState(idSrc)
tgtState = self.getState(idTgt)
if (srcState!=None and tgtState!=None and input!=None and output!=None) :
transition = Transition(srcState, tgtState, input, output)
srcState.addOutTr(transition)
tgtState.addInTr(transition)
id = self.nextTransitionId()
self._transitionsById[id] = transition
transition.setID(id)
self._inputSet.add(input)
self._outputSet.add(output)
return transition
return None
def nbTransitions(self):
return len(self._transitionsById.keys())
def min_words(self, remaining_states, current_state):
stop = False
if len(remaining_states) == 0:
stop = True
state = current_state
inputs_set = []
outputs_set = []
alphabet = 0
transitions = list(self._transitionsById.values())
for x in transitions:
if x._src._id == state:
alphabet += 1
if stop:
inputs_set.append(x._input)
outputs_set.append(x._output)
else:
input_char = x._input
output_char = x._output
if x._tgt._id in remaining_states:
input_words, output_words = self.min_words(x._tgt._id, remaining_states.remove(x._tgt._id))
inputs_set.append([input_char+p for p in input_words])
outputs_set.append([output_char+p for p in output_words])
if alphabet > len(self._inputSet):
print(f'The state {state} has more output transitions than the alphabet lenght')
return inputs_set, outputs_set
def __str__(self) -> str:
pass
def toDot(self) -> str :
rst =""
rst+= f'digraph fsm' + "{"
for cle in self._statesById.keys() :
rst += "\n\t" + self._statesById[cle].toDot()
rst += "\n\tqi [shape = point]"
rst += f'\n\tqi -> s_{self._initial._id}'
for cle in self._transitionsById.keys() :
rst += "\n\t" + self._transitionsById[cle].toDot()
rst+="\n}"
return rst
def produceOutput(self, input) -> str:
currentState = self._initial
output = ""
# i for input_symbol
# o for output_symbol
for i in input:
o = list(self._statesById[currentState.getID()]._outTr[i].keys())[0]
currentState = self._statesById[currentState.getID()]._outTr[i][o][0]._tgt
output += o
return output
def print(self):
print(f'-- The initial state is {self._initial._id}')
print(f'-- The amount of states is {len(self._statesById)}')
print(f'-- The amount of Transitions is {len(self._transitionsById)}')
transitions = list(self._transitionsById.values())
for x in transitions:
print(f'-> {x._src._id} --> {x._input}/{x._output} --> {x._tgt._id}')
def save(self, id=0):
os.makedirs(f"./FSMs",exist_ok=True)
f1 = open(f"./FSMs/FSM{id}.txt", "w")
f1.write(f'{id}\n')
states = []
transitions = []
for i in self._statesById.keys():
states.append(self._statesById[i]._label)
for i in self._transitionsById.keys():
t = self._transitionsById[i]
transitions.append(f'({t._src._label}, {t._input}, {t._output}, {t._tgt._label})')
f1.write(f'{states}\n')
f1.write(f'{transitions}\n')
f1.close()
os.makedirs(f"./FSMs_visuals",exist_ok=True)
f1 = open(f"./FSMs_visuals/fsm{id}.dot", "w")
f1.write(self.toDot())
f1.close()