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