compose.h revision f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2
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