// 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 #include #include namespace fst { // WRITABLE MATCHERS - these have the interface of Matchers (see // matcher.h) and these additional methods: // // template // 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 NullMatcherFstInit { public: typedef AddOnPair D; typedef AddOnImpl 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 MatcherFst : public ImplToExpandedFst< AddOnImpl > > { public: friend class StateIterator< MatcherFst >; friend class ArcIterator< MatcherFst >; typedef F FST; typedef M FstMatcher; typedef typename F::Arc Arc; typedef typename Arc::StateId StateId; typedef AddOnPair D; typedef AddOnImpl Impl; MatcherFst() : ImplToExpandedFst(new Impl(F(), N)) {} explicit MatcherFst(const F &fst) : ImplToExpandedFst(CreateImpl(fst, N)) {} explicit MatcherFst(const Fst &fst) : ImplToExpandedFst(CreateImpl(fst, N)) {} // See Fst<>::Copy() for doc. MatcherFst(const MatcherFst &fst, bool safe = false) : ImplToExpandedFst(fst, safe) {} // Get a copy of this MatcherFst. See Fst<>::Copy() for further doc. virtual MatcherFst *Copy(bool safe = false) const { return new MatcherFst(*this, safe); } // Read a MatcherFst from an input stream; return NULL on error static MatcherFst *Read(istream &strm, const FstReadOptions &opts) { Impl *impl = Impl::Read(strm, opts); return impl ? new MatcherFst(impl) : 0; } // Read a MatcherFst from a file; return NULL on error // Empty filename reads from standard input static MatcherFst *Read(const string &filename) { Impl *impl = ImplToExpandedFst::Read(filename); return impl ? new MatcherFst(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::WriteFile(filename); } virtual void InitStateIterator(StateIteratorData *data) const { return GetImpl()->InitStateIterator(data); } virtual void InitArcIterator(StateId s, ArcIteratorData *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 >::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 &fst, const string &name) { F ffst(fst); return CreateImpl(ffst, name); } explicit MatcherFst(Impl *impl) : ImplToExpandedFst(impl) {} // Makes visible to friends. void SetImpl(Impl *impl, bool own_impl = true) { ImplToFst< Impl, ExpandedFst >::SetImpl(impl, own_impl); } void operator=(const MatcherFst &fst); // disallow }; // Specialization fo MatcherFst. template class StateIterator< MatcherFst > : public StateIterator { public: explicit StateIterator(const MatcherFst &fst) : StateIterator(fst.GetImpl()->GetFst()) {} }; // Specialization for MatcherFst. template class ArcIterator< MatcherFst > : public ArcIterator { public: ArcIterator(const MatcherFst &fst, typename F::Arc::StateId s) : ArcIterator(fst.GetImpl()->GetFst(), s) {} }; // Specialization for MatcherFst template class Matcher< MatcherFst > { public: typedef MatcherFst 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 &matcher) { matcher_ = matcher.matcher_->Copy(); } ~Matcher() { delete matcher_; } Matcher *Copy() const { return new Matcher(*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 &); // disallow }; // Specialization for MatcherFst template class LookAheadMatcher< MatcherFst > { public: typedef MatcherFst 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 &matcher, bool safe = false) { matcher_ = matcher.matcher_->Copy(safe); } ~LookAheadMatcher() { delete matcher_; } // General matcher methods LookAheadMatcher *Copy(bool safe = false) const { return new LookAheadMatcher(*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 &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& fst, bool copy = false) { matcher_->InitLookAheadFst(fst, copy); } private: M *matcher_; void operator=(const LookAheadMatcher &); // disallow }; // // Useful aliases when using StdArc and LogArc. // // Arc look-ahead matchers extern const char arc_lookahead_fst_type[]; typedef MatcherFst, ArcLookAheadMatcher > >, arc_lookahead_fst_type> StdArcLookAheadFst; typedef MatcherFst, ArcLookAheadMatcher > >, 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, LabelLookAheadMatcher >, ilabel_lookahead_flags, FastLogAccumulator >, ilabel_lookahead_fst_type, LabelLookAheadRelabeler > StdILabelLookAheadFst; typedef MatcherFst, LabelLookAheadMatcher >, ilabel_lookahead_flags, FastLogAccumulator >, ilabel_lookahead_fst_type, LabelLookAheadRelabeler > LogILabelLookAheadFst; typedef MatcherFst, LabelLookAheadMatcher >, olabel_lookahead_flags, FastLogAccumulator >, olabel_lookahead_fst_type, LabelLookAheadRelabeler > StdOLabelLookAheadFst; typedef MatcherFst, LabelLookAheadMatcher >, olabel_lookahead_flags, FastLogAccumulator >, olabel_lookahead_fst_type, LabelLookAheadRelabeler > LogOLabelLookAheadFst; } // namespace fst #endif // FST_LIB_MATCHER_FST_FST_H__