|
|
// Copyright 2005-2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the 'License');
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an 'AS IS' BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// See www.openfst.org for extensive documentation on this weighted
// finite-state transducer library.
//
// Function to sort states of an FST.
#ifndef FST_STATESORT_H_
#define FST_STATESORT_H_
#include <algorithm>
#include <utility>
#include <vector>
#include <fst/log.h>
#include <fst/fst.h>
#include <fst/mutable-fst.h>
#include <fst/properties.h>
#include <fst/util.h>
namespace fst {
// Sorts the input states of an FST. order[i] gives the state ID after
// sorting that corresponds to the state ID i before sorting; it must
// therefore be a permutation of the input FST's states ID sequence.
template <class Arc> void StateSort(MutableFst<Arc> *fst, const std::vector<typename Arc::StateId> &order) { using StateId = typename Arc::StateId; using Weight = typename Arc::Weight; if (order.size() != fst->NumStates()) { FSTERROR() << "StateSort: Bad order vector size: " << order.size(); fst->SetProperties(kError, kError); return; } if (fst->Start() == kNoStateId) return; const auto props = fst->Properties(kStateSortProperties, false); std::vector<bool> done(order.size(), false); std::vector<Arc> arcsa; std::vector<Arc> arcsb; fst->SetStart(order[fst->Start()]); for (StateIterator<MutableFst<Arc>> siter(*fst); !siter.Done(); siter.Next()) { auto s1 = siter.Value(); StateId s2; if (done[s1]) continue; auto final1 = fst->Final(s1); auto final2 = Weight::Zero(); arcsa.clear(); for (ArcIterator<MutableFst<Arc>> aiter(*fst, s1); !aiter.Done(); aiter.Next()) { arcsa.push_back(aiter.Value()); } for (; !done[s1]; s1 = s2, final1 = final2, std::swap(arcsa, arcsb)) { s2 = order[s1]; if (!done[s2]) { final2 = fst->Final(s2); arcsb.clear(); for (ArcIterator<MutableFst<Arc>> aiter(*fst, s2); !aiter.Done(); aiter.Next()) { arcsb.push_back(aiter.Value()); } } fst->SetFinal(s2, final1); fst->DeleteArcs(s2); for (auto arc : arcsa) { // NOLINT(performance-for-range-copy)
arc.nextstate = order[arc.nextstate]; fst->AddArc(s2, arc); } done[s1] = true; } } fst->SetProperties(props, kFstProperties); }
} // namespace fst
#endif // FST_STATESORT_H_
|