// 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
// Compose a PDT and an FST.
#ifndef FST_EXTENSIONS_PDT_COMPOSE_H__
#define FST_EXTENSIONS_PDT_COMPOSE_H__
#include <fst/compose.h>
namespace fst {
// Class to setup composition options for PDT composition.
// Default is for the PDT as the first composition argument.
template <class Arc, bool left_pdt = true>
class PdtComposeOptions : public
ComposeFstOptions<Arc,
MultiEpsMatcher< Matcher<Fst<Arc> > >,
MultiEpsFilter<AltSequenceComposeFilter<
MultiEpsMatcher<
Matcher<Fst<Arc> > > > > > {
public:
typedef typename Arc::Label Label;
typedef MultiEpsMatcher< Matcher<Fst<Arc> > > PdtMatcher;
typedef MultiEpsFilter<AltSequenceComposeFilter<PdtMatcher> > PdtFilter;
typedef ComposeFstOptions<Arc, PdtMatcher, PdtFilter> COptions;
using COptions::matcher1;
using COptions::matcher2;
using COptions::filter;
PdtComposeOptions(const Fst<Arc> &ifst1,
const vector<pair<Label, Label> > &parens,
const Fst<Arc> &ifst2) {
matcher1 = new PdtMatcher(ifst1, MATCH_OUTPUT, kMultiEpsList);
matcher2 = new PdtMatcher(ifst2, MATCH_INPUT, kMultiEpsLoop);
// Treat parens as multi-epsilons when composing.
for (size_t i = 0; i < parens.size(); ++i) {
matcher1->AddMultiEpsLabel(parens[i].first);
matcher1->AddMultiEpsLabel(parens[i].second);
matcher2->AddMultiEpsLabel(parens[i].first);
matcher2->AddMultiEpsLabel(parens[i].second);
}
filter = new PdtFilter(ifst1, ifst2, matcher1, matcher2, true);
}
};
// Class to setup composition options for PDT with FST composition.
// Specialization is for the FST as the first composition argument.
template <class Arc>
class PdtComposeOptions<Arc, false> : public
ComposeFstOptions<Arc,
MultiEpsMatcher< Matcher<Fst<Arc> > >,
MultiEpsFilter<SequenceComposeFilter<
MultiEpsMatcher<
Matcher<Fst<Arc> > > > > > {
public:
typedef typename Arc::Label Label;
typedef MultiEpsMatcher< Matcher<Fst<Arc> > > PdtMatcher;
typedef MultiEpsFilter<SequenceComposeFilter<PdtMatcher> > PdtFilter;
typedef ComposeFstOptions<Arc, PdtMatcher, PdtFilter> COptions;
using COptions::matcher1;
using COptions::matcher2;
using COptions::filter;
PdtComposeOptions(const Fst<Arc> &ifst1,
const Fst<Arc> &ifst2,
const vector<pair<Label, Label> > &parens) {
matcher1 = new PdtMatcher(ifst1, MATCH_OUTPUT, kMultiEpsLoop);
matcher2 = new PdtMatcher(ifst2, MATCH_INPUT, kMultiEpsList);
// Treat parens as multi-epsilons when composing.
for (size_t i = 0; i < parens.size(); ++i) {
matcher1->AddMultiEpsLabel(parens[i].first);
matcher1->AddMultiEpsLabel(parens[i].second);
matcher2->AddMultiEpsLabel(parens[i].first);
matcher2->AddMultiEpsLabel(parens[i].second);
}
filter = new PdtFilter(ifst1, ifst2, matcher1, matcher2, true);
}
};
// Composes pushdown transducer (PDT) encoded as an FST (1st arg) and
// an FST (2nd arg) with the result also a PDT encoded as an Fst. (3rd arg).
// In the PDTs, some transitions are labeled with open or close
// parentheses. To be interpreted as a PDT, the parens must balance on
// a path (see PdtExpand()). The open-close parenthesis label pairs
// are passed in 'parens'.
template <class Arc>
void Compose(const Fst<Arc> &ifst1,
const vector<pair<typename Arc::Label,
typename Arc::Label> > &parens,
const Fst<Arc> &ifst2,
MutableFst<Arc> *ofst,
const ComposeOptions &opts = ComposeOptions()) {
PdtComposeOptions<Arc, true> copts(ifst1, parens, ifst2);
copts.gc_limit = 0;
*ofst = ComposeFst<Arc>(ifst1, ifst2, copts);
if (opts.connect)
Connect(ofst);
}
// Composes an FST (1st arg) and pushdown transducer (PDT) encoded as
// an FST (2nd arg) with the result also a PDT encoded as an Fst (3rd arg).
// In the PDTs, some transitions are labeled with open or close
// parentheses. To be interpreted as a PDT, the parens must balance on
// a path (see ExpandFst()). The open-close parenthesis label pairs
// are passed in 'parens'.
template <class Arc>
void Compose(const Fst<Arc> &ifst1,
const Fst<Arc> &ifst2,
const vector<pair<typename Arc::Label,
typename Arc::Label> > &parens,
MutableFst<Arc> *ofst,
const ComposeOptions &opts = ComposeOptions()) {
PdtComposeOptions<Arc, false> copts(ifst1, ifst2, parens);
copts.gc_limit = 0;
*ofst = ComposeFst<Arc>(ifst1, ifst2, copts);
if (opts.connect)
Connect(ofst);
}
} // namespace fst
#endif // FST_EXTENSIONS_PDT_COMPOSE_H__