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