GRM-SFST  sfst-1.2.1
OpenGrm SFst Library
equal.h
Go to the documentation of this file.
1 // Copyright 2018-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 // Equal and Isomorphic for normalized stochastic FSTs.
15 
16 #include <cstdint>
17 
18 #include <fst/log.h>
19 #include <fst/arc-map.h>
20 #include <fst/equal.h>
21 #include <fst/fst.h>
22 #include <fst/isomorphic.h>
23 #include <fst/properties.h>
24 #include <sfst/normalize.h>
25 
26 #ifndef NLP_GRM2_SFST_EQUAL_H_
27 #define NLP_GRM2_SFST_EQUAL_H_
28 
29 namespace sfst {
30 
31 namespace internal {
32 
33 // Mapper to map weights on phi-labeled arcs to One()
34 template <class Arc>
36  public:
37  using Label = typename Arc::Label;
38  using Weight = typename Arc::Weight;
39  using FromArc = Arc;
40  using ToArc = Arc;
41 
42  explicit RmPhiWeightMapper(Label phi_label) : phi_label_(phi_label) {}
43 
44  Arc operator()(const Arc &arc) const {
45  return Arc(arc.ilabel, arc.olabel,
46  arc.ilabel == phi_label_ ? Weight::One() : arc.weight,
47  arc.nextstate);
48  }
49 
50  constexpr fst::MapFinalAction FinalAction() const {
51  return fst::MAP_NO_SUPERFINAL;
52  }
53 
54  constexpr fst::MapSymbolsAction InputSymbolsAction() const {
55  return fst::MAP_COPY_SYMBOLS;
56  }
57 
58  constexpr fst::MapSymbolsAction OutputSymbolsAction() const {
59  return fst::MAP_COPY_SYMBOLS;
60  }
61 
62  uint64_t Properties(uint64_t props) const {
63  return (props & fst::kWeightInvariantProperties) | fst::kUnweighted;
64  }
65 
66  private:
67  Label phi_label_;
68 };
69 
70 } // namespace internal
71 
72 // Equal for normalized stochastic FSTs that deals with uninteresting
73 // variations in the failure weights. In particular, if the
74 // FSTs are normalized, comparing failure weights can be skipped since
75 // they are determined by the other weights.
76 template <class Arc>
77 bool Equal(const fst::Fst<Arc> &fst1, const fst::Fst<Arc> &fst2,
78  typename Arc::Label phi_label, float delta = fst::kDelta,
79  uint32_t etype = fst::kEqualFsts) {
80  namespace f = fst;
81  using Mapper = internal::RmPhiWeightMapper<Arc>;
82 
83  if (!IsNormalized(fst1, phi_label, delta)) {
84  FSTERROR() << "Equal: Input FST1 is not normalized";
85  return false;
86  }
87  if (!IsNormalized(fst2, phi_label, delta)) {
88  FSTERROR() << "Equal: Input FST2 is not normalized";
89  return false;
90  }
91 
92  if (phi_label == f::kNoLabel) {
93  return f::Equal(fst1, fst2, delta, etype);
94  } else {
95  // Maps all failure weights to One() before comparing.
96  Mapper mapper(phi_label);
97  f::ArcMapFst mfst1(fst1, mapper);
98  f::ArcMapFst mfst2(fst2, mapper);
99  return f::Equal(mfst1, mfst2, delta, etype);
100  }
101 }
102 
103 // Isomorphic for normalized stochastic FSTs that deals with uninteresting
104 // variations in the failure weights. In particular, if the
105 // FSTs are normalized, comparing failure weights can be skipped since
106 // they are determined by the other weights.
107 template <class Arc>
108 bool Isomorphic(const fst::Fst<Arc> &fst1, const fst::Fst<Arc> &fst2,
109  typename Arc::Label phi_label, float delta = fst::kDelta) {
110  namespace f = fst;
111  using Mapper = internal::RmPhiWeightMapper<Arc>;
112 
113  if (!IsNormalized(fst1, phi_label, delta)) {
114  FSTERROR() << "Isomorphic: Input FST1 is not normalized";
115  return false;
116  }
117  if (!IsNormalized(fst2, phi_label, delta)) {
118  FSTERROR() << "Isomorphic: Input FST2 is not normalized";
119  return false;
120  }
121 
122  if (phi_label == f::kNoLabel) {
123  return f::Isomorphic(fst1, fst2, delta);
124  } else {
125  // Maps all failure weights to One() before comparing
126  Mapper mapper(phi_label);
127  f::ArcMapFst mfst1(fst1, mapper);
128  f::ArcMapFst mfst2(fst2, mapper);
129  return f::Isomorphic(mfst1, mfst2, delta);
130  }
131 }
132 
133 } // namespace sfst
134 
135 #endif // NLP_GRM2_SFST_EQUAL_H_
RmPhiWeightMapper(Label phi_label)
Definition: equal.h:42
typename Arc::Label Label
Definition: equal.h:37
constexpr fst::MapSymbolsAction InputSymbolsAction() const
Definition: equal.h:54
bool Isomorphic(const fst::Fst< Arc > &fst1, const fst::Fst< Arc > &fst2, typename Arc::Label phi_label, float delta=fst::kDelta)
Definition: equal.h:108
Definition: perplexity.h:32
Definition: sfstinfo.cc:39
uint64_t Properties(uint64_t props) const
Definition: equal.h:62
typename Arc::Weight Weight
Definition: equal.h:38
bool Equal(const fst::Fst< Arc > &fst1, const fst::Fst< Arc > &fst2, typename Arc::Label phi_label, float delta=fst::kDelta, uint32_t etype=fst::kEqualFsts)
Definition: equal.h:77
bool IsNormalized(const fst::Fst< Arc > &fst, typename Arc::Label phi_label=fst::kNoLabel, float delta=fst::kDelta)
Definition: normalize.h:159
constexpr fst::MapSymbolsAction OutputSymbolsAction() const
Definition: equal.h:58
Arc operator()(const Arc &arc) const
Definition: equal.h:44
constexpr fst::MapFinalAction FinalAction() const
Definition: equal.h:50