// lookahead-filter.h
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2005-2010 Google, Inc.
// Author: riley@google.com (Michael Riley)
//
// \file
// Composition filters to support lookahead matchers, useful for improving
// composition efficiency with certain inputs.
#ifndef FST_LIB_LOOKAHEAD_FILTER_H__
#define FST_LIB_LOOKAHEAD_FILTER_H__
#include <vector>
using std::vector;
#include <fst/fst.h>
#include <fst/lookahead-matcher.h>
namespace fst {
// Identifies and verifies the capabilities of the matcher to be used for
// lookahead with the composition filters below. This version is passed
// the matchers.
template <class M1, class M2>
MatchType LookAheadMatchType(const M1 &m1, const M2 &m2) {
MatchType type1 = m1.Type(false);
MatchType type2 = m2.Type(false);
if (type1 == MATCH_OUTPUT &&
m1.Flags() & kOutputLookAheadMatcher)
return MATCH_OUTPUT;
else if (type2 == MATCH_INPUT &&
m2.Flags() & kInputLookAheadMatcher)
return MATCH_INPUT;
else if (m1.Flags() & kOutputLookAheadMatcher &&
m1.Type(true) == MATCH_OUTPUT)
return MATCH_OUTPUT;
else if (m2.Flags() & kInputLookAheadMatcher &&
m2.Type(true) == MATCH_INPUT)
return MATCH_INPUT;
else
return MATCH_NONE;
}
// Identifies and verifies the capabilities of the matcher to be used for
// lookahead with the composition filters below. This version uses the
// Fst's default matchers.
template <class Arc>
MatchType LookAheadMatchType(const Fst<Arc> &fst1, const Fst<Arc> &fst2) {
LookAheadMatcher< Fst <Arc> > matcher1(fst1, MATCH_OUTPUT);
LookAheadMatcher< Fst <Arc> > matcher2(fst2, MATCH_INPUT);
return LookAheadMatchType(matcher1, matcher2);
}
//
// LookAheadSelector - a helper class for selecting among possibly
// distinct FST and matcher types w/o using a common base class. This
// lets us avoid virtual function calls.
//
// Stores and returns the appropriate FST and matcher for lookahead.
// It is templated on the matcher types. General case has no methods
// since not currently supported.
template <class M1, class M2, MatchType MT>
class LookAheadSelector {
};
// Stores and returns the appropriate FST and matcher for lookahead.
// Specialized for two matchers of same type with the (match) 'type'
// arg determining which is used for lookahead.
template <class M, MatchType MT>
class LookAheadSelector<M, M, MT> {
public:
typedef typename M::Arc Arc;
typedef typename M::FST F;
LookAheadSelector(M *lmatcher1, M *lmatcher2, MatchType type)
: lmatcher1_(lmatcher1->Copy()),
lmatcher2_(lmatcher2->Copy()),
type_(type) {}
LookAheadSelector(const LookAheadSelector<M, M, MT> &selector)
: lmatcher1_(selector.lmatcher1_->Copy()),
lmatcher2_(selector.lmatcher2_->Copy()),
type_(selector.type_) {}
~LookAheadSelector() {
delete lmatcher1_;
delete lmatcher2_;
}
const F &GetFst() const {
return type_ == MATCH_OUTPUT ? lmatcher2_->GetFst() :
lmatcher1_->GetFst();
}
M *GetMatcher() const {
return type_ == MATCH_OUTPUT ? lmatcher1_ : lmatcher2_;
}
private:
M *lmatcher1_;
M *lmatcher2_;
MatchType type_;
void operator=(const LookAheadSelector<M, M, MT> &); // disallow
};
// Stores and returns the appropriate FST and matcher for lookahead.
// Specialized for lookahead on input labels.
template <class M1, class M2>
class LookAheadSelector<M1, M2, MATCH_INPUT> {
public:
typedef typename M1::FST F1;
LookAheadSelector(M1 *lmatcher1, M2 *lmatcher2, MatchType)
: fst_(lmatcher1->GetFst().Copy()),
lmatcher_(lmatcher2->Copy()) {}
LookAheadSelector(const LookAheadSelector<M1, M2, MATCH_INPUT> &selector)
: fst_(selector.fst_->Copy()),
lmatcher_(selector.lmatcher_->Copy()) {}
~LookAheadSelector() {
delete lmatcher_;
delete fst_;
}
const F1 &GetFst() const { return *fst_; }
M2 *GetMatcher() const { return lmatcher_; }
private:
const F1 *fst_;
M2 *lmatcher_;
void operator=(const LookAheadSelector<M1, M2, MATCH_INPUT> &); // disallow
};
// Stores and returns the appropriate FST and matcher for lookahead.
// Specialized for lookahead on output labels.
template <class M1, class M2>
class LookAheadSelector<M1, M2, MATCH_OUTPUT> {
public:
typedef typename M2::FST F2;
LookAheadSelector(M1 *lmatcher1, M2 *lmatcher2, MatchType)
: fst_(lmatcher2->GetFst().Copy()),
lmatcher_(lmatcher1->Copy()) {}
LookAheadSelector(const LookAheadSelector<M1, M2, MATCH_OUTPUT> &selector)
: fst_(selector.fst_->Copy()),
lmatcher_(selector.lmatcher_->Copy()) {}
~LookAheadSelector() {
delete lmatcher_;
delete fst_;
}
const F2 &GetFst() const { return *fst_; }
M1 *GetMatcher() const { return lmatcher_; }
private:
const F2 *fst_;
M1 *lmatcher_;
void operator=(const LookAheadSelector<M1, M2, MATCH_OUTPUT> &); // disallow
};
// This filter uses a lookahead matcher in FilterArc(arc1, arc2) to
// examine the future of the composition state (arc1.nextstate,
// arc2.nextstate), blocking moving forward when its determined to be
// non-coaccessible. It is templated on an underlying filter,
// typically the epsilon filter. Which matcher is the lookahead
// matcher is determined by the template argument MT unless it is
// MATCH_BOTH. In that case, both matcher arguments must be lookahead
// matchers of the same type and one will be selected by
// LookAheadMatchType() based on their capability.
template <class F,
class M1 = LookAheadMatcher<typename F::FST1>,
class M2 = M1,
MatchType MT = MATCH_BOTH>
class LookAheadComposeFilter {
public:
typedef typename F::FST1 FST1;
typedef typename F::FST2 FST2;
typedef typename F::Arc Arc;
typedef typename F::Matcher1 Matcher1;
typedef typename F::Matcher2 Matcher2;
typedef typename F::