FST  openfst-1.8.2
OpenFst Library
complement.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 // Class to complement an FST.
19 
20 #ifndef FST_COMPLEMENT_H_
21 #define FST_COMPLEMENT_H_
22 
23 #include <algorithm>
24 #include <cstdint>
25 #include <string>
26 #include <vector>
27 
28 #include <fst/log.h>
29 
30 #include <fst/fst.h>
31 #include <fst/test-properties.h>
32 
33 namespace fst {
34 
35 template <class Arc>
37 
38 namespace internal {
39 
40 // Implementation of delayed ComplementFst. The algorithm used completes the
41 // (deterministic) FSA and then exchanges final and non-final states.
42 // Completion, i.e. ensuring that all labels can be read from every state, is
43 // accomplished by using ρ-labels, which match all labels that are otherwise
44 // not found leaving a state. The first state in the output is reserved to be a
45 // new state that is the destination of all ρ-labels. Each remaining output
46 // state s corresponds to input state s - 1. The first arc in the output at
47 // these states is the ρ-label, the remaining arcs correspond to the input
48 // arcs.
49 template <class A>
50 class ComplementFstImpl : public FstImpl<A> {
51  public:
52  using Arc = A;
53  using Label = typename Arc::Label;
54  using StateId = typename Arc::StateId;
55  using Weight = typename Arc::Weight;
56 
57  using FstImpl<A>::SetType;
61 
63  friend class ArcIterator<ComplementFst<Arc>>;
64 
65  explicit ComplementFstImpl(const Fst<Arc> &fst) : fst_(fst.Copy()) {
66  SetType("complement");
67  const auto props = fst.Properties(kILabelSorted, false);
71  }
72 
74  : fst_(impl.fst_->Copy()) {
75  SetType("complement");
79  }
80 
81  StateId Start() const {
82  if (Properties(kError)) return kNoStateId;
83  const auto start = fst_->Start();
84  return start != kNoStateId ? start + 1 : 0;
85  }
86 
87  // Exchange final and non-final states; makes ρ-destination state final.
88  Weight Final(StateId s) const {
89  if (s == 0 || fst_->Final(s - 1) == Weight::Zero()) {
90  return Weight::One();
91  } else {
92  return Weight::Zero();
93  }
94  }
95 
96  size_t NumArcs(StateId s) const {
97  return s == 0 ? 1 : fst_->NumArcs(s - 1) + 1;
98  }
99 
100  size_t NumInputEpsilons(StateId s) const {
101  return s == 0 ? 0 : fst_->NumInputEpsilons(s - 1);
102  }
103 
104  size_t NumOutputEpsilons(StateId s) const {
105  return s == 0 ? 0 : fst_->NumOutputEpsilons(s - 1);
106  }
107 
108  uint64_t Properties() const override { return Properties(kFstProperties); }
109 
110  // Sets error if found, and returns other FST impl properties.
111  uint64_t Properties(uint64_t mask) const override {
112  if ((mask & kError) && fst_->Properties(kError, false)) {
113  SetProperties(kError, kError);
114  }
115  return FstImpl<Arc>::Properties(mask);
116  }
117 
118  private:
119  std::unique_ptr<const Fst<Arc>> fst_;
120 };
121 
122 } // namespace internal
123 
124 // Complements an automaton. This is a library-internal operation that
125 // introduces a (negative) ρ-label; use Difference/DifferenceFst in user code,
126 // which will not see this label. This version is a delayed FST.
127 //
128 // This class attaches interface to implementation and handles
129 // reference counting, delegating most methods to ImplToFst.
130 template <class A>
131 class ComplementFst : public ImplToFst<internal::ComplementFstImpl<A>> {
132  public:
133  using Arc = A;
134  using Label = typename Arc::Label;
135  using StateId = typename Arc::StateId;
137 
139  friend class ArcIterator<ComplementFst<Arc>>;
140 
141  explicit ComplementFst(const Fst<Arc> &fst)
142  : ImplToFst<Impl>(std::make_shared<Impl>(fst)) {
143  static constexpr auto props =
145  if (fst.Properties(props, true) != props) {
146  FSTERROR() << "ComplementFst: Argument not an unweighted "
147  << "epsilon-free deterministic acceptor";
148  GetImpl()->SetProperties(kError, kError);
149  }
150  }
151 
152  // See Fst<>::Copy() for doc.
153  ComplementFst(const ComplementFst &fst, bool safe = false)
154  : ImplToFst<Impl>(fst, safe) {}
155 
156  // Gets a copy of this FST. See Fst<>::Copy() for further doc.
157  ComplementFst *Copy(bool safe = false) const override {
158  return new ComplementFst(*this, safe);
159  }
160 
161  inline void InitStateIterator(StateIteratorData<Arc> *data) const override;
162 
163  inline void InitArcIterator(StateId s,
164  ArcIteratorData<Arc> *data) const override;
165 
166  // Label that represents the ρ-transition; we use a negative value private to
167  // the library and which will preserve FST label sort order.
168  static constexpr Label kRhoLabel = -2;
169 
170  private:
172 
173  ComplementFst &operator=(const ComplementFst &) = delete;
174 };
175 
176 // Specialization for ComplementFst.
177 template <class Arc>
179  public:
180  using StateId = typename Arc::StateId;
181 
183  : siter_(*fst.GetImpl()->fst_), s_(0) {}
184 
185  bool Done() const final { return s_ > 0 && siter_.Done(); }
186 
187  StateId Value() const final { return s_; }
188 
189  void Next() final {
190  if (s_ != 0) siter_.Next();
191  ++s_;
192  }
193 
194  void Reset() final {
195  siter_.Reset();
196  s_ = 0;
197  }
198 
199  private:
200  StateIterator<Fst<Arc>> siter_;
201  StateId s_;
202 };
203 
204 // Specialization for ComplementFst.
205 template <class Arc>
207  public:
208  using StateId = typename Arc::StateId;
209  using Weight = typename Arc::Weight;
210 
211  ArcIterator(const ComplementFst<Arc> &fst, StateId s) : s_(s), pos_(0) {
212  if (s_ != 0) {
213  aiter_ =
214  std::make_unique<ArcIterator<Fst<Arc>>>(*fst.GetImpl()->fst_, s - 1);
215  }
216  }
217 
218  bool Done() const final {
219  if (s_ != 0) {
220  return pos_ > 0 && aiter_->Done();
221  } else {
222  return pos_ > 0;
223  }
224  }
225 
226  // Adds the ρ-label to the ρ destination state.
227  const Arc &Value() const final {
228  if (pos_ == 0) {
229  arc_.ilabel = arc_.olabel = ComplementFst<Arc>::kRhoLabel;
230  arc_.weight = Weight::One();
231  arc_.nextstate = 0;
232  } else {
233  arc_ = aiter_->Value();
234  ++arc_.nextstate;
235  }
236  return arc_;
237  }
238 
239  void Next() final {
240  if (s_ != 0 && pos_ > 0) aiter_->Next();
241  ++pos_;
242  }
243 
244  size_t Position() const final { return pos_; }
245 
246  void Reset() final {
247  if (s_ != 0) aiter_->Reset();
248  pos_ = 0;
249  }
250 
251  void Seek(size_t a) final {
252  if (s_ != 0) {
253  if (a == 0) {
254  aiter_->Reset();
255  } else {
256  aiter_->Seek(a - 1);
257  }
258  }
259  pos_ = a;
260  }
261 
262  uint8_t Flags() const final { return kArcValueFlags; }
263 
264  void SetFlags(uint8_t, uint8_t) final {}
265 
266  private:
267  std::unique_ptr<ArcIterator<Fst<Arc>>> aiter_;
268  StateId s_;
269  size_t pos_;
270  mutable Arc arc_;
271 };
272 
273 template <class Arc>
275  StateIteratorData<Arc> *data) const {
276  data->base = std::make_unique<StateIterator<ComplementFst<Arc>>>(*this);
277 }
278 
279 template <class Arc>
281  StateId s, ArcIteratorData<Arc> *data) const {
282  data->base = std::make_unique<ArcIterator<ComplementFst<Arc>>>(*this, s);
283 }
284 
285 // Useful alias when using StdArc.
287 
288 } // namespace fst
289 
290 #endif // FST_COMPLEMENT_H_
typename Arc::Label Label
Definition: complement.h:134
void SetProperties(uint64_t props)
Definition: fst.h:710
uint64_t Properties() const override
Definition: complement.h:108
constexpr uint8_t kArcValueFlags
Definition: fst.h:453
virtual uint64_t Properties(uint64_t mask, bool test) const =0
size_t NumOutputEpsilons(StateId s) const
Definition: complement.h:104
Weight Final(StateId s) const
Definition: complement.h:88
const Arc & Value() const final
Definition: complement.h:227
typename Arc::Label Label
Definition: complement.h:53
typename Arc::StateId StateId
Definition: complement.h:135
const SymbolTable * OutputSymbols() const
Definition: fst.h:762
constexpr uint64_t kError
Definition: properties.h:51
size_t NumArcs(StateId s) const
Definition: complement.h:96
void SetOutputSymbols(const SymbolTable *osyms)
Definition: fst.h:772
ComplementFst(const Fst< Arc > &fst)
Definition: complement.h:141
ComplementFstImpl(const Fst< Arc > &fst)
Definition: complement.h:65
ComplementFstImpl(const ComplementFstImpl< Arc > &impl)
Definition: complement.h:73
constexpr int kNoStateId
Definition: fst.h:202
typename Arc::StateId StateId
Definition: complement.h:54
uint64_t Properties(uint64_t mask) const override
Definition: complement.h:111
#define FSTERROR()
Definition: util.h:53
virtual uint64_t Properties() const
Definition: fst.h:702
typename Arc::Weight Weight
Definition: complement.h:55
constexpr uint64_t kCopyProperties
Definition: properties.h:162
ArcIterator(const ComplementFst< Arc > &fst, StateId s)
Definition: complement.h:211
ComplementFst(const ComplementFst &fst, bool safe=false)
Definition: complement.h:153
constexpr uint64_t kNoEpsilons
Definition: properties.h:80
std::unique_ptr< StateIteratorBase< Arc > > base
Definition: fst.h:382
constexpr uint64_t kIDeterministic
Definition: properties.h:68
void SetFlags(uint8_t, uint8_t) final
Definition: complement.h:264
std::unique_ptr< ArcIteratorBase< Arc > > base
Definition: fst.h:495
uint64_t ComplementProperties(uint64_t inprops)
Definition: properties.cc:61
void SetInputSymbols(const SymbolTable *isyms)
Definition: fst.h:768
StateIterator(const ComplementFst< Arc > &fst)
Definition: complement.h:182
constexpr uint64_t kILabelSorted
Definition: properties.h:93
void InitStateIterator(StateIteratorData< Arc > *data) const override
Definition: complement.h:274
constexpr uint64_t kFstProperties
Definition: properties.h:325
constexpr uint64_t kUnweighted
Definition: properties.h:105
ComplementFst * Copy(bool safe=false) const override
Definition: complement.h:157
virtual const SymbolTable * InputSymbols() const =0
const SymbolTable * InputSymbols() const
Definition: fst.h:760
void SetType(std::string_view type)
Definition: fst.h:700
size_t NumInputEpsilons(StateId s) const
Definition: complement.h:100
void InitArcIterator(StateId s, ArcIteratorData< Arc > *data) const override
Definition: complement.h:280
FstImpl & operator=(const FstImpl &impl)
Definition: fst.h:687
const internal::ComplementFstImpl< A > * GetImpl() const
Definition: fst.h:1026
constexpr uint64_t kAcceptor
Definition: properties.h:63
virtual const SymbolTable * OutputSymbols() const =0