// compose.h
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2005-2010 Google, Inc.
// Author: riley@google.com (Michael Riley)
//
// \file
// Class to compute the composition of two FSTs
#ifndef FST_LIB_COMPOSE_H__
#define FST_LIB_COMPOSE_H__
#include <algorithm>
#include <string>
#include <vector>
using std::vector;
#include <fst/cache.h>
#include <fst/compose-filter.h>
#include <fst/lookahead-filter.h>
#include <fst/matcher.h>
#include <fst/state-table.h>
#include <fst/test-properties.h>
namespace fst {
// Delayed composition options templated on the arc type, the matcher,
// the composition filter, and the composition state table. By
// default, the matchers, filter, and state table are constructed by
// composition. If set below, the user can instead pass in these
// objects; in that case, ComposeFst takes their ownership. This
// version controls composition implemented between generic Fst<Arc>
// types and a shared matcher type M for Fst<Arc>. This should be
// adequate for most applications, giving a reasonable tradeoff
// between efficiency and code sharing (but see ComposeFstImplOptions).
template <class A,
class M = Matcher<Fst<A> >,
class F = SequenceComposeFilter<M>,
class T = GenericComposeStateTable<A, typename F::FilterState> >
struct ComposeFstOptions : public CacheOptions {
M *matcher1; // FST1 matcher (see matcher.h)
M *matcher2; // FST2 matcher
F *filter; // Composition filter (see compose-filter.h)
T *state_table; // Composition state table (see compose-state-table.h)
explicit ComposeFstOptions(const CacheOptions &opts,
M *mat1 = 0, M *mat2 = 0,
F *filt = 0, T *sttable= 0)
: CacheOptions(opts), matcher1(mat1), matcher2(mat2),
filter(filt), state_table(sttable) {}
ComposeFstOptions() : matcher1(0), matcher2(0), filter(0), state_table(0) {}
};
// Delayed composition options templated on the two matcher types, the
// composition filter, and the composition state table. By default,
// the matchers, filter, and state table are constructed by
// composition. If set below, the user can instead pass in these
// objects; in that case, ComposeFst takes their ownership. This
// version controls composition implemented using arbitrary matchers
// (of the same Arc type but otherwise arbitrary Fst type). The user
// must ensure the matchers are compatible. These options permit the
// most efficient use, but shares the least code. This is for advanced
// use only in the most demanding or specialized applications that can
// benefit from it (o.w. prefer ComposeFstOptions).
template <class M1, class M2,
class F = SequenceComposeFilter<M1, M2>,
class T = GenericComposeStateTable<typename M1::Arc,
typename F::FilterState> >
struct ComposeFstImplOptions : public CacheOptions {
M1 *matcher1; // FST1 matcher (see matcher.h)
M2 *matcher2; // FST2 matcher
F *filter; // Composition filter (see compose-filter.h)
T *state_table; // Composition state table (see compose-state-table.h)
explicit ComposeFstImplOptions(const CacheOptions &opts,
M1 *mat1 = 0, M2 *mat2 = 0,
F *filt = 0, T *sttable= 0)
: CacheOptions(opts), matcher1(mat1), matcher2(mat2),
filter(filt), state_table(sttable) {}
ComposeFstImplOptions()
: matcher1(0), matcher2(0), filter(0), state_table(0) {}
};
// Implementation of delayed composition. This base class is
// common to the variants with different matchers, composition filters
// and state tables.
template <class A>
class ComposeFstImplBase : public CacheImpl<A> {
public:
using FstImpl<A>::SetType;
using FstImpl<A>::SetProperties;
using FstImpl<A>::Properties;
using FstImpl<A>::SetInputSymbols;
using FstImpl<A>::SetOutputSymbols;
using CacheBaseImpl< CacheState<A> >::HasStart;
using CacheBaseImpl< CacheState<A> >::HasFinal;
using CacheBaseImpl< CacheState<A> >::HasArcs;
using CacheBaseImpl< CacheState<A> >::SetFinal;
using CacheBaseImpl< CacheState<A> >::SetStart;
typedef typename A::Label Label;
typedef typename A::Weight Weight;
typedef typename A::StateId StateId;
typedef CacheState<A> State;
ComposeFstImplBase(const Fst<A> &fst1, const Fst<A> &fst2,
const CacheOptions &opts)
: CacheImpl<A>(opts) {
VLOG(2) << "ComposeFst(" << this << "): Begin";
SetType("compose");
if (!CompatSymbols(fst2.InputSymbols(), fst1.OutputSymbols())) {
FSTERROR() << "ComposeFst: output symbol table of 1st argument "
<< "does not match input symbol table of 2nd argument";
SetProperties(kError, kError);
}
SetInputSymbols(fst1.InputSymbols());
SetOutputSymbols(fst2.OutputSymbols());
}
ComposeFstImplBase(const ComposeFstImplBase<A> &impl)
: CacheImpl<A>(impl, true) {
SetProperties(impl.Properties(), kCopyProperties);
SetInputSymbols(impl.InputSymbols());
SetOutputSymbols(impl.OutputSymbols());
}
virtual ComposeFstImplBase<A> *Copy() = 0;
virtual ~ComposeFstImplBase() {}
StateId Start() {
if (!HasStart()) {
StateId start = ComputeStart();
if (start != kNoStateId) {
SetStart(start);
}
}
return CacheImpl<A>::Start();
}
Weight Final(StateId s) {
if (!HasFinal(s)) {
Weight final = ComputeFinal(s);
SetFinal(s, final);
}
return CacheImpl<A>::Final(s);
}
virtual void Expand(StateId s) = 0;
size_t NumArcs(StateId s) {
if (!HasArcs(s))
Expand(s);
return CacheImpl<A>::NumArcs(s);
}
size_t NumInputEpsilons(StateId s) {
if (!HasArcs(s))
Expand(s);
return CacheImpl<A>::NumInputEpsilons(s);
}
size_t NumOutputEpsilons(StateId s) {
if (!HasArcs(s))
Expand(s);
return CacheImpl<A>::<