17 #ifndef NLP_GRM2_SFST_CANONICAL_H_ 18 #define NLP_GRM2_SFST_CANONICAL_H_ 23 #include <fst/arcfilter.h> 24 #include <fst/dfs-visit.h> 26 #include <fst/matcher.h> 27 #include <fst/properties.h> 28 #include <fst/topsort.h> 38 typename Arc::Label phi_label,
39 std::vector<typename Arc::StateId> *top_order) {
41 typedef typename Arc::StateId StateId;
43 f::MultiLabelArcFilter<Arc> label_filter;
44 if (phi_label != f::kNoLabel)
45 label_filter.AddLabel(phi_label);
47 label_filter.AddLabel(0);
49 std::vector<StateId> inv_order;
50 f::TopOrderVisitor<Arc> top_order_visitor(&inv_order, &acyclic);
51 f::DfsVisit(fst, &top_order_visitor, label_filter);
53 top_order->resize(inv_order.size());
54 for (StateId s = 0; s < inv_order.size(); ++s) {
55 (*top_order)[inv_order[s]] = s;
72 std::vector<typename Arc::StateId> *top_order) {
74 typedef typename Arc::StateId StateId;
75 typedef f::ExplicitMatcher<f::Matcher<f::Fst<Arc>>> Matr;
76 typedef f::StateIterator<f::Fst<Arc>> StateItr;
78 bool phi_acyclic =
PhiTopOrder(fst, phi_label, top_order);
81 VLOG(1) <<
"IsCanonical: input FST not acyclic w.r.t. phi/epsilon labels";
84 typedef typename Arc::StateId StateId;
86 if (!fst.Properties(f::kILabelSorted,
true)) {
87 VLOG(1) <<
"IsCanonical: input FST not sorted w.r.t input labels";
91 if (phi_label != f::kNoLabel) {
93 Matr matcher(fst, f::MATCH_INPUT);
94 for (StateItr siter(fst); !siter.Done(); siter.Next()) {
95 StateId s = siter.Value();
97 if (matcher.Find(phi_label)) {
99 if (!matcher.Done()) {
100 VLOG(1) <<
"IsCanonical: phi non-determinism: state: " << s;
113 typename Arc::Label phi_label = fst::kNoLabel) {
114 typedef typename Arc::StateId StateId;
115 std::vector<StateId> top_order;
124 std::vector<int> *state_order) {
126 typedef typename Arc::StateId StateId;
127 typedef f::ExplicitMatcher<f::Matcher<f::Fst<Arc>>> Matr;
128 state_order->clear();
129 if (phi_label == f::kNoLabel) {
130 state_order->resize(f::CountStates(fst), 1);
133 std::vector<StateId> top_order;
134 bool acyclic =
PhiTopOrder(fst, phi_label, &top_order);
136 FSTERROR() <<
"PhiStateOrder: input FST not canonical (phi-cyclic)";
139 state_order->resize(top_order.size(), 1);
142 Matr matcher(fst, f::MATCH_INPUT);
143 for (StateId i = top_order.size() - 1; i >= 0; --i) {
144 StateId s = top_order[i];
146 if (matcher.Find(phi_label)) {
147 const Arc &arc = matcher.Value();
148 int ord = (*state_order)[arc.nextstate] + 1;
149 (*state_order)[s] = ord;
160 #endif // NLP_GRM2_SFST_CANONICAL_H_ int PhiStateOrder(const fst::Fst< Arc > &fst, typename Arc::Label phi_label, std::vector< int > *state_order)
bool PhiTopOrder(const fst::Fst< Arc > &fst, typename Arc::Label phi_label, std::vector< typename Arc::StateId > *top_order)
bool IsCanonical(const fst::Fst< Arc > &fst, typename Arc::Label phi_label, std::vector< typename Arc::StateId > *top_order)