39 if (
clat_->Properties(kTopSorted,
true) == 0) {
40 if (!TopSort(
clat_)) {
41 KALDI_WARN <<
"Topological sorting of state-level lattice failed " 42 "(probably your lexicon has empty words or your LM has epsilon cycles; this " 55 static void GetString(
const ExpandedFst<CompactArc> &clat,
58 typename std::vector<IntType>::iterator begin,
59 typename std::vector<IntType>::iterator end) {
60 CompactWeight
final = clat.Final(state);
61 size_t len = end - begin;
65 const std::vector<IntType> &
string =
final.String();
67 "Either code error, or paths in lattice have inconsistent lengths");
68 std::copy(
string.begin(),
string.begin() + len, begin);
72 ArcIterator<ExpandedFst<CompactArc> > aiter(clat, state);
76 "Either code error, or paths in lattice are inconsistent in length.");
78 const CompactArc &arc = aiter.Value();
79 size_t arc_len = arc.weight.String().size();
81 std::copy(arc.weight.String().begin(), arc.weight.String().begin() + len, begin);
83 std::copy(arc.weight.String().begin(), arc.weight.String().end(), begin);
85 GetString(clat, arc.nextstate, -1, begin + arc_len, end);
92 if (shift == NULL)
return;
97 size_t num_arcs =
clat_->NumArcs(state);
98 if (num_arcs + (is_final ? 1 : 0) > 1 && *shift > 0) {
103 std::vector<IntType> string(*shift), compare_string(*shift);
107 std::copy(
final.String().begin(),
final.String().begin() + *shift,
115 for (; arc < num_arcs; arc++) {
117 compare_string.begin(), compare_string.end());
118 std::pair<typename std::vector<IntType>::iterator,
119 typename std::vector<IntType>::iterator> pr =
120 std::mismatch(
string.begin(),
string.end(),
121 compare_string.begin());
122 if (pr.first !=
string.end()) {
124 *shift = pr.first -
string.begin();
125 string.resize(*shift);
126 compare_string.resize(*shift);
133 StateId num_states =
clat_->NumStates();
141 for (StateId state = num_states - 1; state >
clat_->Start(); state--) {
142 size_t num_arcs =
clat_->NumArcs(state);
143 CompactWeight
final =
clat_->Final(state);
149 int32 shift = std::numeric_limits<int32>::max();
153 shift = std::min(shift, static_cast<int32>(
final.String().size()));
154 for (ArcIterator<MutableFst<CompactArc> > aiter(*
clat_, state);
155 !aiter.Done(); aiter.Next(), num_arcs++) {
156 const CompactArc &arc (aiter.Value());
157 shift = std::min(shift,
shift_vec_[arc.nextstate] +
158 static_cast<int32>(arc.weight.String().size()));
167 StateId num_states =
clat_->NumStates();
168 for (StateId state = 0; state < num_states; state++) {
170 std::vector<IntType> string;
171 for (MutableArcIterator<MutableFst<CompactArc> > aiter(
clat_, state);
172 !aiter.Done(); aiter.Next()) {
173 CompactArc arc(aiter.Value());
174 KALDI_ASSERT(arc.nextstate > state &&
"Cyclic lattice");
176 string = arc.weight.String();
177 size_t orig_len =
string.size(), next_shift =
shift_vec_[arc.nextstate];
179 string.resize(
string.size() + next_shift);
183 string.begin() + orig_len,
string.end());
186 arc.weight.SetString(std::vector<IntType>(
string.begin() + shift,
191 CompactWeight
final =
clat_->Final(state);
194 final.SetString(std::vector<IntType>(
final.String().begin() + shift,
195 final.String().end()));
196 clat_->SetFinal(state,
final);
202 MutableFst<ArcTpl<CompactLatticeWeightTpl<Weight, IntType> > > *
clat_;
209 template<
class Weight,
class IntType>
213 return pusher.
Push();
216 template<
class Weight,
class IntType>
219 if (clat->Properties(kTopSorted,
true) == 0) {
220 if (!TopSort(clat)) {
221 KALDI_WARN <<
"Topological sorting of state-level lattice failed " 222 "(probably your lexicon has empty words or your LM has epsilon cycles; this " 231 StateId num_states = clat->NumStates();
232 if (num_states == 0) {
233 KALDI_WARN <<
"Pushing weights of empty compact lattice";
237 std::vector<Weight> weight_to_end(num_states);
239 for (StateId s = num_states - 1; s >= 0; s--) {
240 Weight this_weight_to_end = clat->Final(s).Weight();
241 for (ArcIterator<MutableFst<CompactArc> > aiter(*clat, s);
242 !aiter.Done(); aiter.Next()) {
243 const CompactArc &arc = aiter.Value();
244 KALDI_ASSERT(arc.nextstate > s &&
"Cyclic lattices not allowed.");
245 this_weight_to_end =
Plus(this_weight_to_end,
246 Times(aiter.Value().weight.Weight(),
247 weight_to_end[arc.nextstate]));
249 if (this_weight_to_end == Weight::Zero()) {
250 KALDI_WARN <<
"Lattice has non-coaccessible states.";
252 weight_to_end[s] = this_weight_to_end;
254 weight_to_end[0] = Weight::One();
257 for (StateId s = 0; s < num_states; s++) {
258 Weight this_weight_to_end = weight_to_end[s];
259 if (this_weight_to_end == Weight::Zero())
261 for (MutableArcIterator<MutableFst<CompactArc> > aiter(clat, s);
262 !aiter.Done(); aiter.Next()) {
263 CompactArc arc = aiter.Value();
264 Weight next_weight_to_end = weight_to_end[arc.nextstate];
265 if (next_weight_to_end != Weight::Zero()) {
266 arc.weight.SetWeight(
Times(arc.weight.Weight(),
267 Divide(next_weight_to_end,
268 this_weight_to_end)));
272 CompactWeight final_weight = clat->Final(s);
274 final_weight.SetWeight(
Divide(final_weight.Weight(), this_weight_to_end));
275 clat->SetFinal(s, final_weight);
284 bool PushCompactLatticeStrings<kaldi::LatticeWeight, kaldi::int32>(
285 MutableFst<kaldi::CompactLatticeArc> *clat);
288 bool PushCompactLatticeWeights<kaldi::LatticeWeight, kaldi::int32>(
289 MutableFst<kaldi::CompactLatticeArc> *clat);
fst::StdArc::StateId StateId
LatticeWeightTpl< FloatType > Divide(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2, DivideType typ=DIVIDE_ANY)
For an extended explanation of the framework of which grammar-fsts are a part, please see Support for...
LatticeWeightTpl< FloatType > Plus(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
CompactLatticeWeightTpl< Weight, IntType > CompactWeight
bool PushCompactLatticeStrings(MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *clat)
This function pushes the transition-ids as far towards the start as they will go. ...
static void GetString(const ExpandedFst< CompactArc > &clat, StateId state, size_t arc_idx, typename std::vector< IntType >::iterator begin, typename std::vector< IntType >::iterator end)
void CheckForConflict(const CompactWeight &final, StateId state, int32 *shift)
bool PushCompactLatticeWeights(MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > *clat)
This function pushes the weights in the CompactLattice so that all states except possibly the start s...
LatticeWeightTpl< FloatType > Times(const LatticeWeightTpl< FloatType > &w1, const LatticeWeightTpl< FloatType > &w2)
CompactLatticePusher(MutableFst< CompactArc > *clat)
MutableFst< ArcTpl< CompactLatticeWeightTpl< Weight, IntType > > > * clat_
fst::StdArc::Weight Weight
std::vector< int32 > shift_vec_
#define KALDI_ASSERT(cond)
ArcTpl< CompactWeight > CompactArc
static const CompactLatticeWeightTpl< WeightType, IntType > Zero()
CompactArc::StateId StateId
#define KALDI_COMPILE_TIME_ASSERT(b)