27 int32 nonterm_phones_offset,
28 std::shared_ptr<
const ConstFst<StdArc> > top_fst,
29 const std::vector<std::pair<
Label, std::shared_ptr<
const ConstFst<StdArc> > > > &ifsts):
30 nonterm_phones_offset_(nonterm_phones_offset),
39 entry_arcs_.resize(ifsts_.size());
40 if (!ifsts_.empty()) {
57 for (
size_t i = 0;
i < instances_.size();
i++) {
59 std::unordered_map<BaseStateId, ExpandedState*>::const_iterator
62 for (; iter != end; ++iter) {
69 nonterminal_map_.clear();
76 int32 *nonterminal_symbol,
77 int32 *left_context_phone) {
81 nonterm_phones_offset = nonterm_phones_offset_,
87 *nonterminal_symbol = (label - big_number) / encoding_multiple;
88 *left_context_phone = label % encoding_multiple;
89 if (*nonterminal_symbol <= nonterm_phones_offset ||
90 *left_context_phone == 0 || *left_context_phone >
91 nonterm_phones_offset + static_cast<int32>(
kNontermBos))
92 KALDI_ERR <<
"Decoding invalid label " << label
93 <<
": code error or invalid --nonterm-phones-offset?";
98 nonterminal_map_.clear();
99 for (
size_t i = 0;
i < ifsts_.size();
i++) {
100 int32 nonterminal = ifsts_[
i].first;
101 if (nonterminal_map_.count(nonterminal))
102 KALDI_ERR <<
"Nonterminal symbol " << nonterminal
103 <<
" is paired with two FSTs.";
105 KALDI_ERR <<
"Nonterminal symbol " << nonterminal
106 <<
" in input pairs, was expected to be >= " 108 nonterminal_map_[nonterminal] =
static_cast<int32>(
i);
115 const ConstFst<StdArc> &
fst = *(ifsts_[
i].second);
116 if (fst.NumStates() == 0)
118 InitEntryOrReentryArcs(fst, fst.Start(),
126 instances_.resize(1);
127 instances_[0].ifst_index = -1;
128 instances_[0].fst = top_fst_.get();
129 instances_[0].parent_instance = -1;
130 instances_[0].parent_state = -1;
134 const ConstFst<StdArc> &
fst,
136 int32 expected_nonterminal_symbol,
137 std::unordered_map<int32, int32> *phone_to_arc) {
138 phone_to_arc->clear();
139 ArcIterator<ConstFst<StdArc> > aiter(fst, entry_state);
141 for (; !aiter.Done(); aiter.Next(), ++arc_index) {
142 const StdArc &arc = aiter.Value();
143 int32 nonterminal, left_context_phone;
145 if (entry_state == fst.Start()) {
146 KALDI_ERR <<
"There is something wrong with the graph; did you forget to " 147 "add #nonterm_begin and #nonterm_end to the non-top-level FSTs " 150 KALDI_ERR <<
"There is something wrong with the graph; re-entry state is " 151 "not as anticipated.";
154 DecodeSymbol(arc.ilabel, &nonterminal, &left_context_phone);
155 if (nonterminal != expected_nonterminal_symbol) {
156 KALDI_ERR <<
"Expected arcs from this state to have nonterminal-symbol " 157 << expected_nonterminal_symbol <<
", but got " 160 std::pair<int32, int32> p(left_context_phone, arc_index);
161 if (!phone_to_arc->insert(p).second) {
166 KALDI_ERR <<
"Two arcs had the same left-context phone.";
174 const ConstFst<StdArc> &
fst = *(instances_[instance_id].fst);
175 ArcIterator<ConstFst<StdArc> > aiter(fst, state_id);
176 KALDI_ASSERT(!aiter.Done() && aiter.Value().ilabel > big_number &&
177 "Something is not right; did you call PrepareForGrammarFst()?");
179 const StdArc &arc = aiter.Value();
181 nonterminal = (arc.ilabel - big_number) / encoding_multiple;
184 KALDI_ERR <<
"Encountered unexpected type of nonterminal while " 186 }
else if (nonterminal == GetPhoneSymbolFor(
kNontermEnd)) {
187 return ExpandStateEnd(instance_id, state_id);
189 return ExpandStateUserDefined(instance_id, state_id);
191 KALDI_ERR <<
"Encountered unexpected type of nonterminal " 192 << nonterminal <<
" while expanding state.";
200 const StdArc &arriving_arc,
201 float cost_correction,
211 arc->olabel = arriving_arc.olabel;
215 arc->weight =
Weight(cost_correction + leaving_arc.weight.Value() +
216 arriving_arc.weight.Value());
217 arc->nextstate = arriving_arc.nextstate;
222 if (instance_id == 0)
223 KALDI_ERR <<
"Did not expect #nonterm_end symbol in FST-instance 0.";
224 const FstInstance &instance = instances_[instance_id];
226 const ConstFst<StdArc> &
fst = *(instance.
fst);
227 const FstInstance &parent_instance = instances_[parent_instance_id];
228 const ConstFst<StdArc> &parent_fst = *(parent_instance.
fst);
236 ArcIterator<ConstFst<StdArc> > parent_aiter(parent_fst,
240 float num_reentry_arcs = instances_[instance_id].parent_reentry_arcs.size(),
241 cost_correction = -log(num_reentry_arcs);
243 ArcIterator<ConstFst<StdArc> > aiter(fst, state_id);
245 for (; !aiter.Done(); aiter.Next()) {
246 const StdArc &leaving_arc = aiter.Value();
247 int32 this_nonterminal, left_context_phone;
248 DecodeSymbol(leaving_arc.ilabel, &this_nonterminal,
249 &left_context_phone);
251 ">1 nonterminals from a state; did you use " 252 "PrepareForGrammarFst()?");
253 std::unordered_map<int32, int32>::const_iterator reentry_iter =
254 instances_[instance_id].parent_reentry_arcs.find(left_context_phone),
255 reentry_end = instances_[instance_id].parent_reentry_arcs.end();
256 if (reentry_iter == reentry_end) {
258 <<
" ends with left-context-phone " << left_context_phone
259 <<
" but parent FST does not support that left-context " 260 "at the return point.";
262 size_t parent_arc_index =
static_cast<size_t>(reentry_iter->second);
263 parent_aiter.Seek(parent_arc_index);
264 const StdArc &arriving_arc = parent_aiter.Value();
267 if (leaving_arc.olabel != 0) {
272 KALDI_ERR <<
"Leaving arc has zero olabel.";
275 CombineArcs(leaving_arc, arriving_arc, cost_correction, &arc);
276 ans->
arcs.push_back(arc);
283 int64 encoded_pair = (
static_cast<int64
>(nonterminal) << 32) + state;
287 int32 child_instance_id = instances_.size();
289 std::pair<int64, int32> p(encoded_pair, child_instance_id);
290 std::pair<std::unordered_map<int64, int32>::const_iterator,
bool> ans =
291 instances_[instance_id].child_instances.insert(p);
295 child_instance_id = ans.first->second;
296 return child_instance_id;
302 instances_.resize(child_instance_id + 1);
303 const FstInstance &parent_instance = instances_[instance_id];
304 FstInstance &child_instance = instances_[child_instance_id];
307 std::unordered_map<int32, int32>::const_iterator iter =
308 nonterminal_map_.find(nonterminal);
309 if (iter == nonterminal_map_.end()) {
310 KALDI_ERR <<
"Nonterminal " << nonterminal <<
" was requested, but " 311 "there is no FST for it.";
313 int32 ifst_index = iter->second;
315 child_instance.
fst = ifsts_[ifst_index].second.get();
318 InitEntryOrReentryArcs(*(parent_instance.
fst), state,
321 return child_instance_id;
326 const ConstFst<StdArc> &
fst = *(instances_[instance_id].fst);
327 ArcIterator<ConstFst<StdArc> > aiter(fst, state_id);
330 int32 dest_fst_instance = -1;
333 for (; !aiter.Done(); aiter.Next()) {
334 const StdArc &leaving_arc = aiter.Value();
335 int32 nonterminal, left_context_phone;
336 DecodeSymbol(leaving_arc.ilabel, &nonterminal,
337 &left_context_phone);
338 int32 child_instance_id = GetChildInstanceId(instance_id,
340 leaving_arc.nextstate);
341 if (dest_fst_instance < 0) {
342 dest_fst_instance = child_instance_id;
343 }
else if (dest_fst_instance != child_instance_id) {
344 KALDI_ERR <<
"Same state leaves to different FST instances " 345 "(Did you use PrepareForGrammarFst()?)";
347 const FstInstance &child_instance = instances_[child_instance_id];
348 const ConstFst<StdArc> &child_fst = *(child_instance.
fst);
350 std::unordered_map<int32, int32> &entry_arcs = entry_arcs_[child_ifst_index];
351 if (entry_arcs.empty()) {
352 if (!InitEntryArcs(child_ifst_index)) {
358 float num_entry_arcs = entry_arcs.size(),
359 cost_correction = -log(num_entry_arcs);
363 std::unordered_map<int32, int32>::const_iterator entry_iter =
364 entry_arcs.find(left_context_phone);
365 if (entry_iter == entry_arcs.end()) {
366 KALDI_ERR <<
"FST for nonterminal " << nonterminal
367 <<
" does not have an entry point for left-context-phone " 368 << left_context_phone;
370 int32 arc_index = entry_iter->second;
371 ArcIterator<ConstFst<StdArc> > child_aiter(child_fst, child_fst.Start());
372 child_aiter.Seek(arc_index);
373 const StdArc &arriving_arc = child_aiter.Value();
375 CombineArcs(leaving_arc, arriving_arc, cost_correction, &arc);
376 ans->
arcs.push_back(arc);
384 using namespace kaldi;
386 KALDI_ERR <<
"GrammarFst::Write only supports binary mode.";
388 num_ifsts = ifsts_.size();
394 std::string stream_name(
"unknown");
395 FstWriteOptions wopts(stream_name);
396 top_fst_->Write(os, wopts);
398 for (
int32 i = 0;
i < num_ifsts;
i++) {
399 int32 nonterminal = ifsts_[
i].first;
401 ifsts_[
i].second->Write(os, wopts);
408 std::string stream_name(
"unknown");
409 if (!hdr.Read(is, stream_name))
410 KALDI_ERR <<
"Reading FST: error reading FST header";
411 FstReadOptions ropts(
"<unspecified>", &hdr);
412 ConstFst<StdArc> *ans = ConstFst<StdArc>::Read(is, ropts);
414 KALDI_ERR <<
"Could not read ConstFst from stream.";
421 using namespace kaldi;
423 KALDI_ERR <<
"GrammarFst::Read only supports binary mode.";
424 if (top_fst_ != NULL)
426 int32 format = 1, num_ifsts;
430 KALDI_ERR <<
"This version of the code cannot read this GrammarFst, " 435 for (
int32 i = 0;
i < num_ifsts;
i++) {
438 std::shared_ptr<const ConstFst<StdArc> >
440 ifsts_.push_back(std::pair<
int32, std::shared_ptr<
const ConstFst<StdArc> > >(
441 nonterminal, this_fst));
473 VectorFst<StdArc> *
fst) {
474 bool was_input_deterministic =
true;
480 struct InfoForIlabel {
481 std::vector<size_t> arc_indexes;
486 InfoForIlabel(): new_state(-1) { }
489 std::unordered_map<Label, InfoForIlabel> label_map;
491 size_t arc_index = 0;
492 for (ArcIterator<VectorFst<Arc> > aiter(*fst, s);
493 !aiter.Done(); aiter.Next(), ++arc_index) {
494 const Arc &arc = aiter.Value();
495 InfoForIlabel &info = label_map[arc.ilabel];
496 if (info.arc_indexes.empty()) {
497 info.tot_cost = arc.weight.Value();
499 info.tot_cost = -
kaldi::LogAdd(-info.tot_cost, -arc.weight.Value());
500 was_input_deterministic =
false;
502 info.arc_indexes.push_back(arc_index);
505 if (was_input_deterministic)
510 std::vector<Arc> new_arcs;
511 new_arcs.reserve(arc_index);
513 for (ArcIterator<VectorFst<Arc> > aiter(*fst, s);
514 !aiter.Done(); aiter.Next(), ++arc_index) {
515 const Arc &arc = aiter.Value();
516 Label ilabel = arc.ilabel;
517 InfoForIlabel &info = label_map[ilabel];
518 if (info.arc_indexes.size() == 1) {
519 new_arcs.push_back(arc);
521 if (info.new_state < 0) {
522 info.new_state = fst->AddState();
524 new_arcs.push_back(
Arc(ilabel, 0,
Weight(info.tot_cost),
528 fst->AddArc(info.new_state, Arc(0, arc.olabel,
529 Weight(arc.weight.Value() - info.tot_cost),
534 for (
size_t i = 0;
i < new_arcs.size();
i++)
535 fst->AddArc(s, new_arcs[
i]);
543 using FST = VectorFst<StdArc>;
550 VectorFst<StdArc> *
fst):
551 nonterm_phones_offset_(nonterm_phones_offset),
552 fst_(fst), orig_num_states_(fst->NumStates()),
553 simple_final_state_(kNoStateId) { }
556 if (
fst_->Start() == kNoStateId) {
560 if (IsSpecialState(s)) {
561 if (NeedEpsilons(s)) {
562 InsertEpsilonsForState(s);
569 FixArcsToFinalStates(s);
570 MaybeAddFinalProbToState(s);
575 if (s ==
fst_->Start() && IsEntryState(s))
580 StateId num_new_states =
fst_->NumStates() - orig_num_states_;
581 KALDI_LOG <<
"Added " << num_new_states <<
" new states while " 582 "preparing for grammar FST.";
590 bool IsSpecialState(
StateId s)
const;
602 void MaybeAddFinalProbToState(
StateId s);
609 bool NeedEpsilons(
StateId s)
const;
613 bool IsEntryState(
StateId s)
const;
626 void FixArcsToFinalStates(
StateId s);
654 else if (nonterminal > other.
nonterminal)
return false;
655 if (nextstate < other.
nextstate)
return true;
656 else if (nextstate > other.
nextstate)
return false;
657 return olabel < other.
olabel;
664 void GetCategoryOfArc(
const Arc &arc,
674 void InsertEpsilonsForState(
StateId s);
677 return nonterm_phones_offset_ +
static_cast<int32>(
n);
695 KALDI_WARN <<
"It looks like you are calling PrepareForGrammarFst twice.";
697 for (ArcIterator<FST> aiter(*
fst_, s ); !aiter.Done(); aiter.Next()) {
698 const Arc &arc = aiter.Value();
709 for (ArcIterator<FST> aiter(*
fst_, s ); !aiter.Done(); aiter.Next()) {
710 const Arc &arc = aiter.Value();
711 int32 nonterminal = (arc.ilabel - big_number) /
726 std::set<ArcCategory> categories;
728 if (
fst_->Final(s) != Weight::Zero()) {
736 categories.insert(category);
742 for (ArcIterator<FST> aiter(*
fst_, s ); !aiter.Done(); aiter.Next()) {
743 const Arc &arc = aiter.Value();
745 GetCategoryOfArc(arc, &category);
746 categories.insert(category);
756 ArcIterator<FST> next_aiter(*
fst_, arc.nextstate);
757 if (next_aiter.Done())
758 KALDI_ERR <<
"Destination state of a user-defined nonterminal " 759 "has no arcs leaving it.";
760 const Arc &next_arc = next_aiter.Value();
761 int32 next_nonterminal = (next_arc.ilabel - big_number) /
764 KALDI_ERR <<
"Expected arcs with user-defined nonterminals to be " 765 "followed by arcs with kNontermReenter.";
769 s !=
fst_->Start()) {
770 KALDI_ERR <<
"#nonterm_begin symbol is present but this is not the " 771 "first state. Did you do fstdeterminizestar while compiling?";
773 if (nonterminal == GetPhoneSymbolFor(
kNontermEnd)) {
774 if (
fst_->NumArcs(arc.nextstate) != 0 ||
775 fst_->Final(arc.nextstate) == Weight::Zero()) {
776 KALDI_ERR <<
"Arc with kNontermEnd is not the final arc.";
780 if (categories.size() > 1) {
784 for (std::set<ArcCategory>::const_iterator
785 iter = categories.begin();
786 iter != categories.end(); ++iter) {
787 int32 nonterminal = iter->nonterminal;
793 KALDI_ERR <<
"We do not expect states with arcs of type " 794 "kNontermBegin/kNontermReenter coming out of them, to also have " 795 "other types of arc.";
804 bool need_epsilons = (categories.size() == 1 &&
805 categories.begin()->olabel != 0) ||
806 categories.size() > 1;
807 return need_epsilons;
813 for (MutableArcIterator<FST> aiter(
fst_, s ); !aiter.Done(); aiter.Next()) {
814 Arc arc = aiter.Value();
815 if (arc.ilabel < big_number)
817 int32 nonterminal = (arc.ilabel - big_number) / encoding_multiple;
818 if (nonterminal == GetPhoneSymbolFor(
kNontermEnd)) {
820 fst_->Final(arc.nextstate) != Weight::Zero());
821 if (
fst_->Final(arc.nextstate) == Weight::One())
823 if (simple_final_state_ == kNoStateId) {
824 simple_final_state_ =
fst_->AddState();
825 fst_->SetFinal(simple_final_state_, Weight::One());
827 arc.weight =
Times(arc.weight,
fst_->Final(arc.nextstate));
828 arc.nextstate = simple_final_state_;
835 if (
fst_->Final(s) != Weight::Zero()) {
840 KALDI_ERR <<
"State already final-prob.";
842 ArcIterator<FST> aiter(*
fst_, s );
844 const Arc &arc = aiter.Value();
847 nonterminal = (arc.ilabel - big_number) / encoding_multiple;
849 if (nonterminal == GetPhoneSymbolFor(
kNontermEnd) ||
860 int32 ilabel = arc.ilabel;
861 if (ilabel < big_number) {
866 int32 nonterminal = (ilabel - big_number) / encoding_multiple;
868 if (nonterminal <= nonterm_phones_offset_) {
869 KALDI_ERR <<
"Problem decoding nonterminal symbol " 870 "(wrong --nonterm-phones-offset option?), ilabel=" 876 arc_category->
olabel = arc.olabel;
880 arc_category->
olabel = arc.olabel;
896 std::map<ArcCategory, std::pair<StateId, float> > category_to_state;
899 for (fst::ArcIterator<FST> aiter(*
fst_, s); !aiter.Done(); aiter.Next()) {
900 const Arc &arc = aiter.Value();
902 GetCategoryOfArc(arc, &category);
904 if (nonterminal == 0)
908 KALDI_ERR <<
"Something went wrong; did not expect to insert epsilons " 909 "for this type of state.";
911 auto iter = category_to_state.find(category);
912 if (iter == category_to_state.end()) {
914 float cost = arc.weight.Value();
915 category_to_state[category] = std::pair<StateId, float>(new_state, cost);
917 std::pair<StateId, float> &p = iter->second;
926 std::vector<Arc> arcs_from_this_state;
927 arcs_from_this_state.reserve(
fst_->NumArcs(s) + category_to_state.size());
931 for (std::map<
ArcCategory, std::pair<StateId, float> >::const_iterator
932 iter = category_to_state.begin(); iter != category_to_state.end();
935 StateId new_state = iter->second.first;
936 float cost = iter->second.second;
940 arc.weight =
Weight(cost);
941 arc.nextstate = new_state;
942 arcs_from_this_state.push_back(arc);
948 for (fst::ArcIterator<FST> aiter(*
fst_, s); !aiter.Done(); aiter.Next()) {
949 const Arc &arc = aiter.Value();
951 GetCategoryOfArc(arc, &category);
953 if (nonterminal == 0) {
954 arcs_from_this_state.push_back(arc);
957 auto iter = category_to_state.find(category);
960 new_arc.ilabel = arc.ilabel;
961 if (arc.olabel == category.
olabel) {
965 new_arc.olabel = arc.olabel;
967 StateId new_state = iter->second.first;
968 float epsilon_arc_cost = iter->second.second;
969 new_arc.weight =
Weight(arc.weight.Value() - epsilon_arc_cost);
970 new_arc.nextstate = arc.nextstate;
971 fst_->AddArc(new_state, new_arc);
975 for (
size_t i = 0;
i < arcs_from_this_state.size();
i++) {
976 fst_->AddArc(s, arcs_from_this_state[
i]);
983 VectorFst<StdArc> *
fst) {
989 VectorFst<StdArc> *vector_fst) {
995 std::vector<std::pair<GrammarStateId, StdStateId> > queue;
996 std::unordered_map<GrammarStateId, StdStateId> state_map;
998 vector_fst->DeleteStates();
999 state_map[grammar_fst->
Start()] = vector_fst->AddState();
1000 vector_fst->SetStart(0);
1003 std::pair<GrammarStateId, StdStateId>(grammar_fst->
Start(), 0));
1005 while (!queue.empty()) {
1006 std::pair<GrammarStateId, StdStateId> p = queue.back();
1008 GrammarStateId grammar_state = p.first;
1009 StdStateId std_state = p.second;
1010 vector_fst->SetFinal(std_state, grammar_fst->
Final(grammar_state));
1012 for (; !aiter.
Done(); aiter.
Next()) {
1015 std_arc.ilabel = grammar_arc.
ilabel;
1016 std_arc.olabel = grammar_arc.
olabel;
1017 std_arc.weight = grammar_arc.
weight;
1018 GrammarStateId next_grammar_state = grammar_arc.
nextstate;
1019 StdStateId next_std_state;
1020 std::unordered_map<GrammarStateId, StdStateId>::const_iterator
1021 state_iter = state_map.find(next_grammar_state);
1022 if (state_iter == state_map.end()) {
1023 next_std_state = vector_fst->AddState();
1024 state_map[next_grammar_state] = next_std_state;
1025 queue.push_back(std::pair<GrammarStateId, StdStateId>(
1026 next_grammar_state, next_std_state));
1028 next_std_state = state_iter->second;
1030 std_arc.nextstate = next_std_state;
1031 vector_fst->AddArc(std_state, std_arc);
void Write(std::ostream &os, bool binary) const
fst::StdArc::StateId StateId
This code computes Goodness of Pronunciation (GOP) and extracts phone-level pronunciation feature for...
static ConstFst< StdArc > * ReadConstFstFromStream(std::istream &is)
std::unordered_map< BaseStateId, ExpandedState * > expanded_states
const ConstFst< StdArc > * fst
StateId simple_final_state_
VectorFst< StdArc > * fst_
int32 GetPhoneSymbolFor(enum NonterminalValues n) const
bool IsEntryState(StateId s) const
void Read(std::istream &os, bool binary)
void InitEntryOrReentryArcs(const ConstFst< StdArc > &fst, int32 entry_state, int32 nonterminal_symbol, std::unordered_map< int32, int32 > *phone_to_arc)
std::vector< StdArc > arcs
void ReadBasicType(std::istream &is, bool binary, T *t)
ReadBasicType is the name of the read function for bool, integer types, and floating-point types...
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
ExpandedState * ExpandState(int32 instance_id, BaseStateId state_id)
bool InitEntryArcs(int32 i)
int32 GetChildInstanceId(int32 instance_id, int32 nonterminal, int32 state)
NonterminalValues
An anonymous enum to define some values for symbols used in our grammar-fst framework.
#define KALDI_GRAMMAR_FST_SPECIAL_WEIGHT
void PrepareForGrammarFst(int32 nonterm_phones_offset, VectorFst< StdArc > *fst)
This function prepares 'ifst' for use in GrammarFst: it ensures that it has the expected properties...
static void CombineArcs(const StdArc &leaving_arc, const StdArc &arriving_arc, float cost_correction, StdArc *arc)
Called while expanding states, this function combines information from two arcs: one leaving one sub-...
std::unordered_map< int32, int32 > parent_reentry_arcs
StdArc::StateId BaseStateId
LatticeWeightTpl< FloatType > Times(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
const fst::Fst< fst::StdArc > & fst_
GrammarFst()
This constructor should only be used prior to calling Read().
void InitNonterminalMap()
Represents an expanded state in an FstInstance.
static void InputDeterminizeSingleState(StdArc::StateId s, VectorFst< StdArc > *fst)
This utility function input-determinizes a specified state s of the FST 'fst'.
void ExpectToken(std::istream &is, bool binary, const char *token)
ExpectToken tries to read in the given token, and throws an exception on failure. ...
bool NeedEpsilons(StateId s) const
ExpandedState * ExpandStateUserDefined(int32 instance_id, BaseStateId state_id)
void MaybeAddFinalProbToState(StateId s)
bool IsSpecialState(StateId s) const
GrammarFst is an FST that is 'stitched together' from multiple FSTs, that can recursively incorporate...
const Arc & Value() const
void WriteToken(std::ostream &os, bool binary, const char *token)
The WriteToken functions are for writing nonempty sequences of non-space characters.
fst::StdArc::Weight Weight
bool operator<(const Int32Pair &a, const Int32Pair &b)
GrammarFstPreparer(int32 nonterm_phones_offset, VectorFst< StdArc > *fst)
double LogAdd(double x, double y)
void GetCategoryOfArc(const Arc &arc, ArcCategory *arc_category) const
#define KALDI_ASSERT(cond)
Weight Final(StateId s) const
void InsertEpsilonsForState(StateId s)
ExpandedState * ExpandStateEnd(int32 instance_id, BaseStateId state_id)
void WriteBasicType(std::ostream &os, bool binary, T t)
WriteBasicType is the name of the write function for bool, integer types, and floating-point types...
This is the overridden template for class ArcIterator for GrammarFst.
void CopyToVectorFst(GrammarFst *grammar_fst, VectorFst< StdArc > *vector_fst)
This function copies a GrammarFst to a VectorFst (intended mostly for testing and comparison purposes...
int32 GetEncodingMultiple(int32 nonterm_phones_offset)
void FixArcsToFinalStates(StateId s)
int32 nonterm_phones_offset_
void DecodeSymbol(Label label, int32 *nonterminal_symbol, int32 *left_context_phone)
Decodes an ilabel into a pair (nonterminal, left_context_phone).