1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// matcher.h 2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Licensed under the Apache License, Version 2.0 (the "License"); 4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you may not use this file except in compliance with the License. 5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You may obtain a copy of the License at 6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// http://www.apache.org/licenses/LICENSE-2.0 8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Unless required by applicable law or agreed to in writing, software 10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distributed under the License is distributed on an "AS IS" BASIS, 11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// See the License for the specific language governing permissions and 13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// limitations under the License. 14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Copyright 2005-2010 Google, Inc. 16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Author: riley@google.com (Michael Riley) 17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file 19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Classes to allow matching labels leaving FST states. 20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_MATCHER_H__ 22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_MATCHER_H__ 23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <algorithm> 25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <set> 26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/mutable-fst.h> // for all internal FST accessors 28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst { 31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// MATCHERS - these can find and iterate through requested labels at 33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// FST states. In the simplest form, these are just some associative 34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// map or search keyed on labels. More generally, they may 35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// implement matching special labels that represent sets of labels 36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// such as 'sigma' (all), 'rho' (rest), or 'phi' (fail). 37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The Matcher interface is: 38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// template <class F> 40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// class Matcher { 41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// public: 42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// typedef F FST; 43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// typedef F::Arc Arc; 44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// typedef typename Arc::StateId StateId; 45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// typedef typename Arc::Label Label; 46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// typedef typename Arc::Weight Weight; 47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // Required constructors. 49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Matcher(const F &fst, MatchType type); 50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // If safe=true, the copy is thread-safe. See Fst<>::Copy() 51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // for further doc. 52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Matcher(const Matcher &matcher, bool safe = false); 53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // If safe=true, the copy is thread-safe. See Fst<>::Copy() 55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // for further doc. 56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Matcher<F> *Copy(bool safe = false) const; 57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // Returns the match type that can be provided (depending on 59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // compatibility of the input FST). It is either 60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // the requested match type, MATCH_NONE, or MATCH_UNKNOWN. 61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // If 'test' is false, a constant time test is performed, but 62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // MATCH_UNKNOWN may be returned. If 'test' is true, 63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // a definite answer is returned, but may involve more costly 64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // computation (e.g., visiting the Fst). 65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// MatchType Type(bool test) const; 66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // Specifies the current state. 67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// void SetState(StateId s); 68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // This finds matches to a label at the current state. 70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // Returns true if a match found. kNoLabel matches any 71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // 'non-consuming' transitions, e.g., epsilon transitions, 72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // which do not require a matching symbol. 73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// bool Find(Label label); 74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // These iterate through any matches found: 75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// bool Done() const; // No more matches. 76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// const A& Value() const; // Current arc (when !Done) 77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// void Next(); // Advance to next arc (when !Done) 785b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin// // Initially and after SetState() the iterator methods 795b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin// // have undefined behavior until Find() is called. 80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // Return matcher FST. 82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// const F& GetFst() const; 83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // This specifies the known Fst properties as viewed from this 84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// // matcher. It takes as argument the input Fst's known properties. 85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// uint64 Properties(uint64 props) const; 86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// }; 87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 88dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin// 89dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin// MATCHER FLAGS (see also kLookAheadFlags in lookahead-matcher.h) 90dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin// 91dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin// Matcher prefers being used as the matching side in composition. 92dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkinconst uint32 kPreferMatch = 0x00000001; 93dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin 94dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin// Matcher needs to be used as the matching side in composition. 95dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkinconst uint32 kRequireMatch = 0x00000002; 96dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin 97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Flags used for basic matchers (see also lookahead.h). 98dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkinconst uint32 kMatcherFlags = kPreferMatch | kRequireMatch; 99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Matcher interface, templated on the Arc definition; used 101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// for matcher specializations that are returned by the 102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// InitMatcher Fst method. 103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> 104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass MatcherBase { 105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef A Arc; 107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename A::StateId StateId; 108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename A::Label Label; 109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename A::Weight Weight; 110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual ~MatcherBase() {} 112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual MatcherBase<A> *Copy(bool safe = false) const = 0; 114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual MatchType Type(bool test) const = 0; 115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetState(StateId s) { SetState_(s); } 116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Find(Label label) { return Find_(label); } 117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Done() const { return Done_(); } 118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const A& Value() const { return Value_(); } 119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void Next() { Next_(); } 120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual const Fst<A> &GetFst() const = 0; 121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual uint64 Properties(uint64 props) const = 0; 122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual uint32 Flags() const { return 0; } 123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void SetState_(StateId s) = 0; 125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual bool Find_(Label label) = 0; 126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual bool Done_() const = 0; 127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual const A& Value_() const = 0; 128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void Next_() = 0; 129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// A matcher that expects sorted labels on the side to be matched. 133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// If match_type == MATCH_INPUT, epsilons match the implicit self loop 134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Arc(kNoLabel, 0, Weight::One(), current_state) as well as any 135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// actual epsilon transitions. If match_type == MATCH_OUTPUT, then 136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Arc(0, kNoLabel, Weight::One(), current_state) is instead matched. 137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class F> 138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass SortedMatcher : public MatcherBase<typename F::Arc> { 139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef F FST; 141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::Arc Arc; 142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Labels >= binary_label will be searched for by binary search, 147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // o.w. linear search is used. 148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SortedMatcher(const F &fst, MatchType match_type, 149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label binary_label = 1) 150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : fst_(fst.Copy()), 151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson s_(kNoStateId), 152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_(0), 153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_(match_type), 154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson binary_label_(binary_label), 155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_label_(kNoLabel), 156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson narcs_(0), 157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_(kNoLabel, 0, Weight::One(), kNoStateId), 158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_(false) { 159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson switch(match_type_) { 160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson case MATCH_INPUT: 161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson case MATCH_NONE: 162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson break; 163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson case MATCH_OUTPUT: 164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson swap(loop_.ilabel, loop_.olabel); 165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson break; 166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson default: 167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "SortedMatcher: bad match type"; 168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_ = MATCH_NONE; 169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SortedMatcher(const SortedMatcher<F> &matcher, bool safe = false) 174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : fst_(matcher.fst_->Copy(safe)), 175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson s_(kNoStateId), 176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_(0), 177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_(matcher.match_type_), 178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson binary_label_(matcher.binary_label_), 179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_label_(kNoLabel), 180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson narcs_(0), 181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_(matcher.loop_), 182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_(matcher.error_) {} 183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual ~SortedMatcher() { 185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (aiter_) 186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete aiter_; 187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete fst_; 188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual SortedMatcher<F> *Copy(bool safe = false) const { 191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return new SortedMatcher<F>(*this, safe); 192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual MatchType Type(bool test) const { 195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_type_ == MATCH_NONE) 196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return match_type_; 197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 true_prop = match_type_ == MATCH_INPUT ? 199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted : kOLabelSorted; 200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 false_prop = match_type_ == MATCH_INPUT ? 201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kNotILabelSorted : kNotOLabelSorted; 202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 props = fst_->Properties(true_prop | false_prop, test); 203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (props & true_prop) 205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return match_type_; 206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (props & false_prop) 207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MATCH_NONE; 208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MATCH_UNKNOWN; 210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetState(StateId s) { 213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (s_ == s) 214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return; 215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson s_ = s; 216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_type_ == MATCH_NONE) { 217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "SortedMatcher: bad match type"; 218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (aiter_) 221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete aiter_; 222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_ = new ArcIterator<F>(*fst_, s); 223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->SetFlags(kArcNoCache, kArcNoCache); 224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson narcs_ = internal::NumArcs(*fst_, s); 225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_.nextstate = s; 226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 2285b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin bool Find(Label match_label) { 2295b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin exact_match_ = true; 2305b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin if (error_) { 2315b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin current_loop_ = false; 2325b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin match_label_ = kNoLabel; 2335b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin return false; 2345b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin } 2355b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin current_loop_ = match_label == 0; 2365b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin match_label_ = match_label == kNoLabel ? 0 : match_label; 2375b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin if (Search()) { 2385b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin return true; 2395b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin } else { 2405b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin return current_loop_; 2415b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin } 2425b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin } 2435b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin 2445b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin // Positions matcher to the first position where inserting 2455b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin // match_label would maintain the sort order. 2465b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin void LowerBound(Label match_label) { 2475b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin exact_match_ = false; 2485b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin current_loop_ = false; 2495b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin if (error_) { 2505b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin match_label_ = kNoLabel; 2515b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin return; 2525b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin } 2535b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin match_label_ = match_label; 2545b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin Search(); 2555b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin } 256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 2575b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin // After Find(), returns false if no more exact matches. 2585b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin // After LowerBound(), returns false if no more arcs. 259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Done() const { 260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (current_loop_) 261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (aiter_->Done()) 263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 2645b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin if (!exact_match_) 2655b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin return false; 266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->SetFlags( 267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_ == MATCH_INPUT ? kArcILabelValue : kArcOLabelValue, 268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kArcValueFlags); 269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label label = match_type_ == MATCH_INPUT ? 270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->Value().ilabel : aiter_->Value().olabel; 271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return label != match_label_; 272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Arc& Value() const { 275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (current_loop_) { 276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return loop_; 277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->SetFlags(kArcValueFlags, kArcValueFlags); 279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return aiter_->Value(); 280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 281f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void Next() { 283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (current_loop_) 284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson current_loop_ = false; 285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->Next(); 287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual const F &GetFst() const { return *fst_; } 290f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 291f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual uint64 Properties(uint64 inprops) const { 292f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 outprops = inprops; 293f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (error_) outprops |= kError; 294f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops; 295f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 2975b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin size_t Position() const { return aiter_ ? aiter_->Position() : 0; } 2985b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin 299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void SetState_(StateId s) { SetState(s); } 301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual bool Find_(Label label) { return Find(label); } 302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual bool Done_() const { return Done(); } 303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual const Arc& Value_() const { return Value(); } 304f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void Next_() { Next(); } 305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 3065b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin bool Search(); 3075b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin 308f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const F *fst_; 309f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson StateId s_; // Current state 310f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ArcIterator<F> *aiter_; // Iterator for current state 311f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType match_type_; // Type of match to perform 312f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label binary_label_; // Least label for binary search 313f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label match_label_; // Current label to be matched 314f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size_t narcs_; // Current state arc count 315f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Arc loop_; // For non-consuming symbols 316f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool current_loop_; // Current arc is the implicit loop 3175b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin bool exact_match_; // Exact match or lower bound? 318f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool error_; // Error encountered 319f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 320f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const SortedMatcher<F> &); // Disallow 321f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 322f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 3235b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin// Returns true iff match to match_label_. Positions arc iterator at 3245b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin// lower bound regardless. 325f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class F> inline 3265b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkinbool SortedMatcher<F>::Search() { 327f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->SetFlags( 328f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_ == MATCH_INPUT ? kArcILabelValue : kArcOLabelValue, 329f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kArcValueFlags); 330f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_label_ >= binary_label_) { 331f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Binary search for match. 332f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size_t low = 0; 333f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size_t high = narcs_; 334f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson while (low < high) { 335f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson size_t mid = (low + high) / 2; 336f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->Seek(mid); 337f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label label = match_type_ == MATCH_INPUT ? 338f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->Value().ilabel : aiter_->Value().olabel; 339f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (label > match_label_) { 340f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson high = mid; 341f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (label < match_label_) { 342f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson low = mid + 1; 343f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 344f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // find first matching label (when non-determinism) 345f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson for (size_t i = mid; i > low; --i) { 346f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->Seek(i - 1); 347f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson label = match_type_ == MATCH_INPUT ? aiter_->Value().ilabel : 348f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->Value().olabel; 349f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (label != match_label_) { 350f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->Seek(i); 351f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 352f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 353f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 354f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 355f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 356f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 3575b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin aiter_->Seek(low); 3585b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin return false; 359f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 360f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Linear search for match. 361f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson for (aiter_->Reset(); !aiter_->Done(); aiter_->Next()) { 362f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label label = match_type_ == MATCH_INPUT ? 363f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter_->Value().ilabel : aiter_->Value().olabel; 364f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (label == match_label_) { 365f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 366f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 367f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (label > match_label_) 368f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson break; 369f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 3705b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin return false; 371f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 372f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 373f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 374f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 375f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specifies whether during matching we rewrite both the input and output sides. 376f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonenum MatcherRewriteMode { 377f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MATCHER_REWRITE_AUTO = 0, // Rewrites both sides iff acceptor. 378f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MATCHER_REWRITE_ALWAYS, 379f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MATCHER_REWRITE_NEVER 380f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 381f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 382f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 383f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// For any requested label that doesn't match at a state, this matcher 384f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// considers all transitions that match the label 'rho_label' (rho = 385f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 'rest'). Each such rho transition found is returned with the 386f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// rho_label rewritten as the requested label (both sides if an 387f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// acceptor, or if 'rewrite_both' is true and both input and output 388f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// labels of the found transition are 'rho_label'). If 'rho_label' is 389f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// kNoLabel, this special matching is not done. RhoMatcher is 390f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// templated itself on a matcher, which is used to perform the 391f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// underlying matching. By default, the underlying matcher is 392f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// constructed by RhoMatcher. The user can instead pass in this 393f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// object; in that case, RhoMatcher takes its ownership. 394f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M> 395f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass RhoMatcher : public MatcherBase<typename M::Arc> { 396f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 397f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M::FST FST; 398f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M::Arc Arc; 399f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 400f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 401f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 402f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 403f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson RhoMatcher(const FST &fst, 404f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType match_type, 405f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label rho_label = kNoLabel, 406f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatcherRewriteMode rewrite_mode = MATCHER_REWRITE_AUTO, 407f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *matcher = 0) 408f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : matcher_(matcher ? matcher : new M(fst, match_type)), 409f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_(match_type), 410f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rho_label_(rho_label), 411f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_(false) { 412f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_type == MATCH_BOTH) { 413f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "RhoMatcher: bad match type"; 414f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_ = MATCH_NONE; 415f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 416f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 417f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rho_label == 0) { 418f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "RhoMatcher: 0 cannot be used as rho_label"; 419f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rho_label_ = kNoLabel; 420f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 421f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 422f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 423f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rewrite_mode == MATCHER_REWRITE_AUTO) 424f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_ = fst.Properties(kAcceptor, true); 425f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (rewrite_mode == MATCHER_REWRITE_ALWAYS) 426f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_ = true; 427f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 428f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_ = false; 429f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 430f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 431f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson RhoMatcher(const RhoMatcher<M> &matcher, bool safe = false) 432f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : matcher_(new M(*matcher.matcher_, safe)), 433f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_(matcher.match_type_), 434f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rho_label_(matcher.rho_label_), 435f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_(matcher.rewrite_both_), 436f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_(matcher.error_) {} 437f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 438f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual ~RhoMatcher() { 439f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete matcher_; 440f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 441f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 442f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual RhoMatcher<M> *Copy(bool safe = false) const { 443f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return new RhoMatcher<M>(*this, safe); 444f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 445f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 446f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual MatchType Type(bool test) const { return matcher_->Type(test); } 447f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 448f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetState(StateId s) { 449f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->SetState(s); 450f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson has_rho_ = rho_label_ != kNoLabel; 451f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 452f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 453f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Find(Label match_label) { 454f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_label == rho_label_ && rho_label_ != kNoLabel) { 455f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "RhoMatcher::Find: bad label (rho)"; 456f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 457f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 458f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 459f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (matcher_->Find(match_label)) { 460f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rho_match_ = kNoLabel; 461f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 462f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (has_rho_ && match_label != 0 && match_label != kNoLabel && 463f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson (has_rho_ = matcher_->Find(rho_label_))) { 464f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rho_match_ = match_label; 465f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 466f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 467f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 468f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 469f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 470f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 471f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Done() const { return matcher_->Done(); } 472f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 473f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Arc& Value() const { 474f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rho_match_ == kNoLabel) { 475f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return matcher_->Value(); 476f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 477f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rho_arc_ = matcher_->Value(); 478f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rewrite_both_) { 479f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rho_arc_.ilabel == rho_label_) 480f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rho_arc_.ilabel = rho_match_; 481f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rho_arc_.olabel == rho_label_) 482f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rho_arc_.olabel = rho_match_; 483f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (match_type_ == MATCH_INPUT) { 484f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rho_arc_.ilabel = rho_match_; 485f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 486f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rho_arc_.olabel = rho_match_; 487f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 488f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return rho_arc_; 489f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 490f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 491f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 492f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void Next() { matcher_->Next(); } 493f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 494f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual const FST &GetFst() const { return matcher_->GetFst(); } 495f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 496f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual uint64 Properties(uint64 props) const; 497f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 498dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin virtual uint32 Flags() const { 499dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (rho_label_ == kNoLabel || match_type_ == MATCH_NONE) 500dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return matcher_->Flags(); 501dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return matcher_->Flags() | kRequireMatch; 502dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 503dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin 504f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 505f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void SetState_(StateId s) { SetState(s); } 506f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual bool Find_(Label label) { return Find(label); } 507f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual bool Done_() const { return Done(); } 508f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual const Arc& Value_() const { return Value(); } 509f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void Next_() { Next(); } 510f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 511f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *matcher_; 512f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType match_type_; // Type of match requested 513f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label rho_label_; // Label that represents the rho transition 514f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool rewrite_both_; // Rewrite both sides when both are 'rho_label_' 515f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool has_rho_; // Are there possibly rhos at the current state? 516f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label rho_match_; // Current label that matches rho transition 517f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson mutable Arc rho_arc_; // Arc to return when rho match 518f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool error_; // Error encountered 519f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 520f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const RhoMatcher<M> &); // Disallow 521f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 522f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 523f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M> inline 524f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonuint64 RhoMatcher<M>::Properties(uint64 inprops) const { 525f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 outprops = matcher_->Properties(inprops); 526f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (error_) outprops |= kError; 527f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 528f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_type_ == MATCH_NONE) { 529f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops; 530f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (match_type_ == MATCH_INPUT) { 531f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rewrite_both_) { 532f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kODeterministic | kNonODeterministic | kString | 533f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted | kNotILabelSorted | 534f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kOLabelSorted | kNotOLabelSorted); 535f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 536f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kODeterministic | kAcceptor | kString | 537f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted | kNotILabelSorted); 538f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 539f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (match_type_ == MATCH_OUTPUT) { 540f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rewrite_both_) { 541f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kIDeterministic | kNonIDeterministic | kString | 542f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted | kNotILabelSorted | 543f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kOLabelSorted | kNotOLabelSorted); 544f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 545f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kIDeterministic | kAcceptor | kString | 546f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kOLabelSorted | kNotOLabelSorted); 547f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 548f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 549f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Shouldn't ever get here. 550f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "RhoMatcher:: bad match type: " << match_type_; 551f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return 0; 552f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 553f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 554f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 555f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 556f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// For any requested label, this matcher considers all transitions 557f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// that match the label 'sigma_label' (sigma = "any"), and this in 558f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// additions to transitions with the requested label. Each such sigma 559f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// transition found is returned with the sigma_label rewritten as the 560f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// requested label (both sides if an acceptor, or if 'rewrite_both' is 561f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// true and both input and output labels of the found transition are 562f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 'sigma_label'). If 'sigma_label' is kNoLabel, this special 563f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// matching is not done. SigmaMatcher is templated itself on a 564f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// matcher, which is used to perform the underlying matching. By 565f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// default, the underlying matcher is constructed by SigmaMatcher. 566f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// The user can instead pass in this object; in that case, 567f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// SigmaMatcher takes its ownership. 568f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M> 569f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass SigmaMatcher : public MatcherBase<typename M::Arc> { 570f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 571f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M::FST FST; 572f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M::Arc Arc; 573f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 574f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 575f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 576f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 577f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SigmaMatcher(const FST &fst, 578f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType match_type, 579f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label sigma_label = kNoLabel, 580f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatcherRewriteMode rewrite_mode = MATCHER_REWRITE_AUTO, 581f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *matcher = 0) 582f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : matcher_(matcher ? matcher : new M(fst, match_type)), 583f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_(match_type), 584f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_label_(sigma_label), 585f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_(false) { 586f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_type == MATCH_BOTH) { 587f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "SigmaMatcher: bad match type"; 588f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_ = MATCH_NONE; 589f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 590f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 591f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (sigma_label == 0) { 592f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "SigmaMatcher: 0 cannot be used as sigma_label"; 593f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_label_ = kNoLabel; 594f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 595f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 596f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 597f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rewrite_mode == MATCHER_REWRITE_AUTO) 598f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_ = fst.Properties(kAcceptor, true); 599f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (rewrite_mode == MATCHER_REWRITE_ALWAYS) 600f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_ = true; 601f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 602f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_ = false; 603f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 604f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 605f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SigmaMatcher(const SigmaMatcher<M> &matcher, bool safe = false) 606f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : matcher_(new M(*matcher.matcher_, safe)), 607f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_(matcher.match_type_), 608f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_label_(matcher.sigma_label_), 609f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_(matcher.rewrite_both_), 610f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_(matcher.error_) {} 611f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 612f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual ~SigmaMatcher() { 613f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete matcher_; 614f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 615f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 616f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual SigmaMatcher<M> *Copy(bool safe = false) const { 617f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return new SigmaMatcher<M>(*this, safe); 618f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 619f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 620f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual MatchType Type(bool test) const { return matcher_->Type(test); } 621f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 622f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetState(StateId s) { 623f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->SetState(s); 624f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson has_sigma_ = 625f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_label_ != kNoLabel ? matcher_->Find(sigma_label_) : false; 626f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 627f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 628f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Find(Label match_label) { 629f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_label_ = match_label; 630f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_label == sigma_label_ && sigma_label_ != kNoLabel) { 631f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "SigmaMatcher::Find: bad label (sigma)"; 632f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 633f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 634f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 635f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (matcher_->Find(match_label)) { 636f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_match_ = kNoLabel; 637f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 638f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (has_sigma_ && match_label != 0 && match_label != kNoLabel && 639f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->Find(sigma_label_)) { 640f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_match_ = match_label; 641f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 642f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 643f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 644f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 645f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 646f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 647f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Done() const { 648f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return matcher_->Done(); 649f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 650f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 651f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Arc& Value() const { 652f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (sigma_match_ == kNoLabel) { 653f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return matcher_->Value(); 654f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 655f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_arc_ = matcher_->Value(); 656f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rewrite_both_) { 657f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (sigma_arc_.ilabel == sigma_label_) 658f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_arc_.ilabel = sigma_match_; 659f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (sigma_arc_.olabel == sigma_label_) 660f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_arc_.olabel = sigma_match_; 661f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (match_type_ == MATCH_INPUT) { 662f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_arc_.ilabel = sigma_match_; 663f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 664f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_arc_.olabel = sigma_match_; 665f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 666f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return sigma_arc_; 667f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 668f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 669f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 670f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void Next() { 671f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->Next(); 672f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (matcher_->Done() && has_sigma_ && (sigma_match_ == kNoLabel) && 673f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson (match_label_ > 0)) { 674f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->Find(sigma_label_); 675f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson sigma_match_ = match_label_; 676f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 677f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 678f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 679f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual const FST &GetFst() const { return matcher_->GetFst(); } 680f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 681f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual uint64 Properties(uint64 props) const; 682f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 683dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin virtual uint32 Flags() const { 684dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (sigma_label_ == kNoLabel || match_type_ == MATCH_NONE) 685dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return matcher_->Flags(); 686dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin // kRequireMatch temporarily disabled until issues 687dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin // in //speech/gaudi/annotation/util/denorm are resolved. 688dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin // return matcher_->Flags() | kRequireMatch; 689dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return matcher_->Flags(); 690dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 691dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin 692f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonprivate: 693f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void SetState_(StateId s) { SetState(s); } 694f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual bool Find_(Label label) { return Find(label); } 695f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual bool Done_() const { return Done(); } 696f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual const Arc& Value_() const { return Value(); } 697f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void Next_() { Next(); } 698f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 699f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *matcher_; 700f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType match_type_; // Type of match requested 701f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label sigma_label_; // Label that represents the sigma transition 702f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool rewrite_both_; // Rewrite both sides when both are 'sigma_label_' 703f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool has_sigma_; // Are there sigmas at the current state? 704f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label sigma_match_; // Current label that matches sigma transition 705f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson mutable Arc sigma_arc_; // Arc to return when sigma match 706f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label match_label_; // Label being matched 707f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool error_; // Error encountered 708f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 709f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const SigmaMatcher<M> &); // disallow 710f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 711f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 712f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M> inline 713f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonuint64 SigmaMatcher<M>::Properties(uint64 inprops) const { 714f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 outprops = matcher_->Properties(inprops); 715f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (error_) outprops |= kError; 716f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 717f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_type_ == MATCH_NONE) { 718f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops; 719f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (rewrite_both_) { 720f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kIDeterministic | kNonIDeterministic | 721f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kODeterministic | kNonODeterministic | 722f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted | kNotILabelSorted | 723f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kOLabelSorted | kNotOLabelSorted | 724f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kString); 725f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (match_type_ == MATCH_INPUT) { 726f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kIDeterministic | kNonIDeterministic | 727f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kODeterministic | kNonODeterministic | 728f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted | kNotILabelSorted | 729f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kString | kAcceptor); 730f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (match_type_ == MATCH_OUTPUT) { 731f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kIDeterministic | kNonIDeterministic | 732f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kODeterministic | kNonODeterministic | 733f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kOLabelSorted | kNotOLabelSorted | 734f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kString | kAcceptor); 735f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 736f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Shouldn't ever get here. 737f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "SigmaMatcher:: bad match type: " << match_type_; 738f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return 0; 739f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 740f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 741f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 742f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 743f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// For any requested label that doesn't match at a state, this matcher 744f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// considers the *unique* transition that matches the label 'phi_label' 745f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// (phi = 'fail'), and recursively looks for a match at its 746f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// destination. When 'phi_loop' is true, if no match is found but a 747f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// phi self-loop is found, then the phi transition found is returned 748f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// with the phi_label rewritten as the requested label (both sides if 749f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// an acceptor, or if 'rewrite_both' is true and both input and output 750f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// labels of the found transition are 'phi_label'). If 'phi_label' is 751f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// kNoLabel, this special matching is not done. PhiMatcher is 752f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// templated itself on a matcher, which is used to perform the 753f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// underlying matching. By default, the underlying matcher is 754f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// constructed by PhiMatcher. The user can instead pass in this 755f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// object; in that case, PhiMatcher takes its ownership. 756f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Warning: phi non-determinism not supported (for simplicity). 757f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M> 758f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass PhiMatcher : public MatcherBase<typename M::Arc> { 759f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 760f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M::FST FST; 761f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M::Arc Arc; 762f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 763f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 764f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 765f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 766f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson PhiMatcher(const FST &fst, 767f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType match_type, 768f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label phi_label = kNoLabel, 769f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool phi_loop = true, 770f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatcherRewriteMode rewrite_mode = MATCHER_REWRITE_AUTO, 771f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *matcher = 0) 772f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : matcher_(matcher ? matcher : new M(fst, match_type)), 773f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_(match_type), 774f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_label_(phi_label), 775f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson state_(kNoStateId), 776f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_loop_(phi_loop), 777f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_(false) { 778f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_type == MATCH_BOTH) { 779f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "PhiMatcher: bad match type"; 780f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_ = MATCH_NONE; 781f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 782f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 783f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 784f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rewrite_mode == MATCHER_REWRITE_AUTO) 785f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_ = fst.Properties(kAcceptor, true); 786f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (rewrite_mode == MATCHER_REWRITE_ALWAYS) 787f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_ = true; 788f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 789f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_ = false; 790f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 791f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 792f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson PhiMatcher(const PhiMatcher<M> &matcher, bool safe = false) 793f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : matcher_(new M(*matcher.matcher_, safe)), 794f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson match_type_(matcher.match_type_), 795f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_label_(matcher.phi_label_), 796f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson rewrite_both_(matcher.rewrite_both_), 797f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson state_(kNoStateId), 798f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_loop_(matcher.phi_loop_), 799f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_(matcher.error_) {} 800f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 801f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual ~PhiMatcher() { 802f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete matcher_; 803f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 804f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 805f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual PhiMatcher<M> *Copy(bool safe = false) const { 806f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return new PhiMatcher<M>(*this, safe); 807f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 808f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 809f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual MatchType Type(bool test) const { return matcher_->Type(test); } 810f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 811f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetState(StateId s) { 812f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->SetState(s); 813f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson state_ = s; 814f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson has_phi_ = phi_label_ != kNoLabel; 815f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 816f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 817f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Find(Label match_label); 818f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 819f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Done() const { return matcher_->Done(); } 820f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 821f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Arc& Value() const { 822f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if ((phi_match_ == kNoLabel) && (phi_weight_ == Weight::One())) { 823f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return matcher_->Value(); 824dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } else if (phi_match_ == 0) { // Virtual epsilon loop 825dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin phi_arc_ = Arc(kNoLabel, 0, Weight::One(), state_); 826dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (match_type_ == MATCH_OUTPUT) 827dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin swap(phi_arc_.ilabel, phi_arc_.olabel); 828dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return phi_arc_; 829f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 830f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_arc_ = matcher_->Value(); 831f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_arc_.weight = Times(phi_weight_, phi_arc_.weight); 832dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (phi_match_ != kNoLabel) { // Phi loop match 833f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rewrite_both_) { 834f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (phi_arc_.ilabel == phi_label_) 835f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_arc_.ilabel = phi_match_; 836f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (phi_arc_.olabel == phi_label_) 837f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_arc_.olabel = phi_match_; 838f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (match_type_ == MATCH_INPUT) { 839f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_arc_.ilabel = phi_match_; 840f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 841f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_arc_.olabel = phi_match_; 842f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 843f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 844f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return phi_arc_; 845f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 846f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 847f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 848f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void Next() { matcher_->Next(); } 849f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 850f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual const FST &GetFst() const { return matcher_->GetFst(); } 851f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 852f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual uint64 Properties(uint64 props) const; 853f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 854dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin virtual uint32 Flags() const { 855dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (phi_label_ == kNoLabel || match_type_ == MATCH_NONE) 856dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return matcher_->Flags(); 857dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return matcher_->Flags() | kRequireMatch; 858dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 859dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin 860f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonprivate: 861f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void SetState_(StateId s) { SetState(s); } 862f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual bool Find_(Label label) { return Find(label); } 863f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual bool Done_() const { return Done(); } 864f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual const Arc& Value_() const { return Value(); } 865f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson virtual void Next_() { Next(); } 866f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 867f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *matcher_; 868f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType match_type_; // Type of match requested 869f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label phi_label_; // Label that represents the phi transition 870f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool rewrite_both_; // Rewrite both sides when both are 'phi_label_' 871f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool has_phi_; // Are there possibly phis at the current state? 872f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label phi_match_; // Current label that matches phi loop 873f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson mutable Arc phi_arc_; // Arc to return 874f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson StateId state_; // State where looking for matches 875f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Weight phi_weight_; // Product of the weights of phi transitions taken 876f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool phi_loop_; // When true, phi self-loop are allowed and treated 877f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // as rho (required for Aho-Corasick) 878f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool error_; // Error encountered 879f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 880f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const PhiMatcher<M> &); // disallow 881f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 882f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 883f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M> inline 884f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonbool PhiMatcher<M>::Find(Label match_label) { 885dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (match_label == phi_label_ && phi_label_ != kNoLabel && phi_label_ != 0) { 886dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin FSTERROR() << "PhiMatcher::Find: bad label (phi): " << phi_label_; 887f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 888f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 889f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 890f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->SetState(state_); 891f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_match_ = kNoLabel; 892f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_weight_ = Weight::One(); 893dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (phi_label_ == 0) { // When 'phi_label_ == 0', 894dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (match_label == kNoLabel) // there are no more true epsilon arcs, 895dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return false; 896dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (match_label == 0) { // but virtual eps loop need to be returned 897dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (!matcher_->Find(kNoLabel)) { 898dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return matcher_->Find(0); 899dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } else { 900dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin phi_match_ = 0; 901dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin return true; 902dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 903dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 904dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 905f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!has_phi_ || match_label == 0 || match_label == kNoLabel) 906f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return matcher_->Find(match_label); 907f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson StateId state = state_; 908f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson while (!matcher_->Find(match_label)) { 909dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin // Look for phi transition (if phi_label_ == 0, we need to look 910dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin // for -1 to avoid getting the virtual self-loop) 911dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (!matcher_->Find(phi_label_ == 0 ? -1 : phi_label_)) 912f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 913f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (phi_loop_ && matcher_->Value().nextstate == state) { 914f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_match_ = match_label; 915f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 916f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 917f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson phi_weight_ = Times(phi_weight_, matcher_->Value().weight); 918f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson state = matcher_->Value().nextstate; 919f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->Next(); 920f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!matcher_->Done()) { 921f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "PhiMatcher: phi non-determinism not supported"; 922f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson error_ = true; 923f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 924f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->SetState(state); 925f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 926f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 927f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 928f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 929f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M> inline 930f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonuint64 PhiMatcher<M>::Properties(uint64 inprops) const { 931f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 outprops = matcher_->Properties(inprops); 932f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (error_) outprops |= kError; 933f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 934f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_type_ == MATCH_NONE) { 935f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops; 936f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (match_type_ == MATCH_INPUT) { 937dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (phi_label_ == 0) { 938dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin outprops &= ~kEpsilons | ~kIEpsilons | ~kOEpsilons; 939dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin outprops |= kNoEpsilons | kNoIEpsilons; 940dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 941f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rewrite_both_) { 942f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kODeterministic | kNonODeterministic | kString | 943f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted | kNotILabelSorted | 944f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kOLabelSorted | kNotOLabelSorted); 945f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 946f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kODeterministic | kAcceptor | kString | 947f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted | kNotILabelSorted | 948f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kOLabelSorted | kNotOLabelSorted); 949f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 950f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (match_type_ == MATCH_OUTPUT) { 951dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (phi_label_ == 0) { 952dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin outprops &= ~kEpsilons | ~kIEpsilons | ~kOEpsilons; 953dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin outprops |= kNoEpsilons | kNoOEpsilons; 954dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 955f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (rewrite_both_) { 956f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kIDeterministic | kNonIDeterministic | kString | 957f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted | kNotILabelSorted | 958f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kOLabelSorted | kNotOLabelSorted); 959f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 960f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops & ~(kIDeterministic | kAcceptor | kString | 961f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted | kNotILabelSorted | 962f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kOLabelSorted | kNotOLabelSorted); 963f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 964f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 965f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Shouldn't ever get here. 966f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "PhiMatcher:: bad match type: " << match_type_; 967f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return 0; 968f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 969f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 970f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 971f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 972f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 973f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// MULTI-EPS MATCHER FLAGS 974f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 975f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 976f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Return multi-epsilon arcs for Find(kNoLabel). 977f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonconst uint32 kMultiEpsList = 0x00000001; 978f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 979f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Return a kNolabel loop for Find(multi_eps). 980f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonconst uint32 kMultiEpsLoop = 0x00000002; 981f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 982f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// MultiEpsMatcher: allows treating multiple non-0 labels as 983f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// non-consuming labels in addition to 0 that is always 984f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// non-consuming. Precise behavior controlled by 'flags' argument. By 985f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// default, the underlying matcher is constructed by 986f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// MultiEpsMatcher. The user can instead pass in this object; in that 987f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// case, MultiEpsMatcher takes its ownership iff 'own_matcher' is 988f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// true. 989f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M> 990f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass MultiEpsMatcher { 991f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 992f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M::FST FST; 993f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M::Arc Arc; 994f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 995f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 996f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 997f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 998f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MultiEpsMatcher(const FST &fst, MatchType match_type, 999f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint32 flags = (kMultiEpsLoop | kMultiEpsList), 1000f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *matcher = 0, bool own_matcher = true) 1001f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : matcher_(matcher ? matcher : new M(fst, match_type)), 1002f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson flags_(flags), 1003f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson own_matcher_(matcher ? own_matcher : true) { 1004f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_type == MATCH_INPUT) { 1005f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_.ilabel = kNoLabel; 1006f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_.olabel = 0; 1007f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 1008f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_.ilabel = 0; 1009f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_.olabel = kNoLabel; 1010f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1011f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_.weight = Weight::One(); 1012f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_.nextstate = kNoStateId; 1013f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1014f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1015f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MultiEpsMatcher(const MultiEpsMatcher<M> &matcher, bool safe = false) 1016f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : matcher_(new M(*matcher.matcher_, safe)), 1017f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson flags_(matcher.flags_), 1018f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson own_matcher_(true), 1019f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson multi_eps_labels_(matcher.multi_eps_labels_), 1020f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_(matcher.loop_) { 1021f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_.nextstate = kNoStateId; 1022f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1023f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1024f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ~MultiEpsMatcher() { 1025f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (own_matcher_) 1026f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete matcher_; 1027f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1028f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1029f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MultiEpsMatcher<M> *Copy(bool safe = false) const { 1030f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return new MultiEpsMatcher<M>(*this, safe); 1031f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1032f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1033f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType Type(bool test) const { return matcher_->Type(test); } 1034f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1035f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetState(StateId s) { 1036f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->SetState(s); 1037f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson loop_.nextstate = s; 1038f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1039f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1040f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Find(Label match_label); 1041f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1042f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Done() const { 1043f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return done_; 1044f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1045f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1046f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Arc& Value() const { 1047f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return current_loop_ ? loop_ : matcher_->Value(); 1048f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1049f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1050f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void Next() { 1051f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!current_loop_) { 1052f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher_->Next(); 1053f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson done_ = matcher_->Done(); 1054f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (done_ && multi_eps_iter_ != multi_eps_labels_.End()) { 1055f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ++multi_eps_iter_; 1056f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson while ((multi_eps_iter_ != multi_eps_labels_.End()) && 1057f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson !matcher_->Find(*multi_eps_iter_)) 1058f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ++multi_eps_iter_; 1059f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (multi_eps_iter_ != multi_eps_labels_.End()) 1060f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson done_ = false; 1061f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 1062f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson done_ = !matcher_->Find(kNoLabel); 1063f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1064f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1065f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 1066f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson done_ = true; 1067f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1068f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1069f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1070f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FST &GetFst() const { return matcher_->GetFst(); } 1071f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1072f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 Properties(uint64 props) const { return matcher_->Properties(props); } 1073f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1074f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint32 Flags() const { return matcher_->Flags(); } 1075f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1076f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void AddMultiEpsLabel(Label label) { 1077f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (label == 0) { 1078f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "MultiEpsMatcher: Bad multi-eps label: 0"; 1079f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 1080f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson multi_eps_labels_.Insert(label); 1081f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1082f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1083f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 10845b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin void RemoveMultiEpsLabel(Label label) { 10855b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin if (label == 0) { 10865b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin FSTERROR() << "MultiEpsMatcher: Bad multi-eps label: 0"; 10875b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin } else { 10885b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin multi_eps_labels_.Erase(label); 10895b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin } 10905b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin } 10915b6dc79427b8f7eeb6a7ff68034ab8548ce670eaAlexander Gutkin 1092f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void ClearMultiEpsLabels() { 1093f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson multi_eps_labels_.Clear(); 1094f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1095f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1096f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonprivate: 1097f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *matcher_; 1098f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint32 flags_; 1099f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool own_matcher_; // Does this class delete the matcher? 1100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Multi-eps label set 1102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson CompactSet<Label, kNoLabel> multi_eps_labels_; 1103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typename CompactSet<Label, kNoLabel>::const_iterator multi_eps_iter_; 1104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool current_loop_; // Current arc is the implicit loop 1106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson mutable Arc loop_; // For non-consuming symbols 1107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool done_; // Matching done 1108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const MultiEpsMatcher<M> &); // Disallow 1110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 1111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M> inline 1113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonbool MultiEpsMatcher<M>::Find(Label match_label) { 1114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson multi_eps_iter_ = multi_eps_labels_.End(); 1115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson current_loop_ = false; 1116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool ret; 1117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (match_label == 0) { 1118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ret = matcher_->Find(0); 1119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (match_label == kNoLabel) { 1120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (flags_ & kMultiEpsList) { 1121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // return all non-consuming arcs (incl. epsilon) 1122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson multi_eps_iter_ = multi_eps_labels_.Begin(); 1123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson while ((multi_eps_iter_ != multi_eps_labels_.End()) && 1124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson !matcher_->Find(*multi_eps_iter_)) 1125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ++multi_eps_iter_; 1126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (multi_eps_iter_ != multi_eps_labels_.End()) 1127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ret = true; 1128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 1129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ret = matcher_->Find(kNoLabel); 1130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 1131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // return all epsilon arcs 1132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ret = matcher_->Find(kNoLabel); 1133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if ((flags_ & kMultiEpsLoop) && 1135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson multi_eps_labels_.Find(match_label) != multi_eps_labels_.End()) { 1136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // return 'implicit' loop 1137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson current_loop_ = true; 1138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ret = true; 1139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 1140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ret = matcher_->Find(match_label); 1141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson done_ = !ret; 1143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ret; 1144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 1145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Generic matcher, templated on the FST definition 1148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// - a wrapper around pointer to specific one. 1149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Here is a typical use: \code 1150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Matcher<StdFst> matcher(fst, MATCH_INPUT); 1151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// matcher.SetState(state); 1152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// if (matcher.Find(label)) 1153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// for (; !matcher.Done(); matcher.Next()) { 1154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// StdArc &arc = matcher.Value(); 1155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// ... 1156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// } \endcode 1157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class F> 1158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass Matcher { 1159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 1160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef F FST; 1161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::Arc Arc; 1162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 1163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 1164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 1165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher(const F &fst, MatchType match_type) { 1167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson base_ = fst.InitMatcher(match_type); 1168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!base_) 1169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson base_ = new SortedMatcher<F>(fst, match_type); 1170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher(const Matcher<F> &matcher, bool safe = false) { 1173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson base_ = matcher.base_->Copy(safe); 1174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Takes ownership of the provided matcher 1177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher(MatcherBase<Arc>* base_matcher) { base_ = base_matcher; } 1178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ~Matcher() { delete base_; } 1180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher<F> *Copy(bool safe = false) const { 1182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return new Matcher<F>(*this, safe); 1183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 1184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType Type(bool test) const { return base_->Type(test); } 1186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetState(StateId s) { base_->SetState(s); } 1187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Find(Label label) { return base_->Find(label); } 1188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool Done() const { return base_->Done(); } 1189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Arc& Value() const { return base_->Value(); } 1190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void Next() { base_->Next(); } 1191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const F &GetFst() const { return static_cast<const F &>(base_->GetFst()); } 1192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 Properties(uint64 props) const { return base_->Properties(props); } 1193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint32 Flags() const { return base_->Flags() & kMatcherFlags; } 1194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 1196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatcherBase<Arc> *base_; 1197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const Matcher<Arc> &); // disallow 1199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 1200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} // namespace fst 1202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 1205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif // FST_LIB_MATCHER_H__ 1206