FST  openfst-1.8.2.post1
OpenFst Library
compose.h
Go to the documentation of this file.
1 // Copyright 2005-2020 Google LLC
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 // See www.openfst.org for extensive documentation on this weighted
16 // finite-state transducer library.
17 //
18 // Compose an MPDT and an FST.
19 
20 #ifndef FST_EXTENSIONS_MPDT_COMPOSE_H_
21 #define FST_EXTENSIONS_MPDT_COMPOSE_H_
22 
23 #include <cstdint>
24 #include <list>
25 
28 #include <fst/compose.h>
29 
30 namespace fst {
31 
32 template <class Filter>
34  public:
35  using FST1 = typename Filter::FST1;
36  using FST2 = typename Filter::FST2;
37  using Arc = typename Filter::Arc;
38  using Label = typename Arc::Label;
39  using StateId = typename Arc::StateId;
40  using Weight = typename Arc::Weight;
41 
42  using Matcher1 = typename Filter::Matcher1;
43  using Matcher2 = typename Filter::Matcher2;
44 
45  using StackId = StateId;
47  using FilterState1 = typename Filter::FilterState;
50 
51  MPdtParenFilter(const FST1 &fst1, const FST2 &fst2,
52  Matcher1 *matcher1 = nullptr, Matcher2 *matcher2 = nullptr,
53  const std::vector<std::pair<Label, Label>> *parens = nullptr,
54  const std::vector<Label> *assignments = nullptr,
55  bool expand = false, bool keep_parens = true)
56  : filter_(fst1, fst2, matcher1, matcher2),
57  parens_(parens ? *parens : std::vector<std::pair<Label, Label>>()),
58  assignments_(assignments ? *assignments : std::vector<Label>()),
59  expand_(expand),
60  keep_parens_(keep_parens),
61  fs_(FilterState::NoState()),
62  stack_(parens_, assignments_),
63  paren_id_(-1) {
64  if (parens) {
65  for (const auto &pair : *parens) {
66  parens_.push_back(pair);
67  GetMatcher1()->AddOpenParen(pair.first);
68  GetMatcher2()->AddOpenParen(pair.first);
69  if (!expand_) {
70  GetMatcher1()->AddCloseParen(pair.second);
71  GetMatcher2()->AddCloseParen(pair.second);
72  }
73  }
74  }
75  }
76 
77  MPdtParenFilter(const MPdtParenFilter &filter, bool safe = false)
78  : filter_(filter.filter_, safe),
79  parens_(filter.parens_),
80  expand_(filter.expand_),
81  keep_parens_(filter.keep_parens_),
82  fs_(FilterState::NoState()),
83  stack_(filter.parens_, filter.assignments_),
84  paren_id_(-1) {}
85 
86  FilterState Start() const {
87  return FilterState(filter_.Start(), FilterState2(0));
88  }
89 
90  void SetState(StateId s1, StateId s2, const FilterState &fs) {
91  fs_ = fs;
92  filter_.SetState(s1, s2, fs_.GetState1());
93  if (!expand_) return;
94  const auto paren_id = stack_.Top(fs.GetState2().GetState());
95  if (paren_id != paren_id_) {
96  if (paren_id_ != -1) {
97  GetMatcher1()->RemoveCloseParen(parens_[paren_id_].second);
98  GetMatcher2()->RemoveCloseParen(parens_[paren_id_].second);
99  }
100  paren_id_ = paren_id;
101  if (paren_id_ != -1) {
102  GetMatcher1()->AddCloseParen(parens_[paren_id_].second);
103  GetMatcher2()->AddCloseParen(parens_[paren_id_].second);
104  }
105  }
106  }
107 
108  FilterState FilterArc(Arc *arc1, Arc *arc2) const {
109  const auto fs1 = filter_.FilterArc(arc1, arc2);
110  const auto &fs2 = fs_.GetState2();
111  if (fs1 == FilterState1::NoState()) return FilterState::NoState();
112  if (arc1->olabel == kNoLabel && arc2->ilabel) { // arc2 parentheses.
113  if (keep_parens_) {
114  arc1->ilabel = arc2->ilabel;
115  } else if (arc2->ilabel) {
116  arc2->olabel = arc1->ilabel;
117  }
118  return FilterParen(arc2->ilabel, fs1, fs2);
119  } else if (arc2->ilabel == kNoLabel && arc1->olabel) { // arc1 parentheses
120  if (keep_parens_) {
121  arc2->olabel = arc1->olabel;
122  } else {
123  arc1->ilabel = arc2->olabel;
124  }
125  return FilterParen(arc1->olabel, fs1, fs2);
126  } else {
127  return FilterState(fs1, fs2);
128  }
129  }
130 
131  void FilterFinal(Weight *w1, Weight *w2) const {
132  if (fs_.GetState2().GetState() != 0) *w1 = Weight::Zero();
133  filter_.FilterFinal(w1, w2);
134  }
135 
136  // Returns respective matchers; ownership stays with filter.
137 
138  Matcher1 *GetMatcher1() { return filter_.GetMatcher1(); }
139 
140  Matcher2 *GetMatcher2() { return filter_.GetMatcher2(); }
141 
142  uint64_t Properties(uint64_t iprops) const {
143  const auto oprops = filter_.Properties(iprops);
145  }
146 
147  private:
148  const FilterState FilterParen(Label label, const FilterState1 &fs1,
149  const FilterState2 &fs2) const {
150  if (!expand_) return FilterState(fs1, fs2);
151  const auto stack_id = stack_.Find(fs2.GetState(), label);
152  if (stack_id < 0) {
153  return FilterState::NoState();
154  } else {
155  return FilterState(fs1, FilterState2(stack_id));
156  }
157  }
158 
159  Filter filter_;
160  std::vector<std::pair<Label, Label>> parens_;
161  std::vector<Label> assignments_;
162  bool expand_; // Expands to FST?
163  bool keep_parens_; // Retains parentheses in output?
164  FilterState fs_; // Current filter state.
165  mutable ParenStack stack_;
166  ssize_t paren_id_;
167 };
168 
169 // Class to setup composition options for MPDT composition. Default is to take
170 // the MPDT as the first composition argument.
171 template <class Arc, bool left_pdt = true>
173  : public ComposeFstOptions<
174  Arc, ParenMatcher<Fst<Arc>>,
175  MPdtParenFilter<AltSequenceComposeFilter<ParenMatcher<Fst<Arc>>>>> {
176  public:
177  using Label = typename Arc::Label;
180 
184 
186  const std::vector<std::pair<Label, Label>> &parens,
187  const std::vector<typename Arc::Label> &assignments,
188  const Fst<Arc> &ifst2, bool expand = false,
189  bool keep_parens = true) {
190  matcher1 = new MPdtMatcher(ifst1, MATCH_OUTPUT, kParenList);
191  matcher2 = new MPdtMatcher(ifst2, MATCH_INPUT, kParenLoop);
192  filter = new MPdtFilter(ifst1, ifst2, matcher1, matcher2, &parens,
193  &assignments, expand, keep_parens);
194  }
195 };
196 
197 // Class to setup composition options for PDT with FST composition.
198 // Specialization is for the FST as the first composition argument.
199 template <class Arc>
201  : public ComposeFstOptions<
202  Arc, ParenMatcher<Fst<Arc>>,
203  MPdtParenFilter<SequenceComposeFilter<ParenMatcher<Fst<Arc>>>>> {
204  public:
205  using Label = typename Arc::Label;
208 
212 
213  MPdtComposeFstOptions(const Fst<Arc> &ifst1, const Fst<Arc> &ifst2,
214  const std::vector<std::pair<Label, Label>> &parens,
215  const std::vector<typename Arc::Label> &assignments,
216  bool expand = false, bool keep_parens = true) {
217  matcher1 = new MPdtMatcher(ifst1, MATCH_OUTPUT, kParenLoop);
218  matcher2 = new MPdtMatcher(ifst2, MATCH_INPUT, kParenList);
219  filter = new MPdtFilter(ifst1, ifst2, matcher1, matcher2, &parens,
220  &assignments, expand, keep_parens);
221  }
222 };
223 
225  bool connect; // Connect output?
226  PdtComposeFilter filter_type; // Which pre-defined filter to use.
227 
229  bool connect = true,
231  : connect(connect), filter_type(filter_type) {}
232 };
233 
234 // Composes multi-pushdown transducer (MPDT) encoded as an FST (1st arg) and an
235 // FST (2nd arg) with the result also an MPDT encoded as an FST (3rd arg). In
236 // theMPDTs, some transitions are labeled with open or close parentheses (and
237 // associated with a stack). To be interpreted as an MPDT, the parents on each
238 // stack must balance on a path (see MPdtExpand()). The open-close parenthesis
239 // label pairs are passed using the parens arguments, and the stack assignments
240 // are passed using the assignments argument.
241 template <class Arc>
242 void Compose(
243  const Fst<Arc> &ifst1,
244  const std::vector<std::pair<typename Arc::Label, typename Arc::Label>>
245  &parens,
246  const std::vector<typename Arc::Label> &assignments, const Fst<Arc> &ifst2,
247  MutableFst<Arc> *ofst,
248  const MPdtComposeOptions &opts = MPdtComposeOptions()) {
249  bool expand = opts.filter_type != PdtComposeFilter::PAREN;
250  bool keep_parens = opts.filter_type != PdtComposeFilter::EXPAND;
251  MPdtComposeFstOptions<Arc, true> copts(ifst1, parens, assignments, ifst2,
252  expand, keep_parens);
253  copts.gc_limit = 0;
254  *ofst = ComposeFst<Arc>(ifst1, ifst2, copts);
255  if (opts.connect) Connect(ofst);
256 }
257 
258 // Composes an FST (1st arg) and a multi-pushdown transducer (MPDT) encoded as
259 // an FST (2nd arg) with the result also an MPDT encoded as an FST (3rd arg).
260 // In the MPDTs, some transitions are labeled with open or close parentheses
261 // (and associated with a stack). To be interpreted as an MPDT, the parents on
262 // each stack must balance on a path (see MPdtExpand()). The open-close
263 // parenthesis label pairs are passed using the parens arguments, and the stack
264 // assignments are passed using the assignments argument.
265 template <class Arc>
266 void Compose(
267  const Fst<Arc> &ifst1, const Fst<Arc> &ifst2,
268  const std::vector<std::pair<typename Arc::Label, typename Arc::Label>>
269  &parens,
270  const std::vector<typename Arc::Label> &assignments, MutableFst<Arc> *ofst,
271  const MPdtComposeOptions &opts = MPdtComposeOptions()) {
272  bool expand = opts.filter_type != PdtComposeFilter::PAREN;
273  bool keep_parens = opts.filter_type != PdtComposeFilter::EXPAND;
274  MPdtComposeFstOptions<Arc, false> copts(ifst1, ifst2, parens, assignments,
275  expand, keep_parens);
276  copts.gc_limit = 0;
277  *ofst = ComposeFst<Arc>(ifst1, ifst2, copts);
278  if (opts.connect) Connect(ofst);
279 }
280 
281 } // namespace fst
282 
283 #endif // FST_EXTENSIONS_MPDT_COMPOSE_H_
MPdtComposeFstOptions(const Fst< Arc > &ifst1, const Fst< Arc > &ifst2, const std::vector< std::pair< Label, Label >> &parens, const std::vector< typename Arc::Label > &assignments, bool expand=false, bool keep_parens=true)
Definition: compose.h:213
constexpr uint32_t kParenLoop
Definition: compose.h:35
typename SequenceComposeFilter< ParenMatcher< Fst< Arc > > >::Arc Arc
Definition: compose.h:37
constexpr int kNoLabel
Definition: fst.h:201
typename SequenceComposeFilter< ParenMatcher< Fst< Arc > > >::Matcher1 Matcher1
Definition: compose.h:42
Matcher1 * GetMatcher1()
Definition: compose.h:138
ssize_t Top(StackId stack_id) const
Definition: mpdt.h:119
MPdtParenFilter(const MPdtParenFilter &filter, bool safe=false)
Definition: compose.h:77
MPdtComposeFstOptions(const Fst< Arc > &ifst1, const std::vector< std::pair< Label, Label >> &parens, const std::vector< typename Arc::Label > &assignments, const Fst< Arc > &ifst2, bool expand=false, bool keep_parens=true)
Definition: compose.h:185
IntegerFilterState< StackId > FilterState2
Definition: compose.h:48
void FilterFinal(Weight *w1, Weight *w2) const
Definition: compose.h:131
void Connect(MutableFst< Arc > *fst)
Definition: connect.h:278
typename SequenceComposeFilter< ParenMatcher< Fst< Arc > > >::Matcher2 Matcher2
Definition: compose.h:43
constexpr uint32_t kParenList
Definition: compose.h:32
typename SequenceComposeFilter< ParenMatcher< Fst< Arc > > >::FilterState FilterState1
Definition: compose.h:47
FilterState FilterArc(Arc *arc1, Arc *arc2) const
Definition: compose.h:108
typename SequenceComposeFilter< ParenMatcher< Fst< Arc > > >::FST2 FST2
Definition: compose.h:36
void Compose(const Fst< Arc > &ifst1, const Fst< Arc > &ifst2, MutableFst< Arc > *ofst, const ComposeOptions &opts=ComposeOptions())
Definition: compose.h:995
constexpr uint64_t kOLabelInvariantProperties
Definition: properties.h:269
MPdtParenFilter(const FST1 &fst1, const FST2 &fst2, Matcher1 *matcher1=nullptr, Matcher2 *matcher2=nullptr, const std::vector< std::pair< Label, Label >> *parens=nullptr, const std::vector< Label > *assignments=nullptr, bool expand=false, bool keep_parens=true)
Definition: compose.h:51
void SetState(StateId s1, StateId s2, const FilterState &fs)
Definition: compose.h:90
constexpr uint64_t kILabelInvariantProperties
Definition: properties.h:260
FilterState Start() const
Definition: compose.h:86
MPdtComposeOptions(bool connect=true, PdtComposeFilter filter_type=PdtComposeFilter::PAREN)
Definition: compose.h:228
typename Arc::Label Label
Definition: compose.h:177
const FilterState1 & GetState1() const
Definition: filter-state.h:175
PairFilterState< FilterState1, FilterState2 > FilterState
Definition: compose.h:49
PdtComposeFilter filter_type
Definition: compose.h:226
uint64_t Properties(uint64_t iprops) const
Definition: compose.h:142
Matcher2 * GetMatcher2()
Definition: compose.h:140
const FilterState2 & GetState2() const
Definition: filter-state.h:177
typename SequenceComposeFilter< ParenMatcher< Fst< Arc > > >::FST1 FST1
Definition: compose.h:35
size_t gc_limit
Definition: cache.h:45
PdtComposeFilter
Definition: compose.h:453
StackId Find(StackId stack_id, Label label)
Definition: mpdt.h:257