21 #ifndef FST_DFS_VISIT_H_ 22 #define FST_DFS_VISIT_H_ 78 using Arc =
typename FST::Arc;
84 return pool->Allocate();
90 dfs_state->~DfsState<
FST>();
91 pool->Free(dfs_state);
108 template <
class FST,
class Visitor,
class ArcFilter>
110 bool access_only =
false) {
111 visitor->InitVisit(fst);
112 const auto start = fst.Start();
114 visitor->FinishVisit();
118 enum class StateColor : uint8_t {
123 std::vector<StateColor> state_color;
124 std::stack<internal::DfsState<FST> *> state_stack;
126 auto nstates = start + 1;
127 bool expanded =
false;
132 state_color.resize(nstates, StateColor::kWhite);
137 for (
auto root = start; dfs && root < nstates;) {
138 state_color[root] = StateColor::kGrey;
140 dfs = visitor->InitState(root, root);
141 while (!state_stack.empty()) {
142 auto *dfs_state = state_stack.top();
143 const auto s = dfs_state->state_id;
144 if (s >=
static_cast<decltype(s)
>(state_color.size())) {
146 state_color.resize(nstates, StateColor::kWhite);
149 if (!dfs || aiter.
Done()) {
150 state_color[s] = StateColor::kBlack;
153 if (!state_stack.empty()) {
154 auto *parent_state = state_stack.top();
155 auto &piter = parent_state->arc_iter;
156 visitor->FinishState(s, parent_state->state_id, &piter.Value());
163 const auto &arc = aiter.
Value();
165 static_cast<decltype(arc.nextstate)>(state_color.size())) {
166 nstates = arc.nextstate + 1;
167 state_color.resize(nstates, StateColor::kWhite);
173 const auto next_color = state_color[arc.nextstate];
174 switch (next_color) {
175 case StateColor::kWhite:
176 dfs = visitor->TreeArc(s, arc);
178 state_color[arc.nextstate] = StateColor::kGrey;
179 state_stack.push(
new (&state_pool)
181 dfs = visitor->InitState(arc.nextstate, root);
183 case StateColor::kGrey:
184 dfs = visitor->BackArc(s, arc);
187 case StateColor::kBlack:
188 dfs = visitor->ForwardOrCrossArc(s, arc);
193 if (access_only)
break;
195 for (root = root == start ? 0 : root + 1;
196 root < nstates && state_color[root] != StateColor::kWhite; ++root) {
199 if (!expanded && root == nstates) {
200 for (; !siter.
Done(); siter.
Next()) {
201 if (siter.
Value() == nstates) {
203 state_color.push_back(StateColor::kWhite);
209 visitor->FinishVisit();
212 template <
class Arc,
class Visitor>
219 #endif // FST_DFS_VISIT_H_
static void Destroy(DfsState< FST > *dfs_state, MemoryPool< DfsState< FST >> *pool)
void DfsVisit(const FST &fst, Visitor *visitor, ArcFilter filter, bool access_only=false)
const Arc & Value() const
DfsState(const FST &fst, StateId s)
typename Arc::StateId StateId
ArcIterator< FST > arc_iter
Arc::StateId CountStates(const Fst< Arc > &fst)
constexpr uint64_t kExpanded