1// compose.h 2 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14// 15// Copyright 2005-2010 Google, Inc. 16// Author: riley@google.com (Michael Riley) 17// 18// \file 19// Compose a PDT and an FST. 20 21#ifndef FST_EXTENSIONS_PDT_COMPOSE_H__ 22#define FST_EXTENSIONS_PDT_COMPOSE_H__ 23 24#include <fst/compose.h> 25 26namespace fst { 27 28// Class to setup composition options for PDT composition. 29// Default is for the PDT as the first composition argument. 30template <class Arc, bool left_pdt = true> 31class PdtComposeOptions : public 32ComposeFstOptions<Arc, 33 MultiEpsMatcher< Matcher<Fst<Arc> > >, 34 MultiEpsFilter<AltSequenceComposeFilter< 35 MultiEpsMatcher< 36 Matcher<Fst<Arc> > > > > > { 37 public: 38 typedef typename Arc::Label Label; 39 typedef MultiEpsMatcher< Matcher<Fst<Arc> > > PdtMatcher; 40 typedef MultiEpsFilter<AltSequenceComposeFilter<PdtMatcher> > PdtFilter; 41 typedef ComposeFstOptions<Arc, PdtMatcher, PdtFilter> COptions; 42 using COptions::matcher1; 43 using COptions::matcher2; 44 using COptions::filter; 45 46 PdtComposeOptions(const Fst<Arc> &ifst1, 47 const vector<pair<Label, Label> > &parens, 48 const Fst<Arc> &ifst2) { 49 matcher1 = new PdtMatcher(ifst1, MATCH_OUTPUT, kMultiEpsList); 50 matcher2 = new PdtMatcher(ifst2, MATCH_INPUT, kMultiEpsLoop); 51 52 // Treat parens as multi-epsilons when composing. 53 for (size_t i = 0; i < parens.size(); ++i) { 54 matcher1->AddMultiEpsLabel(parens[i].first); 55 matcher1->AddMultiEpsLabel(parens[i].second); 56 matcher2->AddMultiEpsLabel(parens[i].first); 57 matcher2->AddMultiEpsLabel(parens[i].second); 58 } 59 60 filter = new PdtFilter(ifst1, ifst2, matcher1, matcher2, true); 61 } 62}; 63 64// Class to setup composition options for PDT with FST composition. 65// Specialization is for the FST as the first composition argument. 66template <class Arc> 67class PdtComposeOptions<Arc, false> : public 68ComposeFstOptions<Arc, 69 MultiEpsMatcher< Matcher<Fst<Arc> > >, 70 MultiEpsFilter<SequenceComposeFilter< 71 MultiEpsMatcher< 72 Matcher<Fst<Arc> > > > > > { 73 public: 74 typedef typename Arc::Label Label; 75 typedef MultiEpsMatcher< Matcher<Fst<Arc> > > PdtMatcher; 76 typedef MultiEpsFilter<SequenceComposeFilter<PdtMatcher> > PdtFilter; 77 typedef ComposeFstOptions<Arc, PdtMatcher, PdtFilter> COptions; 78 using COptions::matcher1; 79 using COptions::matcher2; 80 using COptions::filter; 81 82 PdtComposeOptions(const Fst<Arc> &ifst1, 83 const Fst<Arc> &ifst2, 84 const vector<pair<Label, Label> > &parens) { 85 matcher1 = new PdtMatcher(ifst1, MATCH_OUTPUT, kMultiEpsLoop); 86 matcher2 = new PdtMatcher(ifst2, MATCH_INPUT, kMultiEpsList); 87 88 // Treat parens as multi-epsilons when composing. 89 for (size_t i = 0; i < parens.size(); ++i) { 90 matcher1->AddMultiEpsLabel(parens[i].first); 91 matcher1->AddMultiEpsLabel(parens[i].second); 92 matcher2->AddMultiEpsLabel(parens[i].first); 93 matcher2->AddMultiEpsLabel(parens[i].second); 94 } 95 96 filter = new PdtFilter(ifst1, ifst2, matcher1, matcher2, true); 97 } 98}; 99 100 101// Composes pushdown transducer (PDT) encoded as an FST (1st arg) and 102// an FST (2nd arg) with the result also a PDT encoded as an Fst. (3rd arg). 103// In the PDTs, some transitions are labeled with open or close 104// parentheses. To be interpreted as a PDT, the parens must balance on 105// a path (see PdtExpand()). The open-close parenthesis label pairs 106// are passed in 'parens'. 107template <class Arc> 108void Compose(const Fst<Arc> &ifst1, 109 const vector<pair<typename Arc::Label, 110 typename Arc::Label> > &parens, 111 const Fst<Arc> &ifst2, 112 MutableFst<Arc> *ofst, 113 const ComposeOptions &opts = ComposeOptions()) { 114 115 PdtComposeOptions<Arc, true> copts(ifst1, parens, ifst2); 116 copts.gc_limit = 0; 117 *ofst = ComposeFst<Arc>(ifst1, ifst2, copts); 118 if (opts.connect) 119 Connect(ofst); 120} 121 122 123// Composes an FST (1st arg) and pushdown transducer (PDT) encoded as 124// an FST (2nd arg) with the result also a PDT encoded as an Fst (3rd arg). 125// In the PDTs, some transitions are labeled with open or close 126// parentheses. To be interpreted as a PDT, the parens must balance on 127// a path (see ExpandFst()). The open-close parenthesis label pairs 128// are passed in 'parens'. 129template <class Arc> 130void Compose(const Fst<Arc> &ifst1, 131 const Fst<Arc> &ifst2, 132 const vector<pair<typename Arc::Label, 133 typename Arc::Label> > &parens, 134 MutableFst<Arc> *ofst, 135 const ComposeOptions &opts = ComposeOptions()) { 136 137 PdtComposeOptions<Arc, false> copts(ifst1, ifst2, parens); 138 copts.gc_limit = 0; 139 *ofst = ComposeFst<Arc>(ifst1, ifst2, copts); 140 if (opts.connect) 141 Connect(ofst); 142} 143 144} // namespace fst 145 146#endif // FST_EXTENSIONS_PDT_COMPOSE_H__ 147