| // 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__ |