FST  openfst-1.8.3
OpenFst Library
expanded-fst.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 // Generic FST augmented with state count-interface class definition.
19 
20 #ifndef FST_EXPANDED_FST_H_
21 #define FST_EXPANDED_FST_H_
22 
23 #include <sys/types.h>
24 
25 #include <cstddef>
26 #include <ios>
27 #include <iostream>
28 #include <istream>
29 #include <memory>
30 #include <optional>
31 #include <string>
32 #include <vector>
33 
34 #include <fst/log.h>
35 #include <fst/arc.h>
36 #include <fstream>
37 #include <fst/fst.h>
38 #include <fst/impl-to-fst.h>
39 #include <fst/properties.h>
40 #include <fst/register.h>
41 
42 namespace fst {
43 
44 // A generic FST plus state count.
45 template <class A>
46 class ExpandedFst : public Fst<A> {
47  public:
48  using Arc = A;
49  using StateId = typename Arc::StateId;
50 
51  virtual StateId NumStates() const = 0; // State count
52 
53  std::optional<StateId> NumStatesIfKnown() const override {
54  return NumStates();
55  }
56 
57  // Get a copy of this ExpandedFst. See Fst<>::Copy() for further doc.
58  ExpandedFst *Copy(bool safe = false) const override = 0;
59 
60  // Read an ExpandedFst from an input stream; return NULL on error.
61  static ExpandedFst *Read(std::istream &strm, const FstReadOptions &opts) {
62  FstReadOptions ropts(opts);
63  FstHeader hdr;
64  if (ropts.header) {
65  hdr = *opts.header;
66  } else {
67  if (!hdr.Read(strm, opts.source)) return nullptr;
68  ropts.header = &hdr;
69  }
70  if (!(hdr.Properties() & kExpanded)) {
71  LOG(ERROR) << "ExpandedFst::Read: Not an ExpandedFst: " << ropts.source;
72  return nullptr;
73  }
74  const auto reader =
75  FstRegister<Arc>::GetRegister()->GetReader(hdr.FstType());
76  if (!reader) {
77  LOG(ERROR) << "ExpandedFst::Read: Unknown FST type \"" << hdr.FstType()
78  << "\" (arc type = \"" << A::Type() << "\"): " << ropts.source;
79  return nullptr;
80  }
81  auto *fst = reader(strm, ropts);
82  if (!fst) return nullptr;
83  return down_cast<ExpandedFst *>(fst);
84  }
85 
86  // Read an ExpandedFst from a file; return NULL on error.
87  // Empty source reads from standard input.
88  static ExpandedFst *Read(std::string_view source) {
89  if (!source.empty()) {
90  std::ifstream strm(std::string(source),
91  std::ios_base::in | std::ios_base::binary);
92  if (!strm) {
93  LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << source;
94  return nullptr;
95  }
96  return Read(strm, FstReadOptions(source));
97  } else {
98  return Read(std::cin, FstReadOptions("standard input"));
99  }
100  }
101 };
102 
103 namespace internal {
104 
105 // ExpandedFst<A> case - abstract methods.
106 template <class Arc>
107 inline typename Arc::Weight Final(const ExpandedFst<Arc> &fst,
108  typename Arc::StateId s) {
109  return fst.Final(s);
110 }
111 
112 template <class Arc>
113 inline ssize_t NumArcs(const ExpandedFst<Arc> &fst, typename Arc::StateId s) {
114  return fst.NumArcs(s);
115 }
116 
117 template <class Arc>
118 inline ssize_t NumInputEpsilons(const ExpandedFst<Arc> &fst,
119  typename Arc::StateId s) {
120  return fst.NumInputEpsilons(s);
121 }
122 
123 template <class Arc>
124 inline ssize_t NumOutputEpsilons(const ExpandedFst<Arc> &fst,
125  typename Arc::StateId s) {
126  return fst.NumOutputEpsilons(s);
127 }
128 
129 } // namespace internal
130 
131 // A useful alias when using StdArc.
133 
134 // This is a helper class template useful for attaching an ExpandedFst
135 // interface to its implementation, handling reference counting. It
136 // delegates to ImplToFst the handling of the Fst interface methods.
137 template <class Impl, class FST = ExpandedFst<typename Impl::Arc>>
138 class ImplToExpandedFst : public ImplToFst<Impl, FST> {
139  public:
140  using Arc = typename FST::Arc;
141  using StateId = typename Arc::StateId;
142  using Weight = typename Arc::Weight;
143 
144  StateId NumStates() const override { return GetImpl()->NumStates(); }
145 
146  protected:
148 
149  explicit ImplToExpandedFst(std::shared_ptr<Impl> impl)
150  : ImplToFst<Impl, FST>(impl) {}
151 
153  : ImplToFst<Impl, FST>(fst, safe) {}
154 
155  static Impl *Read(std::istream &strm, const FstReadOptions &opts) {
156  return Impl::Read(strm, opts);
157  }
158 
159  // Read FST implementation from a file; return NULL on error.
160  // Empty source reads from standard input.
161  static Impl *Read(std::string_view source) {
162  if (!source.empty()) {
163  std::ifstream strm(std::string(source),
164  std::ios_base::in | std::ios_base::binary);
165  if (!strm) {
166  LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << source;
167  return nullptr;
168  }
169  return Impl::Read(strm, FstReadOptions(source));
170  } else {
171  return Impl::Read(std::cin, FstReadOptions("standard input"));
172  }
173  }
174 };
175 
176 // Function to return the number of states in an FST, counting them
177 // if necessary.
178 template <class Arc>
179 typename Arc::StateId CountStates(const Fst<Arc> &fst) {
180  if (std::optional<typename Arc::StateId> num_states =
181  fst.NumStatesIfKnown()) {
182  return *num_states;
183  } else {
184  typename Arc::StateId nstates = 0;
185  for (StateIterator<Fst<Arc>> siter(fst); !siter.Done(); siter.Next()) {
186  ++nstates;
187  }
188  return nstates;
189  }
190 }
191 
192 // Function to return the number of states in a vector of FSTs, counting them if
193 // necessary.
194 template <class Arc>
195 typename Arc::StateId CountStates(const std::vector<const Fst<Arc> *> &fsts) {
196  typename Arc::StateId nstates = 0;
197  for (const auto *fst : fsts) nstates += CountStates(*fst);
198  return nstates;
199 }
200 
201 // Function to return the number of arcs in an FST.
202 template <class F>
203 size_t CountArcs(const F &fst) {
204  size_t narcs = 0;
205  for (StateIterator<F> siter(fst); !siter.Done(); siter.Next()) {
206  narcs += fst.NumArcs(siter.Value());
207  }
208  return narcs;
209 }
210 
211 } // namespace fst
212 
213 #endif // FST_EXPANDED_FST_H_
static Impl * Read(std::istream &strm, const FstReadOptions &opts)
Definition: expanded-fst.h:155
bool Read(std::istream &strm, const std::string &source, bool rewind=false)
Definition: fst.cc:56
const FstHeader * header
Definition: fst.h:74
virtual size_t NumArcs(StateId) const =0
std::string source
Definition: fst.h:73
static ExpandedFst * Read(std::string_view source)
Definition: expanded-fst.h:88
typename Arc::Weight Weight
Definition: fst.h:207
#define LOG(type)
Definition: log.h:53
virtual Weight Final(StateId) const =0
To down_cast(From *f)
Definition: compat.h:50
size_t CountArcs(const F &fst)
Definition: expanded-fst.h:203
virtual size_t NumInputEpsilons(StateId) const =0
const std::string & FstType() const
Definition: fst.h:136
std::optional< StateId > NumStatesIfKnown() const override
Definition: expanded-fst.h:53
ImplToExpandedFst(std::shared_ptr< Impl > impl)
Definition: expanded-fst.h:149
StateId NumStates() const override
Definition: expanded-fst.h:144
ExpandedFst * Copy(bool safe=false) const override=0
ImplToExpandedFst(const ImplToExpandedFst &fst, bool safe)
Definition: expanded-fst.h:152
virtual std::optional< StateId > NumStatesIfKnown() const
Definition: fst.h:228
A Arc
Definition: fst.h:205
Arc::StateId CountStates(const Fst< Arc > &fst)
Definition: expanded-fst.h:179
bool Done() const
Definition: fst.h:415
static ExpandedFst * Read(std::istream &strm, const FstReadOptions &opts)
Definition: expanded-fst.h:61
typename Arc::StateId StateId
Definition: fst.h:206
static Impl * Read(std::string_view source)
Definition: expanded-fst.h:161
virtual StateId NumStates() const =0
constexpr uint64_t kExpanded
Definition: properties.h:46
virtual size_t NumOutputEpsilons(StateId) const =0
uint64_t Properties() const
Definition: fst.h:144