Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef FST_LIB_VISIT_H__
00023 #define FST_LIB_VISIT_H__
00024
00025 #include <fst/arcfilter.h>
00026 #include <fst/mutable-fst.h>
00027
00028 namespace fst {
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 template <class Arc, class V, class Q, class ArcFilter>
00067 void Visit(const Fst<Arc> &fst, V *visitor, Q *queue, ArcFilter filter) {
00068
00069 typedef typename Arc::StateId StateId;
00070 typedef ArcIterator< Fst<Arc> > AIterator;
00071
00072 visitor->InitVisit(fst);
00073
00074 StateId start = fst.Start();
00075 if (start == kNoStateId) {
00076 visitor->FinishVisit();
00077 return;
00078 }
00079
00080
00081 const unsigned kWhiteState = 0x01;
00082 const unsigned kGreyState = 0x02;
00083 const unsigned kBlackState = 0x04;
00084
00085
00086 const unsigned kArcIterDone = 0x08;
00087
00088 vector<unsigned char> state_status;
00089 vector<AIterator *> arc_iterator;
00090
00091 StateId nstates = start + 1;
00092 bool expanded = false;
00093 if (fst.Properties(kExpanded, false)) {
00094 nstates = CountStates(fst);
00095 expanded = true;
00096 }
00097
00098 state_status.resize(nstates, kWhiteState);
00099 arc_iterator.resize(nstates);
00100 StateIterator< Fst<Arc> > siter(fst);
00101
00102
00103 bool visit = true;
00104
00105
00106 for (StateId root = start; visit && root < nstates;) {
00107 visit = visitor->InitState(root, root);
00108 state_status[root] = kGreyState;
00109 queue->Enqueue(root);
00110 while (!queue->Empty()) {
00111 StateId s = queue->Head();
00112 if (s >= state_status.size()) {
00113 nstates = s + 1;
00114 state_status.resize(nstates, kWhiteState);
00115 arc_iterator.resize(nstates);
00116 }
00117
00118 if (arc_iterator[s] == 0 && !(state_status[s] & kArcIterDone) && visit)
00119 arc_iterator[s] = new AIterator(fst, s);
00120
00121 AIterator *aiter = arc_iterator[s];
00122 if ((aiter && aiter->Done()) || !visit) {
00123 delete aiter;
00124 arc_iterator[s] = 0;
00125 state_status[s] |= kArcIterDone;
00126 }
00127
00128 if (state_status[s] & kArcIterDone) {
00129 queue->Dequeue();
00130 visitor->FinishState(s);
00131 state_status[s] = kBlackState;
00132 continue;
00133 }
00134
00135 const Arc &arc = aiter->Value();
00136 if (arc.nextstate >= state_status.size()) {
00137 nstates = arc.nextstate + 1;
00138 state_status.resize(nstates, kWhiteState);
00139 arc_iterator.resize(nstates);
00140 }
00141
00142 if (filter(arc)) {
00143
00144 if (state_status[arc.nextstate] == kWhiteState) {
00145 visit = visitor->WhiteArc(s, arc);
00146 if (!visit) continue;
00147 visit = visitor->InitState(arc.nextstate, root);
00148 state_status[arc.nextstate] = kGreyState;
00149 queue->Enqueue(arc.nextstate);
00150 } else if (state_status[arc.nextstate] == kBlackState) {
00151 visit = visitor->BlackArc(s, arc);
00152 } else {
00153 visit = visitor->GreyArc(s, arc);
00154 }
00155 }
00156 aiter->Next();
00157
00158 if (aiter->Done()) {
00159 delete aiter;
00160 arc_iterator[s] = 0;
00161 state_status[s] |= kArcIterDone;
00162 }
00163 }
00164
00165 for (root = root == start ? 0 : root + 1;
00166 root < nstates && state_status[root] != kWhiteState;
00167 ++root);
00168
00169
00170 if (!expanded && root == nstates) {
00171 for (; !siter.Done(); siter.Next()) {
00172 if (siter.Value() == nstates) {
00173 ++nstates;
00174 state_status.push_back(kWhiteState);
00175 arc_iterator.push_back(0);
00176 break;
00177 }
00178 }
00179 }
00180 }
00181 visitor->FinishVisit();
00182 }
00183
00184
00185 template <class Arc, class V, class Q>
00186 inline void Visit(const Fst<Arc> &fst, V *visitor, Q* queue) {
00187 Visit(fst, visitor, queue, AnyArcFilter<Arc>());
00188 }
00189
00190
00191 template <class A>
00192 class CopyVisitor {
00193 public:
00194 typedef A Arc;
00195 typedef typename A::StateId StateId;
00196
00197 CopyVisitor(MutableFst<Arc> *ofst) : ifst_(0), ofst_(ofst) {}
00198
00199 void InitVisit(const Fst<A> &ifst) {
00200 ifst_ = &ifst;
00201 ofst_->DeleteStates();
00202 ofst_->SetStart(ifst_->Start());
00203 }
00204
00205 bool InitState(StateId s, StateId) {
00206 while (ofst_->NumStates() <= s)
00207 ofst_->AddState();
00208 return true;
00209 }
00210
00211 bool WhiteArc(StateId s, const Arc &arc) {
00212 ofst_->AddArc(s, arc);
00213 return true;
00214 }
00215
00216 bool GreyArc(StateId s, const Arc &arc) {
00217 ofst_->AddArc(s, arc);
00218 return true;
00219 }
00220
00221 bool BlackArc(StateId s, const Arc &arc) {
00222 ofst_->AddArc(s, arc);
00223 return true;
00224 }
00225
00226 void FinishState(StateId s) {
00227 ofst_->SetFinal(s, ifst_->Final(s));
00228 }
00229
00230 void FinishVisit() {}
00231
00232 private:
00233 const Fst<Arc> *ifst_;
00234 MutableFst<Arc> *ofst_;
00235 };
00236
00237
00238
00239 template <class A>
00240 class PartialVisitor {
00241 public:
00242 typedef A Arc;
00243 typedef typename A::StateId StateId;
00244
00245 explicit PartialVisitor(StateId maxvisit) : maxvisit_(maxvisit) {}
00246
00247 void InitVisit(const Fst<A> &ifst) { nvisit_ = 0; }
00248
00249 bool InitState(StateId s, StateId) {
00250 ++nvisit_;
00251 return nvisit_ <= maxvisit_;
00252 }
00253
00254 bool WhiteArc(StateId s, const Arc &arc) { return true; }
00255 bool GreyArc(StateId s, const Arc &arc) { return true; }
00256 bool BlackArc(StateId s, const Arc &arc) { return true; }
00257 void FinishState(StateId s) {}
00258 void FinishVisit() {}
00259
00260 private:
00261 StateId maxvisit_;
00262 StateId nvisit_;
00263 };
00264
00265
00266 }
00267
00268 #endif /// FST_LIB_VISIT_H__
00269