GRM-SFST  sfst-1.2.1
OpenGrm SFst Library
sfstinfo.cc
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 // Prints out various information about a stochastic FST.
15 
16 #include <cstddef>
17 #include <cstring>
18 #include <ios>
19 #include <iostream>
20 #include <ostream>
21 #include <sstream>
22 #include <string>
23 #include <vector>
24 
25 #include <fst/flags.h>
26 #include <fst/fst-decl.h>
27 #include <fst/fst.h>
28 #include <fst/weight.h>
29 #include <sfst/backoff.h>
30 #include <sfst/canonical.h>
31 #include <sfst/count.h>
32 #include <sfst/normalize.h>
33 #include <sfst/trim.h>
34 
35 DEFINE_double(delta, fst::kDelta, "Comparison delta");
36 DEFINE_int64(phi_label, fst::kNoLabel,
37  "Specifies failure label (default: none)");
38 
39 namespace sfst {
40 
41 template <class Arc>
42 void SfstInfo(const fst::Fst<Arc> &fst) {
43  namespace f = fst;
44  typedef typename Arc::StateId StateId;
45  typedef typename Arc::Label Label;
46  typedef typename Arc::Weight Weight;
47  typedef f::ArcIterator<f::Fst<Arc>> ArcItr;
48  typedef f::StateIterator<f::Fst<Arc>> StateItr;
49 
50  StateId start = fst.Start();
51  StateId nstates = 0;
52  size_t narcs = 0;
53  size_t nphis = 0;
54  size_t nfinal = 0;
55 
56  Label phi_label = FST_FLAGS_phi_label;
57  bool canonical = IsCanonical(fst, phi_label);
58  bool trim = IsTrim(fst, phi_label);
59  bool backoff = IsBackoffComplete(fst, phi_label);
60  bool conservative = IsConservative(fst, FST_FLAGS_delta);
61  bool norm = IsNormalized(fst, phi_label, FST_FLAGS_delta);
62  std::vector<int> state_order;
63  int max_order = 1;
64  if (canonical)
65  max_order = PhiStateOrder(fst, phi_label, &state_order);
66  std::vector<size_t> order_counts(max_order, 0);
67 
68  for (StateItr siter(fst); !siter.Done(); siter.Next()) {
69  ++nstates;
70  StateId s = siter.Value();
71  if (fst.Final(s) != Weight::Zero())
72  ++nfinal;
73  if (canonical)
74  ++order_counts[state_order[s] - 1];
75  for (ArcItr aiter(fst, s); !aiter.Done(); aiter.Next()) {
76  ++narcs;
77  const Arc &arc = aiter.Value();
78  if (arc.ilabel == phi_label)
79  ++nphis;
80  }
81  }
82 
83  const auto old = std::cout.setf(std::ios::left);
84  std::cout.width(50);
85  std::cout << "# of states" << nstates << std::endl;
86  std::cout.width(50);
87  std::cout << "# of arcs" << narcs << std::endl;
88  std::cout.width(50);
89  std::cout << "# of failure transitions" << nphis << std::endl;
90  std::cout.width(50);
91  std::cout << "initial state" << start << std::endl;
92  std::cout.width(50);
93  std::cout << "# of final states" << nfinal << std::endl;
94  if (canonical) {
95  std::cout.width(50);
96  std::cout << "max state order" << max_order << std::endl;
97  for (int order = 1; order <= max_order; ++order) {
98  std::stringstream label;
99  label << "# of order-" << order << " states";
100  std::cout.width(50);
101  std::cout << label.str() << order_counts[order - 1] << std::endl;
102  }
103  }
104  std::cout.width(50);
105  std::cout << "canonical" << (canonical ? 'y' : 'n')
106  << std::endl;
107  std::cout.width(50);
108  std::cout << "backoff-complete" << (backoff ? 'y' : 'n')
109  << std::endl;
110  std::cout.width(50);
111  std::cout << "trim" << (trim ? 'y' : 'n')
112  << std::endl;
113  std::cout.width(50);
114  std::cout << "conservative" << (conservative ? 'y' : 'n')
115  << std::endl;
116  std::cout.width(50);
117  std::cout << "normalized" << (norm ? 'y' : 'n')
118  << std::endl;
119  std::cout.width(50);
120  std::cout << "symbols" << (fst.InputSymbols() ? 'y' : 'n') << std::endl;
121  std::cout.setf(old);
122 }
123 
124 } // namespace sfst
125 
126 
127 int main(int argc, char **argv) {
128  using fst::StdFst;
129 
130  std::string usage =
131  "Prints out information about a stochastic FST.\n\n Usage: ";
132  usage += argv[0];
133  usage += " [in.fst]\n";
134 
135  SET_FLAGS(usage.c_str(), &argc, &argv, true);
136  if (argc > 2) {
137  ShowUsage();
138  return 1;
139  }
140 
141  std::string in_name =
142  (argc > 1 && (strcmp(argv[1], "-") != 0)) ? argv[1] : "";
143 
144  StdFst *ifst = StdFst::Read(in_name);
145  if (!ifst) return 1;
146 
147  sfst::SfstInfo(*ifst);
148 
149  return 0;
150 }
int main(int argc, char **argv)
Definition: sfstinfo.cc:127
int PhiStateOrder(const fst::Fst< Arc > &fst, typename Arc::Label phi_label, std::vector< int > *state_order)
Definition: canonical.h:123
Definition: perplexity.h:32
DEFINE_double(delta, fst::kDelta,"Comparison delta")
Definition: sfstinfo.cc:39
bool IsConservative(const fst::Fst< Arc > &fst, float delta=fst::kDelta)
Definition: count.h:447
DEFINE_int64(phi_label, fst::kNoLabel,"Specifies failure label (default: none)")
bool IsCanonical(const fst::Fst< Arc > &fst, typename Arc::Label phi_label, std::vector< typename Arc::StateId > *top_order)
Definition: canonical.h:71
bool IsNormalized(const fst::Fst< Arc > &fst, typename Arc::Label phi_label=fst::kNoLabel, float delta=fst::kDelta)
Definition: normalize.h:159
void SfstInfo(const fst::Fst< Arc > &fst)
Definition: sfstinfo.cc:42
bool IsTrim(const fst::Fst< Arc > &fst, typename Arc::Label phi_label)
Definition: trim.h:405
bool IsBackoffComplete(const fst::Fst< Arc > &fst, typename Arc::Label phi_label)
Definition: backoff.h:240