1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// lookahead-filter.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// Composition filters to support lookahead matchers, useful for improving 20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// composition efficiency with certain inputs. 21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_LOOKAHEAD_FILTER_H__ 23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_LOOKAHEAD_FILTER_H__ 24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <vector> 26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::vector; 27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/fst.h> 29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/lookahead-matcher.h> 30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst { 33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Identifies and verifies the capabilities of the matcher to be used for 35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// lookahead with the composition filters below. This version is passed 36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// the matchers. 37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M1, class M2> 38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonMatchType LookAheadMatchType(const M1 &m1, const M2 &m2) { 39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType type1 = m1.Type(false); 40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType type2 = m2.Type(false); 41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (type1 == MATCH_OUTPUT && 42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson m1.Flags() & kOutputLookAheadMatcher) 43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MATCH_OUTPUT; 44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (type2 == MATCH_INPUT && 45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson m2.Flags() & kInputLookAheadMatcher) 46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MATCH_INPUT; 47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (m1.Flags() & kOutputLookAheadMatcher && 48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson m1.Type(true) == MATCH_OUTPUT) 49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MATCH_OUTPUT; 50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (m2.Flags() & kInputLookAheadMatcher && 51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson m2.Type(true) == MATCH_INPUT) 52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MATCH_INPUT; 53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return MATCH_NONE; 55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Identifies and verifies the capabilities of the matcher to be used for 58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// lookahead with the composition filters below. This version uses the 59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Fst's default matchers. 60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class Arc> 61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonMatchType LookAheadMatchType(const Fst<Arc> &fst1, const Fst<Arc> &fst2) { 62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadMatcher< Fst <Arc> > matcher1(fst1, MATCH_OUTPUT); 63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadMatcher< Fst <Arc> > matcher2(fst2, MATCH_INPUT); 64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LookAheadMatchType(matcher1, matcher2); 65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// LookAheadSelector - a helper class for selecting among possibly 69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distinct FST and matcher types w/o using a common base class. This 70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// lets us avoid virtual function calls. 71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Stores and returns the appropriate FST and matcher for lookahead. 74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// It is templated on the matcher types. General case has no methods 75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// since not currently supported. 76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M1, class M2, MatchType MT> 77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass LookAheadSelector { 78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Stores and returns the appropriate FST and matcher for lookahead. 81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialized for two matchers of same type with the (match) 'type' 82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// arg determining which is used for lookahead. 83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M, MatchType MT> 84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass LookAheadSelector<M, M, MT> { 85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M::Arc Arc; 87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M::FST F; 88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadSelector(M *lmatcher1, M *lmatcher2, MatchType type) 90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : lmatcher1_(lmatcher1->Copy()), 91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lmatcher2_(lmatcher2->Copy()), 92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson type_(type) {} 93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadSelector(const LookAheadSelector<M, M, MT> &selector) 95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : lmatcher1_(selector.lmatcher1_->Copy()), 96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lmatcher2_(selector.lmatcher2_->Copy()), 97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson type_(selector.type_) {} 98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ~LookAheadSelector() { 100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete lmatcher1_; 101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete lmatcher2_; 102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const F &GetFst() const { 105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return type_ == MATCH_OUTPUT ? lmatcher2_->GetFst() : 106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lmatcher1_->GetFst(); 107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *GetMatcher() const { 110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return type_ == MATCH_OUTPUT ? lmatcher1_ : lmatcher2_; 111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *lmatcher1_; 115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M *lmatcher2_; 116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType type_; 117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const LookAheadSelector<M, M, MT> &); // disallow 119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Stores and returns the appropriate FST and matcher for lookahead. 122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialized for lookahead on input labels. 123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M1, class M2> 124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass LookAheadSelector<M1, M2, MATCH_INPUT> { 125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M1::FST F1; 127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadSelector(M1 *lmatcher1, M2 *lmatcher2, MatchType) 129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : fst_(lmatcher1->GetFst().Copy()), 130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lmatcher_(lmatcher2->Copy()) {} 131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadSelector(const LookAheadSelector<M1, M2, MATCH_INPUT> &selector) 133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : fst_(selector.fst_->Copy()), 134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lmatcher_(selector.lmatcher_->Copy()) {} 135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ~LookAheadSelector() { 137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete lmatcher_; 138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete fst_; 139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const F1 &GetFst() const { return *fst_; } 142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M2 *GetMatcher() const { return lmatcher_; } 144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const F1 *fst_; 147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M2 *lmatcher_; 148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const LookAheadSelector<M1, M2, MATCH_INPUT> &); // disallow 150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Stores and returns the appropriate FST and matcher for lookahead. 154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specialized for lookahead on output labels. 155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class M1, class M2> 156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass LookAheadSelector<M1, M2, MATCH_OUTPUT> { 157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename M2::FST F2; 159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadSelector(M1 *lmatcher1, M2 *lmatcher2, MatchType) 161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : fst_(lmatcher2->GetFst().Copy()), 162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lmatcher_(lmatcher1->Copy()) {} 163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadSelector(const LookAheadSelector<M1, M2, MATCH_OUTPUT> &selector) 165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : fst_(selector.fst_->Copy()), 166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lmatcher_(selector.lmatcher_->Copy()) {} 167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ~LookAheadSelector() { 169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete lmatcher_; 170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete fst_; 171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const F2 &GetFst() const { return *fst_; } 174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M1 *GetMatcher() const { return lmatcher_; } 176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const F2 *fst_; 179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M1 *lmatcher_; 180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const LookAheadSelector<M1, M2, MATCH_OUTPUT> &); // disallow 182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This filter uses a lookahead matcher in FilterArc(arc1, arc2) to 185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// examine the future of the composition state (arc1.nextstate, 186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// arc2.nextstate), blocking moving forward when its determined to be 187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// non-coaccessible. It is templated on an underlying filter, 188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// typically the epsilon filter. Which matcher is the lookahead 189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// matcher is determined by the template argument MT unless it is 190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// MATCH_BOTH. In that case, both matcher arguments must be lookahead 191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// matchers of the same type and one will be selected by 192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// LookAheadMatchType() based on their capability. 193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class F, 194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson class M1 = LookAheadMatcher<typename F::FST1>, 195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson class M2 = M1, 196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType MT = MATCH_BOTH> 197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass LookAheadComposeFilter { 198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::FST1 FST1; 200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::FST2 FST2; 201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::Arc Arc; 202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::Matcher1 Matcher1; 203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::Matcher2 Matcher2; 204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::FilterState FilterState; 205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadComposeFilter<F, M1, M2, MT> Filter; 206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadComposeFilter(const FST1 &fst1, const FST2 &fst2, 212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M1 *matcher1, M2 *matcher2) 213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : filter_(fst1, fst2, matcher1, matcher2), 214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lookahead_type_(MT == MATCH_BOTH ? 215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadMatchType(*filter_.GetMatcher1(), 216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson *filter_.GetMatcher2()) : MT), 217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson selector_(filter_.GetMatcher1(), filter_.GetMatcher2(), 218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lookahead_type_), 219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson flags_(lookahead_type_ == MATCH_OUTPUT ? 220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.GetMatcher1()->Flags() : 221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.GetMatcher2()->Flags()) { 222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (lookahead_type_ == MATCH_NONE) { 223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FSTERROR() << "LookAheadComposeFilter: 1st argument cannot " 224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson << "match/look-ahead on output labels and 2nd argument " 225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson << "cannot match/look-ahead on input labels."; 226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson selector_.GetMatcher()->InitLookAheadFst(selector_.GetFst()); 228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadComposeFilter(const LookAheadComposeFilter<F, M1, M2, MT> &filter, 231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool safe = false) 232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : filter_(filter.filter_, safe), 233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lookahead_type_(filter.lookahead_type_), 234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson selector_(filter_.GetMatcher1(), filter_.GetMatcher2(), 235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lookahead_type_), 236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson flags_(filter.flags_) { 237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson selector_.GetMatcher()->InitLookAheadFst(selector_.GetFst(), true); 238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState Start() const { 241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return filter_.Start(); 242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetState(StateId s1, StateId s2, const FilterState &f) { 245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.SetState(s1, s2, f); 246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState FilterArc(Arc *arc1, Arc *arc2) const { 249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lookahead_arc_ = false; 250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FilterState &f = filter_.FilterArc(arc1, arc2); 252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (f == FilterState::NoState()) 253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState::NoState(); 254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LookAheadOutput() ? LookAheadFilterArc(arc1, arc2, f) : 256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadFilterArc(arc2, arc1, f); 257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void FilterFinal(Weight *weight1, Weight *weight2) const { 260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.FilterFinal(weight1, weight2); 261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Return resp matchers. Ownership stays with filter. 264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher1 *GetMatcher1() { return filter_.GetMatcher1(); } 265f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher2 *GetMatcher2() { return filter_.GetMatcher2(); } 266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LookAheadSelector<Matcher1, Matcher2, MT> &Selector() const { 268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return selector_; 269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 Properties(uint64 inprops) const { 272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 outprops = filter_.Properties(inprops); 273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (lookahead_type_ == MATCH_NONE) 274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson outprops |= kError; 275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return outprops; 276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint32 LookAheadFlags() const { return flags_; } 279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool LookAheadArc() const { return lookahead_arc_; } 281f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool LookAheadOutput() const { 283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (MT == MATCH_OUTPUT) 284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (MT == MATCH_INPUT) 286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else if (lookahead_type_ == MATCH_OUTPUT) 288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 290f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 291f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 292f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 293f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 294f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState LookAheadFilterArc(Arc *arca, Arc *arcb, 295f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FilterState &f) const { 296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label &labela = LookAheadOutput() ? arca->olabel : arca->ilabel; 297f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 298f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (labela != 0 && !(flags_ & kLookAheadNonEpsilons)) 299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return f; 300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (labela == 0 && !(flags_ & kLookAheadEpsilons)) 301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return f; 302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson lookahead_arc_ = true; 304f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson selector_.GetMatcher()->SetState(arca->nextstate); 305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 306f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return selector_.GetMatcher()->LookAheadFst(selector_.GetFst(), 307f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson arcb->nextstate) ? f : 308f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState::NoState(); 309f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 310f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 311f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson F filter_; // Underlying filter 312f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType lookahead_type_; // Lookahead match type 313f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadSelector<Matcher1, Matcher2, MT> selector_; 314f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint32 flags_; // Lookahead flags 315f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson mutable bool lookahead_arc_; // Look-ahead performed at last FilterArc()? 316f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 317f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const LookAheadComposeFilter<F, M1, M2> &); // disallow 318f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 319f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 320f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 321f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This filter adds weight-pushing to a lookahead composition filter 322f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// using the LookAheadWeight() method of matcher argument. It is 323f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// templated on an underlying lookahead filter, typically the basic 324f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// lookahead filter. Weight-pushing in composition brings weights 325f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// forward as much as possible based on the lookahead information. 326f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class F, 327f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson class M1 = LookAheadMatcher<typename F::FST1>, 328f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson class M2 = M1, 329f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType MT = MATCH_BOTH> 330f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass PushWeightsComposeFilter { 331f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 332f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::FST1 FST1; 333f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::FST2 FST2; 334f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::Arc Arc; 335f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::Matcher1 Matcher1; 336f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::Matcher2 Matcher2; 337f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::FilterState FilterState1; 338f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef WeightFilterState<typename Arc::Weight> FilterState2; 339f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef PairFilterState<FilterState1, FilterState2> FilterState; 340f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 341f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 342f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 343f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 344f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 345f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson PushWeightsComposeFilter(const FST1 &fst1, const FST2 &fst2, 346f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M1 *matcher1, M2 *matcher2) 347f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : filter_(fst1, fst2, matcher1, matcher2), 348f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson f_(FilterState::NoState()) {} 349f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 350f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson PushWeightsComposeFilter(const PushWeightsComposeFilter<F, M1, M2, MT> 351f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson &filter, 352f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool safe = false) 353f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : filter_(filter.filter_, safe), 354f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson f_(FilterState::NoState()) {} 355f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 356f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState Start() const { 357f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState(filter_.Start(), FilterState2(Weight::One())); 358f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 359f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 360f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetState(StateId s1, StateId s2, const FilterState &f) { 361f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson f_ = f; 362f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.SetState(s1, s2, f.GetState1()); 363f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 364f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 365f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState FilterArc(Arc *arc1, Arc *arc2) const { 366f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FilterState1 &f1 = filter_.FilterArc(arc1, arc2); 367f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (f1 == FilterState1::NoState()) 368f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState::NoState(); 369f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 370f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!(LookAheadFlags() & kLookAheadWeight)) 371f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState(f1, FilterState2(Weight::One())); 372f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 373f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Weight &lweight = filter_.LookAheadArc() ? 374f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Selector().GetMatcher()->LookAheadWeight() : Weight::One(); 375f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FilterState2 &f2 = f_.GetState2(); 376f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Weight &fweight = f2.GetWeight(); 377f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 378f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson arc2->weight = Divide(Times(arc2->weight, lweight), fweight); 379f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState(f1, FilterState2(lweight)); 380f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 381f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 382f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void FilterFinal(Weight *weight1, Weight *weight2) const { 383f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.FilterFinal(weight1, weight2); 384f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!(LookAheadFlags() & kLookAheadWeight) || *weight1 == Weight::Zero()) 385f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return; 386f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 387f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FilterState2 &f2 = f_.GetState2(); 388f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Weight &fweight = f2.GetWeight(); 389f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson *weight1 = Divide(*weight1, fweight); 390f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 391f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Return resp matchers. Ownership states with filter. 392f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher1 *GetMatcher1() { return filter_.GetMatcher1(); } 393f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher2 *GetMatcher2() { return filter_.GetMatcher2(); } 394f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 395f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LookAheadSelector<Matcher1, Matcher2, MT> &Selector() const { 396f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return filter_.Selector(); 397f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 398f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 399f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint32 LookAheadFlags() const { return filter_.LookAheadFlags(); } 400f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool LookAheadArc() const { return filter_.LookAheadArc(); } 401f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool LookAheadOutput() const { return filter_.LookAheadOutput(); } 402f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 403f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 Properties(uint64 props) const { 404f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return filter_.Properties(props) & kWeightInvariantProperties; 405f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 406f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 407f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 408f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson F filter_; // Underlying filter 409f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState f_; // Current filter state 410f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 411f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const PushWeightsComposeFilter<F, M1, M2, MT> &); // disallow 412f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 413f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 414f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This filter adds label-pushing to a lookahead composition filter 415f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// using the LookAheadPrefix() method of the matcher argument. It is 416f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// templated on an underlying filter, typically the basic lookahead 417f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// or weight-pushing lookahead filter. Label-pushing in composition 418f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// matches labels as early as possible based on the lookahead 419f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// information. 420f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class F, 421f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson class M1 = LookAheadMatcher<typename F::FST1>, 422f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson class M2 = M1, 423f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson MatchType MT = MATCH_BOTH> 424f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass PushLabelsComposeFilter { 425f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 426f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::FST1 FST1; 427f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::FST2 FST2; 428f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::Arc Arc; 429f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 430f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 431f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 432f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 433f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef MultiEpsMatcher<typename F::Matcher1> Matcher1; 434f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef MultiEpsMatcher<typename F::Matcher2> Matcher2; 435f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename F::FilterState FilterState1; 436f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef IntegerFilterState<typename Arc::Label> FilterState2; 437f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef PairFilterState<FilterState1, FilterState2> FilterState; 438f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 439f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson PushLabelsComposeFilter(const FST1 &fst1, const FST2 &fst2, 440f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson M1 *matcher1, M2 *matcher2) 441f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : filter_(fst1, fst2, matcher1, matcher2), 442f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson f_(FilterState::NoState()), 443f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson fst1_(filter_.GetMatcher1()->GetFst()), 444f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson fst2_(filter_.GetMatcher2()->GetFst()), 445f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher1_(fst1_, MATCH_OUTPUT, 446f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.LookAheadOutput() ? kMultiEpsList : kMultiEpsLoop, 447f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.GetMatcher1(), 448f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson false), 449f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher2_(fst2_, MATCH_INPUT, 450f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.LookAheadOutput() ? kMultiEpsLoop : kMultiEpsList, 451f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.GetMatcher2(), 452f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson false) {} 453f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 454f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson PushLabelsComposeFilter(const PushLabelsComposeFilter<F, M1, M2, MT> &filter, 455f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool safe = false) 456f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : filter_(filter.filter_, safe), 457f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson f_(FilterState::NoState()), 458f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson fst1_(filter_.GetMatcher1()->GetFst()), 459f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson fst2_(filter_.GetMatcher2()->GetFst()), 460f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher1_(fst1_, MATCH_OUTPUT, 461f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.LookAheadOutput() ? kMultiEpsList : kMultiEpsLoop, 462f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.GetMatcher1(), 463f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson false), 464f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson matcher2_(fst2_, MATCH_INPUT, 465f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.LookAheadOutput() ? kMultiEpsLoop : kMultiEpsList, 466f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.GetMatcher2(), 467f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson false) { 468f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 469f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 470f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState Start() const { 471f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState(filter_.Start(), FilterState2(kNoLabel)); 472f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 473f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 474f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void SetState(StateId s1, StateId s2, const FilterState &f) { 475f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson f_ = f; 476f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.SetState(s1, s2, f.GetState1()); 477f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!(LookAheadFlags() & kLookAheadPrefix)) 478f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return; 479f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 480f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson narcsa_ = LookAheadOutput() ? internal::NumArcs(fst1_, s1) 481f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson : internal::NumArcs(fst2_, s2); 482f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 483f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FilterState2 &f2 = f_.GetState2(); 484f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Label &flabel = f2.GetState(); 485f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 486f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson GetMatcher1()->ClearMultiEpsLabels(); 487f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson GetMatcher2()->ClearMultiEpsLabels(); 488f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (flabel != kNoLabel) { // Have a lookahead label? 489f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson GetMatcher1()->AddMultiEpsLabel(flabel); // Yes, make it a multi-epsilon 490f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson GetMatcher2()->AddMultiEpsLabel(flabel); // label so that it matches the 491f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } // implicit epsilon arc to be 492f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } // modified below when pushing. 493f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 494f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState FilterArc(Arc *arc1, Arc *arc2) const { 495f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!(LookAheadFlags() & kLookAheadPrefix)) 496f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState(filter_.FilterArc(arc1, arc2), 497f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState2(kNoLabel)); 498f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 499f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FilterState2 &f2 = f_.GetState2(); 500f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Label &flabel = f2.GetState(); 501f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (flabel != kNoLabel) // Have a lookahead label? 502f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LookAheadOutput() ? PushedLabelFilterArc(arc1, arc2, flabel) : 503f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson PushedLabelFilterArc(arc2, arc1, flabel); 504f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 505f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FilterState1 &f1 = filter_.FilterArc(arc1, arc2); 506f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (f1 == FilterState1::NoState()) 507f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState::NoState(); 508f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 509f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!filter_.LookAheadArc()) 510f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState(f1, FilterState2(kNoLabel)); 511f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 512f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return LookAheadOutput() ? PushLabelFilterArc(arc1, arc2, f1) : 513f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson PushLabelFilterArc(arc2, arc1, f1); 514f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 515f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 516f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void FilterFinal(Weight *weight1, Weight *weight2) const { 517f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson filter_.FilterFinal(weight1, weight2); 518f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!(LookAheadFlags() & kLookAheadPrefix) || 519f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson *weight1 == Weight::Zero()) 520f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return; 521f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 522f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FilterState2 &f2 = f_.GetState2(); 523f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Label &flabel = f2.GetState(); 524f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (flabel != kNoLabel) 525f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson *weight1 = Weight::Zero(); 526f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 527f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 528f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Return resp matchers. Ownership states with filter. 529f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher1 *GetMatcher1() { return &matcher1_; } 530f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher2 *GetMatcher2() { return &matcher2_; } 531f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 532f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 Properties(uint64 iprops) const { 533f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 oprops = filter_.Properties(iprops); 534f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (LookAheadOutput()) 535f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return oprops & kOLabelInvariantProperties; 536f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 537f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return oprops & kILabelInvariantProperties; 538f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 539f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 540f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private: 541f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const LookAheadSelector<typename F::Matcher1, typename F::Matcher2, MT> 542f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson &Selector() const { 543f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return filter_.Selector(); 544f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 545f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 546f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Consumes an already pushed label. 547f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState PushedLabelFilterArc(Arc *arca, Arc *arcb, 548f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label flabel) const { 549f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label &labela = LookAheadOutput() ? arca->olabel : arca->ilabel; 550f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Label &labelb = LookAheadOutput() ? arcb->ilabel : arcb->olabel; 551f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 552f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (labelb != kNoLabel) { 553f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState::NoState(); // Block non- (multi-) epsilon label 554f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (labela == flabel) { 555f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson labela = 0; // Convert match to multi-eps to eps 556f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return Start(); 557f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else if (labela == 0) { 558f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (narcsa_ == 1) 559f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return f_; // Take eps; keep state w/ label 560f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Selector().GetMatcher()->SetState(arca->nextstate); 561f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (Selector().GetMatcher()->LookAheadLabel(flabel)) 562f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return f_; // Take eps; keep state w/ label 563f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson else 564f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState::NoState(); // Block non-coaccessible path 565f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 566f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState::NoState(); // Block mismatch to multi-eps label 567f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 568f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 569f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 570f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Pushes a label forward when possible. 571f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState PushLabelFilterArc(Arc *arca, Arc *arcb, 572f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FilterState1 &f1) const { 573f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Label &labela = LookAheadOutput() ? arca->olabel : arca->ilabel; 574f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Label &labelb = LookAheadOutput() ? arcb->olabel : arcb->ilabel; 575f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 576f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (labelb != 0) // No place to push. 577f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState(f1, FilterState2(kNoLabel)); 578f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (labela != 0 && // Wrong lookahead prefix type? 579f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LookAheadFlags() & kLookAheadNonEpsilonPrefix) 580f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState(f1, FilterState2(kNoLabel)); 581f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 582f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Arc larc(kNoLabel, kNoLabel, Weight::Zero(), kNoStateId); 583f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 584f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (Selector().GetMatcher()->LookAheadPrefix(&larc)) { // Have prefix arc? 585f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson labela = LookAheadOutput() ? larc.ilabel : larc.olabel; 586f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson arcb->ilabel = larc.ilabel; // Yes, go forward on that arc, 587f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson arcb->olabel = larc.olabel; // thus pushing the label. 588f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson arcb->weight = Times(arcb->weight, larc.weight); 589f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson arcb->nextstate = larc.nextstate; 590f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState(f1, FilterState2(labela)); 591f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 592f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return FilterState(f1, FilterState2(kNoLabel)); 593f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 594f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 595f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 596f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint32 LookAheadFlags() const { return filter_.LookAheadFlags(); } 597f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool LookAheadArc() const { return filter_.LookAheadArc(); } 598f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool LookAheadOutput() const { return filter_.LookAheadOutput(); } 599f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 600f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson F filter_; // Underlying filter 601f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson FilterState f_ ; // Current filter state 602f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FST1 &fst1_; 603f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const FST2 &fst2_; 604f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher1 matcher1_; // Multi-epsilon matcher for fst1 605f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Matcher2 matcher2_; // Multi-epsilon matcher for fst2 606f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ssize_t narcsa_; // Number of arcs leaving look-ahead match FST 607f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 608f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson void operator=(const PushLabelsComposeFilter<F, M1, M2, MT> &); // disallow 609f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 610f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 611f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 612f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// CONVENIENCE CLASS useful for setting up composition with a default 613f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// look-ahead matcher and filter. 614f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// 615f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 616f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A, MatchType type> // MATCH_NONE 617f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass DefaultLookAhead { 618f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 619f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef Matcher< Fst<A> > M; 620f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef SequenceComposeFilter<M> ComposeFilter; 621f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef M FstMatcher; 622f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 623f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 624f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specializes for MATCH_INPUT to allow lookahead. 625f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> 626f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass DefaultLookAhead<A, MATCH_INPUT> { 627f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 628f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadMatcher< Fst<A> > M; 629f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef SequenceComposeFilter<M> SF; 630f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadComposeFilter<SF, M> ComposeFilter; 631f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef M FstMatcher; 632f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 633f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 634f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specializes for MATCH_OUTPUT to allow lookahead. 635f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> 636f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass DefaultLookAhead<A, MATCH_OUTPUT> { 637f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 638f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadMatcher< Fst<A> > M; 639f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef AltSequenceComposeFilter<M> SF; 640f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadComposeFilter<SF, M> ComposeFilter; 641f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef M FstMatcher; 642f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 643f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 644f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specializes for StdArc to allow weight and label pushing. 645f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> 646f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass DefaultLookAhead<StdArc, MATCH_INPUT> { 647f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 648f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef StdArc A; 649f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadMatcher< Fst<A> > M; 650f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef SequenceComposeFilter<M> SF; 651f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadComposeFilter<SF, M> LF; 652f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef PushWeightsComposeFilter<LF, M> WF; 653f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef PushLabelsComposeFilter<WF, M> ComposeFilter; 654f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef M FstMatcher; 655f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 656f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 657f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specializes for StdArc to allow weight and label pushing. 658f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> 659f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass DefaultLookAhead<StdArc, MATCH_OUTPUT> { 660f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 661f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef StdArc A; 662f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadMatcher< Fst<A> > M; 663f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef AltSequenceComposeFilter<M> SF; 664f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadComposeFilter<SF, M> LF; 665f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef PushWeightsComposeFilter<LF, M> WF; 666f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef PushLabelsComposeFilter<WF, M> ComposeFilter; 667f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef M FstMatcher; 668f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 669f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 670f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specializes for LogArc to allow weight and label pushing. 671f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> 672f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass DefaultLookAhead<LogArc, MATCH_INPUT> { 673f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 674f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LogArc A; 675f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadMatcher< Fst<A> > M; 676f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef SequenceComposeFilter<M> SF; 677f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadComposeFilter<SF, M> LF; 678f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef PushWeightsComposeFilter<LF, M> WF; 679f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef PushLabelsComposeFilter<WF, M> ComposeFilter; 680f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef M FstMatcher; 681f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 682f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 683f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Specializes for LogArc to allow weight and label pushing. 684f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <> 685f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonclass DefaultLookAhead<LogArc, MATCH_OUTPUT> { 686f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public: 687f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LogArc A; 688f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadMatcher< Fst<A> > M; 689f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef AltSequenceComposeFilter<M> SF; 690f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef LookAheadComposeFilter<SF, M> LF; 691f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef PushWeightsComposeFilter<LF, M> WF; 692f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef PushLabelsComposeFilter<WF, M> ComposeFilter; 693f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef M FstMatcher; 694f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}; 695f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 696f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} // namespace fst 697f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 698f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif // FST_LIB_LOOKAHEAD_FILTER_H__ 699