FST  openfst-1.8.4
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 I, class FST = ExpandedFst<typename I::Arc>>
138 class ImplToExpandedFst : public ImplToFst<I, FST> {
139  using Base = ImplToFst<I, FST>;
140 
141  public:
142  using Impl = I;
143  using Arc = typename FST::Arc;
144  using StateId = typename Arc::StateId;
145  using Weight = typename Arc::Weight;
146 
147  StateId NumStates() const override { return GetImpl()->NumStates(); }
148 
149  protected:
150  using Base::GetImpl;
151 
152  explicit ImplToExpandedFst(std::shared_ptr<Impl> impl) : Base(impl) {}
153 
155  : Base(fst, safe) {}
156 
157  static Impl *Read(std::istream &strm, const FstReadOptions &opts) {
158  return Impl::Read(strm, opts);
159  }
160 
161  // Read FST implementation from a file; return NULL on error.
162  // Empty source reads from standard input.
163  static Impl *Read(std::string_view source) {
164  if (!source.empty()) {
165  std::ifstream strm(std::string(source),
166  std::ios_base::in | std::ios_base::binary);
167  if (!strm) {
168  LOG(ERROR) << "ExpandedFst::Read: Can't open file: " << source;
169  return nullptr;
170  }
171  return Impl::Read(strm, FstReadOptions(source));
172  } else {
173  return Impl::Read(std::cin, FstReadOptions("standard input"));
174  }
175  }
176 };
177 
178 // Function to return the number of states in an FST, counting them
179 // if necessary.
180 template <class Arc>
181 typename Arc::StateId CountStates(const Fst<Arc> &fst) {
182  if (std::optional<typename Arc::StateId> num_states =
183  fst.NumStatesIfKnown()) {
184  return *num_states;
185  } else {
186  typename Arc::StateId nstates = 0;
187  for (StateIterator<Fst<Arc>> siter(fst); !siter.Done(); siter.Next()) {
188  ++nstates;
189  }
190  return nstates;
191  }
192 }
193 
194 // Function to return the number of states in a vector of FSTs, counting them if
195 // necessary.
196 template <class Arc>
197 typename Arc::StateId CountStates(const std::vector<const Fst<Arc> *> &fsts) {
198  typename Arc::StateId nstates = 0;
199  for (const auto *fst : fsts) nstates += CountStates(*fst);
200  return nstates;
201 }
202 
203 // Function to return the number of arcs in an FST.
204 template <class F>
205 size_t CountArcs(const F &fst) {
206  size_t narcs = 0;
207  for (StateIterator<F> siter(fst); !siter.Done(); siter.Next()) {
208  narcs += fst.NumArcs(siter.Value());
209  }
210  return narcs;
211 }
212 
213 } // namespace fst
214 
215 #endif // FST_EXPANDED_FST_H_
bool Read(std::istream &strm, const std::string &source, bool rewind=false)
Definition: fst.cc:56
const FstHeader * header
Definition: fst.h:74
static Impl * Read(std::istream &strm, const FstReadOptions &opts)
Definition: expanded-fst.h:157
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:206
#define LOG(type)
Definition: log.h:53
virtual Weight Final(StateId) const =0
To down_cast(From *f)
Definition: compat.h:52
size_t CountArcs(const F &fst)
Definition: expanded-fst.h:205
static Impl * Read(std::string_view source)
Definition: expanded-fst.h:163
virtual size_t NumInputEpsilons(StateId) const =0
const std::string & FstType() const
Definition: fst.h:135
ImplToExpandedFst(std::shared_ptr< Impl > impl)
Definition: expanded-fst.h:152
std::optional< StateId > NumStatesIfKnown() const override
Definition: expanded-fst.h:53
StateId NumStates() const override
Definition: expanded-fst.h:147
ExpandedFst * Copy(bool safe=false) const override=0
virtual std::optional< StateId > NumStatesIfKnown() const
Definition: fst.h:227
ImplToExpandedFst(const ImplToExpandedFst &fst, bool safe)
Definition: expanded-fst.h:154
A Arc
Definition: fst.h:204
Arc::StateId CountStates(const Fst< Arc > &fst)
Definition: expanded-fst.h:181
bool Done() const
Definition: fst.h:414
static ExpandedFst * Read(std::istream &strm, const FstReadOptions &opts)
Definition: expanded-fst.h:61
typename Arc::StateId StateId
Definition: fst.h:205
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:143