// matcher-fst.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: riley@google.com (Michael Riley) // // \file // Class to add a matcher to an FST. #ifndef FST_LIB_MATCHER_FST_FST_H__ #define FST_LIB_MATCHER_FST_FST_H__ #include <fst/add-on.h> #include <fst/const-fst.h> #include <fst/lookahead-matcher.h> namespace fst { // WRITABLE MATCHERS - these have the interface of Matchers (see // matcher.h) and these additional methods: // // template <class F> // class Matcher { // public: // typedef ... MatcherData; // Initialization data // ... // // Constructor with additional argument for external initialization // // data; matcher increments its reference count on construction and // // decrements the reference count, and if 0 deletes, on destruction. // Matcher(const F &fst, MatchType type, MatcherData *data); // // // Returns pointer to initialization data that can be // // passed to a Matcher constructor. // MatcherData *GetData() const; // }; // The matcher initialization data class must have the form: // class MatcherData { // public: // // Required copy constructor. // MatcherData(const MatcherData &); // // // // Required I/O methods. // static MatcherData *Read(istream &istrm); // bool Write(ostream &ostrm); // // // Required reference counting. // int RefCount() const; // int IncrRefCount(); // int DecrRefCount(); // }; // Default MatcherFst initializer - does nothing. template <class M> class NullMatcherFstInit { public: typedef AddOnPair<typename M::MatcherData, typename M::MatcherData> D; typedef AddOnImpl<typename M::FST, D> Impl; NullMatcherFstInit(Impl **) {} }; // Class to add a matcher M to an Fst F. Creates a new Fst of type name N. // Optional function object I can be used to initialize the Fst. template <class F, class M, const char* N, class I = NullMatcherFstInit<M> > class MatcherFst : public ImplToExpandedFst< AddOnImpl<F, AddOnPair<typename M::MatcherData, typename M::MatcherData> > > { public: friend class StateIterator< MatcherFst<F, M, N, I> >; friend class ArcIterator< MatcherFst<F, M, N, I> >; typedef F FST; typedef M FstMatcher; typedef typename F::Arc Arc; typedef typename Arc::StateId StateId; typedef AddOnPair<typename M::MatcherData, typename M::MatcherData> D; typedef AddOnImpl<F, D> Impl; MatcherFst() : ImplToExpandedFst<Impl>(new Impl(F(), N)) {} explicit MatcherFst(const F &fst) : ImplToExpandedFst<Impl>(CreateImpl(fst, N)) {} explicit MatcherFst(const Fst<Arc> &fst) : ImplToExpandedFst<Impl>(CreateImpl(fst, N)) {} // See Fst<>::Copy() for doc. MatcherFst(const MatcherFst<F, M, N, I> &fst, bool safe = false) : ImplToExpandedFst<Impl>(fst, safe) {} // Get a copy of this MatcherFst. See Fst<>::Copy() for further doc. virtual MatcherFst<F, M, N, I> *Copy(bool safe = false) const { return new MatcherFst<F, M, N, I>(*this, safe); } // Read a MatcherFst from an input stream; return NULL on error static MatcherFst<F, M, N, I> *Read(istream &strm, const FstReadOptions &opts) { Impl *impl = Impl::Read(strm, opts); return impl ? new MatcherFst<F, M, N, I>(impl) : 0; } // Read a MatcherFst from a file; return NULL on error // Empty filename reads from standard input static MatcherFst<F, M, N, I> *Read(const string &filename) { Impl *impl = ImplToExpandedFst<Impl>::Read(filename); return impl ? new MatcherFst<F, M, N, I>(impl) : 0; } virtual bool Write(ostream &strm, const FstWriteOptions &opts) const { return GetImpl()->Write(strm, opts); } virtual bool Write(const string &filename) const { return Fst<Arc>::WriteFile(filename); } virtual void InitStateIterator(StateIteratorData<Arc> *data) const { return GetImpl()->InitStateIterator(data); } virtual void InitArcIterator(StateId s, ArcIteratorData<Arc> *data) const { return GetImpl()->InitArcIterator(s, data); } virtual M *InitMatcher(MatchType match_type) const { return new M(GetFst(), match_type, GetData(match_type)); } // Allows access to MatcherFst components. Impl *GetImpl() const { return ImplToFst<Impl, ExpandedFst<Arc> >::GetImpl(); } F& GetFst() const { return GetImpl()->GetFst(); } typename M::MatcherData *GetData(MatchType match_type) const { D *data = GetImpl()->GetAddOn(); return match_type == MATCH_INPUT ? data->First() : data->Second(); } private: static Impl *CreateImpl(const F &fst, const string &name) { M imatcher(fst, MATCH_INPUT); M omatcher(fst, MATCH_OUTPUT); D *data = new D(imatcher.GetData(), omatcher.GetData()); Impl *impl = new Impl(fst, name); impl->SetAddOn(data); I init(&impl); data->DecrRefCount(); return impl; } static Impl *CreateImpl(const Fst<Arc> &fst, const string &name) { F ffst(fst); return CreateImpl(ffst, name); } explicit MatcherFst(Impl *impl) : ImplToExpandedFst<Impl>(impl) {} // Makes visible to friends. void SetImpl(Impl *impl, bool own_impl = true) { ImplToFst< Impl, ExpandedFst<Arc> >::SetImpl(impl, own_impl); } void operator=(const MatcherFst<F, M, N, I> &fst); // disallow }; // Specialization fo MatcherFst. template <class F, class M, const char* N, class I> class StateIterator< MatcherFst<F, M, N, I> > : public StateIterator<F> { public: explicit StateIterator(const MatcherFst<F, M, N, I> &fst) : StateIterator<F>(fst.GetImpl()->GetFst()) {} }; // Specialization for MatcherFst. template <class F, class M, const char* N, class I> class ArcIterator< MatcherFst<F, M, N, I> > : public ArcIterator<F> { public: ArcIterator(const MatcherFst<F, M, N, I> &fst, typename F::Arc::StateId s) : ArcIterator<F>(fst.GetImpl()->GetFst(), s) {} }; // Specialization for MatcherFst template <class F, class M, const char* N, class I> class Matcher< MatcherFst<F, M, N, I> > { public: typedef MatcherFst<F, M, N, I> FST; typedef typename F::Arc Arc; typedef typename Arc::StateId StateId; typedef typename Arc::Label Label; Matcher(const FST &fst, MatchType match_type) { matcher_ = fst.InitMatcher(match_type); } Matcher(const Matcher<FST> &matcher) { matcher_ = matcher.matcher_->Copy(); } ~Matcher() { delete matcher_; } Matcher<FST> *Copy() const { return new Matcher<FST>(*this); } MatchType Type(bool test) const { return matcher_->Type(test); } void SetState(StateId s) { matcher_->SetState(s); } bool Find(Label label) { return matcher_->Find(label); } bool Done() const { return matcher_->Done(); } const Arc& Value() const { return matcher_->Value(); } void Next() { matcher_->Next(); } uint64 Properties(uint64 props) const { return matcher_->Properties(props); } uint32 Flags() const { return matcher_->Flags(); } private: M *matcher_; void operator=(const Matcher<Arc> &); // disallow }; // Specialization for MatcherFst template <class F, class M, const char* N, class I> class LookAheadMatcher< MatcherFst<F, M, N, I> > { public: typedef MatcherFst<F, M, N, I> FST; typedef typename F::Arc Arc; typedef typename Arc::StateId StateId; typedef typename Arc::Label Label; typedef typename Arc::Weight Weight; LookAheadMatcher(const FST &fst, MatchType match_type) { matcher_ = fst.InitMatcher(match_type); } LookAheadMatcher(const LookAheadMatcher<FST> &matcher, bool safe = false) { matcher_ = matcher.matcher_->Copy(safe); } ~LookAheadMatcher() { delete matcher_; } // General matcher methods LookAheadMatcher<FST> *Copy(bool safe = false) const { return new LookAheadMatcher<FST>(*this, safe); } MatchType Type(bool test) const { return matcher_->Type(test); } void SetState(StateId s) { matcher_->SetState(s); } bool Find(Label label) { return matcher_->Find(label); } bool Done() const { return matcher_->Done(); } const Arc& Value() const { return matcher_->Value(); } void Next() { matcher_->Next(); } const FST &GetFst() const { return matcher_->GetFst(); } uint64 Properties(uint64 props) const { return matcher_->Properties(props); } uint32 Flags() const { return matcher_->Flags(); } // Look-ahead methods bool LookAheadLabel(Label label) const { return matcher_->LookAheadLabel(label); } bool LookAheadFst(const Fst<Arc> &fst, StateId s) { return matcher_->LookAheadFst(fst, s); } Weight LookAheadWeight() const { return matcher_->LookAheadWeight(); } bool LookAheadPrefix(Arc *arc) const { return matcher_->LookAheadPrefix(arc); } void InitLookAheadFst(const Fst<Arc>& fst, bool copy = false) { matcher_->InitLookAheadFst(fst, copy); } private: M *matcher_; void operator=(const LookAheadMatcher<FST> &); // disallow }; // // Useful aliases when using StdArc and LogArc. // // Arc look-ahead matchers extern const char arc_lookahead_fst_type[]; typedef MatcherFst<ConstFst<StdArc>, ArcLookAheadMatcher<SortedMatcher<ConstFst<StdArc> > >, arc_lookahead_fst_type> StdArcLookAheadFst; typedef MatcherFst<ConstFst<LogArc>, ArcLookAheadMatcher<SortedMatcher<ConstFst<LogArc> > >, arc_lookahead_fst_type> LogArcLookAheadFst; // Label look-ahead matchers extern const char ilabel_lookahead_fst_type[]; extern const char olabel_lookahead_fst_type[]; static const uint32 ilabel_lookahead_flags = kInputLookAheadMatcher | kLookAheadWeight | kLookAheadPrefix | kLookAheadEpsilons | kLookAheadNonEpsilonPrefix; static const uint32 olabel_lookahead_flags = kOutputLookAheadMatcher | kLookAheadWeight | kLookAheadPrefix | kLookAheadEpsilons | kLookAheadNonEpsilonPrefix; typedef MatcherFst<ConstFst<StdArc>, LabelLookAheadMatcher<SortedMatcher<ConstFst<StdArc> >, ilabel_lookahead_flags, FastLogAccumulator<StdArc> >, ilabel_lookahead_fst_type, LabelLookAheadRelabeler<StdArc> > StdILabelLookAheadFst; typedef MatcherFst<ConstFst<LogArc>, LabelLookAheadMatcher<SortedMatcher<ConstFst<LogArc> >, ilabel_lookahead_flags, FastLogAccumulator<LogArc> >, ilabel_lookahead_fst_type, LabelLookAheadRelabeler<LogArc> > LogILabelLookAheadFst; typedef MatcherFst<ConstFst<StdArc>, LabelLookAheadMatcher<SortedMatcher<ConstFst<StdArc> >, olabel_lookahead_flags, FastLogAccumulator<StdArc> >, olabel_lookahead_fst_type, LabelLookAheadRelabeler<StdArc> > StdOLabelLookAheadFst; typedef MatcherFst<ConstFst<LogArc>, LabelLookAheadMatcher<SortedMatcher<ConstFst<LogArc> >, olabel_lookahead_flags, FastLogAccumulator<LogArc> >, olabel_lookahead_fst_type, LabelLookAheadRelabeler<LogArc> > LogOLabelLookAheadFst; } // namespace fst #endif // FST_LIB_MATCHER_FST_FST_H__