forked from shoupon/prob_verify
-
Notifications
You must be signed in to change notification settings - Fork 0
/
fsm.cpp
172 lines (137 loc) · 4.72 KB
/
fsm.cpp
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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#include <string>
#include <vector>
using namespace std;
#include "define.h"
#include "fsm.h"
#include "statemachine.h"
Fsm::Fsm(string name, Lookup* msg, Lookup* mac)
:_name(name), _current(0), StateMachine(msg, mac)
{
}
bool Fsm::addState(string name)
{
int id = (int)_stateNames.size();
InsertResult ir = _stateNames.insert( Entry(name, id) );
if( ir.second == false )
return false ;
State* newState = new State(name, id) ;
_states.push_back(newState) ;
return true;
}
bool Fsm::addTransition(string from, string to, Transition& label)
{
int idFrom = _stateNames.find(from)->second;
int idTo = _stateNames.find(to)->second;
return addTransition(idFrom, idTo, label);
}
bool Fsm::addTransition(int from, int to, Transition& label)
{
// need to check if there's duplicate input label
// There can be at most one high probability transition with a specific label for a state,
// while there can be multiple low probability transitions with the same label
if( _states[from]->findTransition(label) ) {
// There is already such input label for _states[from]
return false ;
}
_states[from]->addOutEdge(label, _states[to]);
return true;
}
State* Fsm::getState(string name)
{
int key = _stateNames.find(name)->second;
return _states[key];
}
State* Fsm::getState(int id)
{
if( id >= 0 && id < (int)_states.size() )
return _states[id];
else
return 0 ;
}
void Fsm::reset()
{
for( size_t ii = 0 ; ii < _states.size() ; ++ii ) {
_states[ii]->reset();
}
_current = 0;
}
int Fsm::nullInputTrans(vector<MessageTuple*>& outMsgs, bool& high_prob, int startIdx )
{
/*State* cs = _states[_current];
outMsgs.clear();
// Go through all the transition of current state
for( size_t tid = startIdx ; tid < cs->getNumTrans() ; ++tid ) {
Transition tr = cs->getTrans((int)tid);
if( tr.getFromMachineId() == 0 ) {
// For each output label. There may be multiple output destined for different machines.
for( size_t oid = 0 ; oid < tr.getNumOutLabels() ; ++oid ) {
OutLabel lbl = tr.getOutLabel(oid);
unique_ptr<MessageTuple> out(new FsmMessage(0, lbl.first,
0, lbl.second, _macLookup->toInt(this->_name)) );
outMsgs.push_back(out);
}
// Change state
State* next = cs->getNextState((int)tid);
_current = next->getID();
if( tr.isHigh() )
high_prob = true;
else
high_prob = false;
return tid+1;
}
}
// The function will get to this line only when no null input transition is found
return -1;*/
MessageTuple* nullInput = new FsmMessage(0,0,0,0,0) ;
int retIdx = transit(nullInput, outMsgs, high_prob, startIdx);
delete nullInput;
return retIdx;
}
// Consider merging this funciton with nullInputTransit()
int Fsm::transit(MessageTuple* inMsg, vector<MessageTuple*>& outMsgs, bool& high_prob, int startIdx )
{
State* cs = _states[_current];
outMsgs.clear();
// Go through the possible transitions, find that matches the message
for( int tid = startIdx ; tid < cs->getNumTrans(); ++tid ) {
Transition tr = cs->getTrans((int)tid);
if( tr.getFromMachineId() == inMsg->subjectId() && tr.getInputMessageId() == inMsg->destMsgId() ) {
// Matching found. Get all the outLabels
for( size_t oid = 0 ; oid < tr.getNumOutLabels() ; ++oid ) {
OutLabel lbl = tr.getOutLabel(oid);
MessageTuple* out = new FsmMessage(tr.getFromMachineId(), lbl.first,
tr.getInputMessageId(), lbl.second, _macLookup->toInt(this->_name)) ;
outMsgs.push_back(out);
}
// Change state
State* next = cs->getNextState((int)tid);
_current = next->getID();
if( tr.isHigh() )
high_prob = true;
else
high_prob = false;
return tid+1;
}
}
// The function will get to this line when no more matching transition is found
return -1;
}
void Fsm::restore(const StateSnapshot* snapshot)
{
_current = snapshot->curStateId() ;
}
StateSnapshot* Fsm::curState()
{
StateSnapshot* ssPtr = new FsmSnapshot(_current);
return ssPtr;
}
MessageTuple* FsmMessage::clone()
{
MessageTuple* ret = new FsmMessage(_src, _dest, _srcMsg, _destMsg, _subject);
return ret;
}
StateSnapshot* FsmSnapshot::clone() const
{
StateSnapshot* ret = new FsmSnapshot(_stateId);
return ret;
}