FST  openfst-1.8.2
OpenFst Library
reverse.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 // Functions and classes to sort arcs in an FST.
19 
20 #ifndef FST_REVERSE_H_
21 #define FST_REVERSE_H_
22 
23 #include <algorithm>
24 #include <cstdint>
25 #include <vector>
26 
27 
28 #include <fst/cache.h>
29 
30 
31 namespace fst {
32 
33 // Reverses an FST. The reversed result is written to an output mutable FST.
34 // If A transduces string x to y with weight a, then the reverse of A
35 // transduces the reverse of x to the reverse of y with weight a.Reverse().
36 //
37 // Typically, a = a.Reverse() and an arc is its own reverse (e.g., for
38 // TropicalWeight or LogWeight). In general, e.g., when the weights only form a
39 // left or right semiring, the output arc type must match the input arc type
40 // except having the reversed Weight type.
41 //
42 // When require_superinitial is false, a superinitial state is not created in
43 // the reversed FST iff the input FST has exactly one final state (which becomes
44 // the initial state of the reversed FST) with a final weight of semiring One,
45 // or if it does not belong to any cycle. When require_superinitial is true, a
46 // superinitial state is always created.
47 template <class FromArc, class ToArc>
48 void Reverse(const Fst<FromArc> &ifst, MutableFst<ToArc> *ofst,
49  bool require_superinitial = true) {
50  using StateId = typename FromArc::StateId;
51  using Weight = typename FromArc::Weight;
52  ofst->DeleteStates();
53  ofst->SetInputSymbols(ifst.InputSymbols());
54  ofst->SetOutputSymbols(ifst.OutputSymbols());
55  if (ifst.Properties(kExpanded, false)) {
56  ofst->ReserveStates(CountStates(ifst) + 1);
57  }
58  StateId istart = ifst.Start();
59  StateId ostart = kNoStateId;
60  StateId offset = 0;
61  uint64_t dfs_iprops = 0;
62  uint64_t dfs_oprops = 0;
63  if (!require_superinitial) {
64  for (StateIterator<Fst<FromArc>> siter(ifst); !siter.Done(); siter.Next()) {
65  const auto s = siter.Value();
66  if (ifst.Final(s) == Weight::Zero()) continue;
67  if (ostart != kNoStateId) {
68  ostart = kNoStateId;
69  break;
70  } else {
71  ostart = s;
72  }
73  }
74  if (ostart != kNoStateId && ifst.Final(ostart) != Weight::One()) {
75  std::vector<StateId> scc;
76  SccVisitor<FromArc> scc_visitor(&scc, nullptr, nullptr, &dfs_iprops);
77  DfsVisit(ifst, &scc_visitor);
78  if (std::count(scc.begin(), scc.end(), scc[ostart]) > 1) {
79  ostart = kNoStateId;
80  } else {
81  for (ArcIterator<Fst<FromArc>> aiter(ifst, ostart); !aiter.Done();
82  aiter.Next()) {
83  if (aiter.Value().nextstate == ostart) {
84  ostart = kNoStateId;
85  break;
86  }
87  }
88  }
89  if (ostart != kNoStateId) dfs_oprops = kInitialAcyclic;
90  }
91  }
92  if (ostart == kNoStateId) { // Super-initial requested or needed.
93  ostart = ofst->AddState();
94  offset = 1;
95  }
96  for (StateIterator<Fst<FromArc>> siter(ifst); !siter.Done(); siter.Next()) {
97  const auto is = siter.Value();
98  const auto os = is + offset;
99  while (ofst->NumStates() <= os) ofst->AddState();
100  if (is == istart) ofst->SetFinal(os);
101  const auto weight = ifst.Final(is);
102  if ((weight != Weight::Zero()) && (offset == 1)) {
103  const ToArc oarc(0, 0, weight.Reverse(), os);
104  ofst->AddArc(0, oarc);
105  }
106  for (ArcIterator<Fst<FromArc>> aiter(ifst, is); !aiter.Done();
107  aiter.Next()) {
108  const auto &iarc = aiter.Value();
109  const auto nos = iarc.nextstate + offset;
110  auto weight = iarc.weight.Reverse();
111  if (!offset && (nos == ostart)) {
112  weight = Times(ifst.Final(ostart).Reverse(), weight);
113  }
114  const ToArc oarc(iarc.ilabel, iarc.olabel, weight, os);
115  while (ofst->NumStates() <= nos) ofst->AddState();
116  ofst->AddArc(nos, oarc);
117  }
118  }
119  ofst->SetStart(ostart);
120  if (offset == 0 && ostart == istart) {
121  ofst->SetFinal(ostart, ifst.Final(ostart).Reverse());
122  }
123  const auto iprops = ifst.Properties(kCopyProperties, false) | dfs_iprops;
124  const auto oprops = ofst->Properties(kFstProperties, false) | dfs_oprops;
125  ofst->SetProperties(ReverseProperties(iprops, offset == 1) | oprops,
127 }
128 
129 } // namespace fst
130 
131 #endif // FST_REVERSE_H_
virtual uint64_t Properties(uint64_t mask, bool test) const =0
ErrorWeight Times(const ErrorWeight &, const ErrorWeight &)
Definition: error-weight.h:63
void DfsVisit(const FST &fst, Visitor *visitor, ArcFilter filter, bool access_only=false)
Definition: dfs-visit.h:109
constexpr uint64_t kInitialAcyclic
Definition: properties.h:115
virtual void SetInputSymbols(const SymbolTable *isyms)=0
virtual Weight Final(StateId) const =0
virtual void SetStart(StateId)=0
constexpr int kNoStateId
Definition: fst.h:202
void Reverse(const Fst< Arc > &ifst, const std::vector< std::pair< typename Arc::Label, typename Arc::Label >> &parens, std::vector< typename Arc::Label > *assignments, MutableFst< RevArc > *ofst)
Definition: reverse.h:34
uint64_t ReverseProperties(uint64_t inprops, bool has_superinitial)
Definition: properties.cc:338
constexpr uint64_t kCopyProperties
Definition: properties.h:162
virtual void SetProperties(uint64_t props, uint64_t mask)=0
virtual StateId Start() const =0
constexpr uint64_t kFstProperties
Definition: properties.h:325
virtual void AddArc(StateId, const Arc &)=0
virtual const SymbolTable * InputSymbols() const =0
Arc::StateId CountStates(const Fst< Arc > &fst)
Definition: expanded-fst.h:169
virtual StateId AddState()=0
virtual void ReserveStates(size_t)
Definition: mutable-fst.h:96
virtual void SetFinal(StateId s, Weight weight=Weight::One())=0
virtual void DeleteStates(const std::vector< StateId > &)=0
virtual void SetOutputSymbols(const SymbolTable *osyms)=0
virtual StateId NumStates() const =0
constexpr uint64_t kExpanded
Definition: properties.h:45
virtual const SymbolTable * OutputSymbols() const =0