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 26 namespace fst { 27 28 // Class to setup composition options for PDT composition. 29 // Default is for the PDT as the first composition argument. 30 template <class Arc, bool left_pdt = true> 31 class PdtComposeOptions : public 32 ComposeFstOptions<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 PdtComposeOptions(const Fst<Arc> & ifst1,const vector<pair<Label,Label>> & parens,const Fst<Arc> & ifst2)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. 66 template <class Arc> 67 class PdtComposeOptions<Arc, false> : public 68 ComposeFstOptions<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 PdtComposeOptions(const Fst<Arc> & ifst1,const Fst<Arc> & ifst2,const vector<pair<Label,Label>> & parens)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'. 107 template <class Arc> 108 void 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'. 129 template <class Arc> 130 void 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