diff options
Diffstat (limited to 'kaldi_io/src/tools/openfst/include/fst/rational.h')
-rw-r--r-- | kaldi_io/src/tools/openfst/include/fst/rational.h | 330 |
1 files changed, 330 insertions, 0 deletions
diff --git a/kaldi_io/src/tools/openfst/include/fst/rational.h b/kaldi_io/src/tools/openfst/include/fst/rational.h new file mode 100644 index 0000000..96aa00d --- /dev/null +++ b/kaldi_io/src/tools/openfst/include/fst/rational.h @@ -0,0 +1,330 @@ +// rational.h + +// 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. +// +// Copyright 2005-2010 Google, Inc. +// Author: [email protected] (Michael Riley) +// +// \file +// An Fst implementation and base interface for delayed unions, +// concatenations and closures. + +#ifndef FST_LIB_RATIONAL_H__ +#define FST_LIB_RATIONAL_H__ + +#include <algorithm> +#include <string> +#include <vector> +using std::vector; + +#include <fst/mutable-fst.h> +#include <fst/replace.h> +#include <fst/test-properties.h> + + +namespace fst { + +typedef CacheOptions RationalFstOptions; + +// This specifies whether to add the empty string. +enum ClosureType { CLOSURE_STAR = 0, // T* -> add the empty string + CLOSURE_PLUS = 1 }; // T+ -> don't add the empty string + +template <class A> class RationalFst; +template <class A> void Union(RationalFst<A> *fst1, const Fst<A> &fst2); +template <class A> void Concat(RationalFst<A> *fst1, const Fst<A> &fst2); +template <class A> void Concat(const Fst<A> &fst1, RationalFst<A> *fst2); +template <class A> void Closure(RationalFst<A> *fst, ClosureType closure_type); + + +// Implementation class for delayed unions, concatenations and closures. +template<class A> +class RationalFstImpl : public FstImpl<A> { + public: + using FstImpl<A>::SetType; + using FstImpl<A>::SetProperties; + using FstImpl<A>::WriteHeader; + using FstImpl<A>::SetInputSymbols; + using FstImpl<A>::SetOutputSymbols; + + typedef A Arc; + typedef typename A::Weight Weight; + typedef typename A::StateId StateId; + typedef typename A::Label Label; + + explicit RationalFstImpl(const RationalFstOptions &opts) + : nonterminals_(0), + replace_(0), + replace_options_(opts, 0) { + SetType("rational"); + fst_tuples_.push_back(pair<Label, const Fst<A>*>(0, 0)); + } + + RationalFstImpl(const RationalFstImpl<A> &impl) + : rfst_(impl.rfst_), + nonterminals_(impl.nonterminals_), + + replace_(impl.replace_ ? impl.replace_->Copy(true) : 0), + replace_options_(impl.replace_options_) { + SetType("rational"); + fst_tuples_.reserve(impl.fst_tuples_.size()); + for (size_t i = 0; i < impl.fst_tuples_.size(); ++i) + fst_tuples_.push_back(make_pair(impl.fst_tuples_[i].first, + impl.fst_tuples_[i].second + ? impl.fst_tuples_[i].second->Copy(true) + : 0)); + } + + virtual ~RationalFstImpl() { + for (size_t i = 0; i < fst_tuples_.size(); ++i) + if (fst_tuples_[i].second) + delete fst_tuples_[i].second; + if (replace_) + delete replace_; + } + + StateId Start() { return Replace()->Start(); } + + Weight Final(StateId s) { return Replace()->Final(s); } + + size_t NumArcs(StateId s) { return Replace()->NumArcs(s); } + + size_t NumInputEpsilons(StateId s) { + return Replace()->NumInputEpsilons(s); + } + + size_t NumOutputEpsilons(StateId s) { + return Replace()->NumOutputEpsilons(s); + } + + uint64 Properties() const { return Properties(kFstProperties); } + + // Set error if found; return FST impl properties. + uint64 Properties(uint64 mask) const { + if ((mask & kError) && Replace()->Properties(kError, false)) + SetProperties(kError, kError); + return FstImpl<Arc>::Properties(mask); + } + + // Implementation of UnionFst(fst1,fst2) + void InitUnion(const Fst<A> &fst1, const Fst<A> &fst2) { + if (replace_) + delete replace_; + uint64 props1 = fst1.Properties(kFstProperties, false); + uint64 props2 = fst2.Properties(kFstProperties, false); + SetInputSymbols(fst1.InputSymbols()); + SetOutputSymbols(fst1.OutputSymbols()); + rfst_.AddState(); + rfst_.AddState(); + rfst_.SetStart(0); + rfst_.SetFinal(1, Weight::One()); + rfst_.SetInputSymbols(fst1.InputSymbols()); + rfst_.SetOutputSymbols(fst1.OutputSymbols()); + nonterminals_ = 2; + rfst_.AddArc(0, A(0, -1, Weight::One(), 1)); + rfst_.AddArc(0, A(0, -2, Weight::One(), 1)); + fst_tuples_.push_back(make_pair(-1, fst1.Copy())); + fst_tuples_.push_back(make_pair(-2, fst2.Copy())); + SetProperties(UnionProperties(props1, props2, true), kCopyProperties); + } + + // Implementation of ConcatFst(fst1,fst2) + void InitConcat(const Fst<A> &fst1, const Fst<A> &fst2) { + if (replace_) + delete replace_; + uint64 props1 = fst1.Properties(kFstProperties, false); + uint64 props2 = fst2.Properties(kFstProperties, false); + SetInputSymbols(fst1.InputSymbols()); + SetOutputSymbols(fst1.OutputSymbols()); + rfst_.AddState(); + rfst_.AddState(); + rfst_.AddState(); + rfst_.SetStart(0); + rfst_.SetFinal(2, Weight::One()); + rfst_.SetInputSymbols(fst1.InputSymbols()); + rfst_.SetOutputSymbols(fst1.OutputSymbols()); + nonterminals_ = 2; + rfst_.AddArc(0, A(0, -1, Weight::One(), 1)); + rfst_.AddArc(1, A(0, -2, Weight::One(), 2)); + fst_tuples_.push_back(make_pair(-1, fst1.Copy())); + fst_tuples_.push_back(make_pair(-2, fst2.Copy())); + SetProperties(ConcatProperties(props1, props2, true), kCopyProperties); + } + + // Implementation of ClosureFst(fst, closure_type) + void InitClosure(const Fst<A> &fst, ClosureType closure_type) { + if (replace_) + delete replace_; + uint64 props = fst.Properties(kFstProperties, false); + SetInputSymbols(fst.InputSymbols()); + SetOutputSymbols(fst.OutputSymbols()); + if (closure_type == CLOSURE_STAR) { + rfst_.AddState(); + rfst_.SetStart(0); + rfst_.SetFinal(0, Weight::One()); + rfst_.AddArc(0, A(0, -1, Weight::One(), 0)); + } else { + rfst_.AddState(); + rfst_.AddState(); + rfst_.SetStart(0); + rfst_.SetFinal(1, Weight::One()); + rfst_.AddArc(0, A(0, -1, Weight::One(), 1)); + rfst_.AddArc(1, A(0, 0, Weight::One(), 0)); + } + rfst_.SetInputSymbols(fst.InputSymbols()); + rfst_.SetOutputSymbols(fst.OutputSymbols()); + fst_tuples_.push_back(make_pair(-1, fst.Copy())); + nonterminals_ = 1; + SetProperties(ClosureProperties(props, closure_type == CLOSURE_STAR, true), + kCopyProperties); + } + + // Implementation of Union(Fst &, RationalFst *) + void AddUnion(const Fst<A> &fst) { + if (replace_) + delete replace_; + uint64 props1 = FstImpl<A>::Properties(); + uint64 props2 = fst.Properties(kFstProperties, false); + VectorFst<A> afst; + afst.AddState(); + afst.AddState(); + afst.SetStart(0); + afst.SetFinal(1, Weight::One()); + ++nonterminals_; + afst.AddArc(0, A(0, -nonterminals_, Weight::One(), 1)); + Union(&rfst_, afst); + fst_tuples_.push_back(make_pair(-nonterminals_, fst.Copy())); + SetProperties(UnionProperties(props1, props2, true), kCopyProperties); + } + + // Implementation of Concat(Fst &, RationalFst *) + void AddConcat(const Fst<A> &fst, bool append) { + if (replace_) + delete replace_; + uint64 props1 = FstImpl<A>::Properties(); + uint64 props2 = fst.Properties(kFstProperties, false); + VectorFst<A> afst; + afst.AddState(); + afst.AddState(); + afst.SetStart(0); + afst.SetFinal(1, Weight::One()); + ++nonterminals_; + afst.AddArc(0, A(0, -nonterminals_, Weight::One(), 1)); + if (append) + Concat(&rfst_, afst); + else + Concat(afst, &rfst_); + fst_tuples_.push_back(make_pair(-nonterminals_, fst.Copy())); + SetProperties(ConcatProperties(props1, props2, true), kCopyProperties); + } + + // Implementation of Closure(RationalFst *, closure_type) + void AddClosure(ClosureType closure_type) { + if (replace_) + delete replace_; + uint64 props = FstImpl<A>::Properties(); + Closure(&rfst_, closure_type); + SetProperties(ClosureProperties(props, closure_type == CLOSURE_STAR, true), + kCopyProperties); + } + + // Returns the underlying ReplaceFst. + ReplaceFst<A> *Replace() const { + if (!replace_) { + fst_tuples_[0].second = rfst_.Copy(); + replace_ = new ReplaceFst<A>(fst_tuples_, replace_options_); + } + return replace_; + } + + private: + VectorFst<A> rfst_; // rational topology machine; uses neg. nonterminals + Label nonterminals_; // # of nonterminals used + // Contains the nonterminals and their corresponding FSTs. + mutable vector<pair<Label, const Fst<A>*> > fst_tuples_; + mutable ReplaceFst<A> *replace_; // Underlying ReplaceFst + ReplaceFstOptions<A> replace_options_; // Options for creating 'replace_' + + void operator=(const RationalFstImpl<A> &impl); // disallow +}; + +// Parent class for the delayed rational operations - delayed union, +// concatenation, and closure. +// +// This class attaches interface to implementation and handles +// reference counting, delegating most methods to ImplToFst. +template <class A> +class RationalFst : public ImplToFst< RationalFstImpl<A> > { + public: + friend class StateIterator< RationalFst<A> >; + friend class ArcIterator< RationalFst<A> >; + friend void Union<>(RationalFst<A> *fst1, const Fst<A> &fst2); + friend void Concat<>(RationalFst<A> *fst1, const Fst<A> &fst2); + friend void Concat<>(const Fst<A> &fst1, RationalFst<A> *fst2); + friend void Closure<>(RationalFst<A> *fst, ClosureType closure_type); + + typedef A Arc; + typedef typename A::StateId StateId; + typedef RationalFstImpl<A> Impl; + + virtual void InitStateIterator(StateIteratorData<A> *data) const { + GetImpl()->Replace()->InitStateIterator(data); + } + + virtual void InitArcIterator(StateId s, ArcIteratorData<A> *data) const { + GetImpl()->Replace()->InitArcIterator(s, data); + } + + protected: + RationalFst() + : ImplToFst<Impl>(new Impl(RationalFstOptions())) {} + + explicit RationalFst(const RationalFstOptions &opts) + : ImplToFst<Impl>(new Impl(opts)) {} + + // See Fst<>::Copy() for doc. + RationalFst(const RationalFst<A> &fst , bool safe = false) + : ImplToFst<Impl>(fst, safe) {} + + private: + // Makes visible to friends. + Impl *GetImpl() const { return ImplToFst<Impl>::GetImpl(); } + + void operator=(const RationalFst<A> &fst); // disallow +}; + + +// Specialization for RationalFst. +template <class A> +class StateIterator< RationalFst<A> > + : public StateIterator< ReplaceFst<A> > { + public: + explicit StateIterator(const RationalFst<A> &fst) + : StateIterator< ReplaceFst<A> >(*(fst.GetImpl()->Replace())) {} +}; + + +// Specialization for RationalFst. +template <class A> +class ArcIterator< RationalFst<A> > + : public CacheArcIterator< ReplaceFst<A> > { + public: + typedef typename A::StateId StateId; + + ArcIterator(const RationalFst<A> &fst, StateId s) + : ArcIterator< ReplaceFst<A> >(*(fst.GetImpl()->Replace()), s) {} +}; + +} // namespace fst + +#endif // FST_LIB_RATIONAL_H__ |