1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// info.h
2f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
3f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Licensed under the Apache License, Version 2.0 (the "License");
4f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// you may not use this file except in compliance with the License.
5f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// You may obtain a copy of the License at
6f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
7f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//     http://www.apache.org/licenses/LICENSE-2.0
8f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
9f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Unless required by applicable law or agreed to in writing, software
10f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// distributed under the License is distributed on an "AS IS" BASIS,
11f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// See the License for the specific language governing permissions and
13f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// limitations under the License.
14f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
15f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Copyright 2005-2010 Google, Inc.
16f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Author: riley@google.com (Michael Riley)
17f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson//
18f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// \file
19f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Class to compute various information about FSTs, helper class for fstinfo.cc
20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_SCRIPT_INFO_IMPL_H_
22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_SCRIPT_INFO_IMPL_H_
23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
24f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <string>
25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <vector>
26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::vector;
27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/connect.h>
29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/dfs-visit.h>
30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/fst.h>
31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/lookahead-matcher.h>
32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/matcher.h>
33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/queue.h>
34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/test-properties.h>
35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/verify.h>
36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/visit.h>
37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst {
39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Compute various information about FSTs, helper class for fstinfo.cc.
41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// WARNING: Stand-alone use of this class is not recommended, most code
42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// should call directly the relevant library functions: Fst<A>::NumStates,
43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Fst<A>::NumArcs, TestProperties, ...
44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A> class FstInfo {
45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson public:
46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef A Arc;
47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::StateId StateId;
48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Label Label;
49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  typedef typename A::Weight Weight;
50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // When info_type is "short" (or "auto" and not an ExpandedFst)
52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // then only minimal info is computed and can be requested.
53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  FstInfo(const Fst<A> &fst, bool test_properties,
54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          const string &arc_filter_type = "any",
55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          string info_type = "auto", bool verify = true)
56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      : fst_type_(fst.Type()),
57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        input_symbols_(fst.InputSymbols() ?
58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                       fst.InputSymbols()->Name() : "none"),
59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        output_symbols_(fst.OutputSymbols() ?
60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson                        fst.OutputSymbols()->Name() : "none"),
61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        nstates_(0), narcs_(0), start_(kNoStateId), nfinal_(0),
62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        nepsilons_(0), niepsilons_(0), noepsilons_(0),
63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        naccess_(0), ncoaccess_(0), nconnect_(0), ncc_(0), nscc_(0),
64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        input_match_type_(MATCH_NONE), output_match_type_(MATCH_NONE),
65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        input_lookahead_(false), output_lookahead_(false),
66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        properties_(0), arc_filter_type_(arc_filter_type), long_info_(true) {
67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (info_type == "long") {
68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      long_info_ = true;
69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else if (info_type == "short") {
70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      long_info_ = false;
71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else if (info_type == "auto") {
72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      long_info_ = fst.Properties(kExpanded, false);
73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else {
74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      FSTERROR() << "Bad info type: " << info_type;
75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return;
76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!long_info_)
79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return;
80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    // If the FST is not sane, we return.
82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (verify && !Verify(fst)) {
83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      FSTERROR() << "FstInfo: Verify: FST not well-formed.";
84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      return;
85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    start_ = fst.Start();
88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    properties_ = fst.Properties(kFstProperties, test_properties);
89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    for (StateIterator< Fst<A> > siter(fst);
91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         !siter.Done();
92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         siter.Next()) {
93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      ++nstates_;
94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      StateId s = siter.Value();
95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (fst.Final(s) != Weight::Zero())
96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        ++nfinal_;
97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      for (ArcIterator< Fst<A> > aiter(fst, s);
98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson           !aiter.Done();
99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson           aiter.Next()) {
100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        const A &arc = aiter.Value();
101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        ++narcs_;
102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (arc.ilabel == 0 && arc.olabel == 0)
103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ++nepsilons_;
104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (arc.ilabel == 0)
105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ++niepsilons_;
106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (arc.olabel == 0)
107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ++noepsilons_;
108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    {
112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      vector<StateId> cc;
113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      CcVisitor<Arc> cc_visitor(&cc);
114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      FifoQueue<StateId> fifo_queue;
115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (arc_filter_type == "any") {
116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        Visit(fst, &cc_visitor, &fifo_queue);
117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else if (arc_filter_type == "epsilon") {
118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        Visit(fst, &cc_visitor, &fifo_queue, EpsilonArcFilter<Arc>());
119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else if (arc_filter_type == "iepsilon") {
120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        Visit(fst, &cc_visitor, &fifo_queue, InputEpsilonArcFilter<Arc>());
121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else if (arc_filter_type == "oepsilon") {
122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        Visit(fst, &cc_visitor, &fifo_queue, OutputEpsilonArcFilter<Arc>());
123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else {
124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        FSTERROR() << "Bad arc filter type: " << arc_filter_type;
125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        return;
126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
128f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      for (StateId s = 0; s < cc.size(); ++s) {
129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (cc[s] >= ncc_)
130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ncc_ = cc[s] + 1;
131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    {
135f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      vector<StateId> scc;
136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      vector<bool> access, coaccess;
137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      uint64 props = 0;
138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      SccVisitor<Arc> scc_visitor(&scc, &access, &coaccess, &props);
139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (arc_filter_type == "any") {
140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        DfsVisit(fst, &scc_visitor);
141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else if (arc_filter_type == "epsilon") {
142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        DfsVisit(fst, &scc_visitor, EpsilonArcFilter<Arc>());
143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else if (arc_filter_type == "iepsilon") {
144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        DfsVisit(fst, &scc_visitor, InputEpsilonArcFilter<Arc>());
145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else if (arc_filter_type == "oepsilon") {
146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        DfsVisit(fst, &scc_visitor, OutputEpsilonArcFilter<Arc>());
147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      } else {
148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        FSTERROR() << "Bad arc filter type: " << arc_filter_type;
149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        return;
150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      for (StateId s = 0; s < scc.size(); ++s) {
153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (access[s])
154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ++naccess_;
155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (coaccess[s])
156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ++ncoaccess_;
157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (access[s] && coaccess[s])
158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          ++nconnect_;
159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson        if (scc[s] >= nscc_)
160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson          nscc_ = scc[s] + 1;
161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      }
162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    LookAheadMatcher< Fst<A> > imatcher(fst, MATCH_INPUT);
165f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    input_match_type_ =  imatcher.Type(test_properties);
166f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    input_lookahead_ =  imatcher.Flags() & kInputLookAheadMatcher;
167f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
168f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    LookAheadMatcher< Fst<A> > omatcher(fst, MATCH_OUTPUT);
169f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    output_match_type_ =  omatcher.Type(test_properties);
170f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    output_lookahead_ =  omatcher.Flags() & kOutputLookAheadMatcher;
171f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
172f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
173f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Short info
174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const string& FstType() const { return fst_type_; }
175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const string& ArcType() const { return A::Type(); }
176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const string& InputSymbols() const { return input_symbols_; }
177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const string& OutputSymbols() const { return output_symbols_; }
178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const bool LongInfo() const { return long_info_; }
179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  const string& ArcFilterType() const { return arc_filter_type_; }
180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  // Long info
182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MatchType InputMatchType() const { CheckLong(); return input_match_type_; }
183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MatchType OutputMatchType() const { CheckLong(); return output_match_type_; }
184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool InputLookAhead() const { CheckLong(); return input_lookahead_; }
185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool OutputLookAhead() const { CheckLong();  return output_lookahead_; }
186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumStates() const { CheckLong();  return nstates_; }
187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumArcs() const { CheckLong();  return narcs_; }
188f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 Start() const { CheckLong();  return start_; }
189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumFinal() const { CheckLong();  return nfinal_; }
190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumEpsilons() const { CheckLong();  return nepsilons_; }
191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumInputEpsilons() const { CheckLong(); return niepsilons_; }
192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumOutputEpsilons() const { CheckLong(); return noepsilons_; }
193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumAccessible() const { CheckLong(); return naccess_; }
194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumCoAccessible() const { CheckLong(); return ncoaccess_; }
195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumConnected() const { CheckLong(); return nconnect_; }
196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumCc() const { CheckLong(); return ncc_; }
197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 NumScc() const { CheckLong(); return nscc_; }
198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 Properties() const { CheckLong(); return properties_; }
199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson private:
201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  void CheckLong() const {
202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (!long_info_)
203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      FSTERROR() << "FstInfo: method only available with long info version";
204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  string fst_type_;
207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  string input_symbols_;
208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  string output_symbols_;
209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 nstates_;
210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 narcs_;
211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 start_;
212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 nfinal_;
213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 nepsilons_;
214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 niepsilons_;
215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 noepsilons_;
216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 naccess_;
217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 ncoaccess_;
218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 nconnect_;
219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 ncc_;
220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  int64 nscc_;
221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MatchType input_match_type_;
222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  MatchType output_match_type_;
223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool input_lookahead_;
224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool output_lookahead_;
225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 properties_;
226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  string arc_filter_type_;
227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  bool long_info_;
228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  DISALLOW_COPY_AND_ASSIGN(FstInfo);
229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson};
230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate <class A>
232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonvoid PrintFstInfo(const FstInfo<A> &fstinfo, bool pipe = false) {
233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ostream &os = pipe ? cerr : cout;
234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  ios_base::fmtflags old = os.setf(ios::left);
236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "fst type" <<  fstinfo.FstType() << endl;
238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "arc type" << fstinfo.ArcType() << endl;
240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "input symbol table" << fstinfo.InputSymbols() << endl;
242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "output symbol table" << fstinfo.OutputSymbols() << endl;
244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (!fstinfo.LongInfo()) {
246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    os.setf(old);
247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    return;
248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
251f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "# of states" << fstinfo.NumStates() << endl;
252f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
253f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "# of arcs" << fstinfo.NumArcs() << endl;
254f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
255f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "initial state" << fstinfo.Start() << endl;
256f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
257f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "# of final states" << fstinfo.NumFinal() << endl;
258f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
259f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "# of input/output epsilons" << fstinfo.NumEpsilons() << endl;
260f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
261f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "# of input epsilons" << fstinfo.NumInputEpsilons() << endl;
262f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
263f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "# of output epsilons" << fstinfo.NumOutputEpsilons() << endl;
264f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
265f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
266f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  string arc_type = "";
267f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  if (fstinfo.ArcFilterType() == "epsilon")
268f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    arc_type = "epsilon ";
269f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  else if (fstinfo.ArcFilterType() == "iepsilon")
270f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    arc_type = "input-epsilon ";
271f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  else if (fstinfo.ArcFilterType() == "oepsilon")
272f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    arc_type = "output-epsilon ";
273f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
274f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  string accessible_label = "# of " +  arc_type + "accessible states";
275f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
276f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << accessible_label << fstinfo.NumAccessible() << endl;
277f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  string coaccessible_label = "# of " +  arc_type + "coaccessible states";
278f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
279f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << coaccessible_label << fstinfo.NumCoAccessible() << endl;
280f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  string connected_label = "# of " +  arc_type + "connected states";
281f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
282f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << connected_label << fstinfo.NumConnected() << endl;
283f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  string numcc_label = "# of " +  arc_type + "connected components";
284f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
285f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << numcc_label << fstinfo.NumCc() << endl;
286f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  string numscc_label = "# of " +  arc_type + "strongly conn components";
287f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
288f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << numscc_label << fstinfo.NumScc() << endl;
289f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
290f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
291f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "input matcher"
292f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson     << (fstinfo.InputMatchType() == MATCH_INPUT ? 'y' :
293f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         fstinfo.InputMatchType() == MATCH_NONE ? 'n' : '?') << endl;
294f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
295f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "output matcher"
296f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson     << (fstinfo.OutputMatchType() == MATCH_OUTPUT ? 'y' :
297f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson         fstinfo.OutputMatchType() == MATCH_NONE ? 'n' : '?') << endl;
298f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
299f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "input lookahead"
300f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson     << (fstinfo.InputLookAhead() ? 'y' : 'n') << endl;
301f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.width(50);
302f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os << "output lookahead"
303f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson     << (fstinfo.OutputLookAhead() ? 'y' : 'n') << endl;
304f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
305f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  uint64 prop = 1;
306f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  for (int i = 0; i < 64; ++i, prop <<= 1) {
307f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    if (prop & kBinaryProperties) {
308f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      char value = 'n';
309f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (fstinfo.Properties() & prop) value = 'y';
310f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      os.width(50);
311f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      os << PropertyNames[i] << value << endl;
312f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    } else if (prop & kPosTrinaryProperties) {
313f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      char value = '?';
314f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      if (fstinfo.Properties() & prop) value = 'y';
315f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      else if (fstinfo.Properties() & prop << 1) value = 'n';
316f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      os.width(50);
317f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson      os << PropertyNames[i] << value << endl;
318f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson    }
319f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  }
320f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson  os.setf(old);
321f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}
322f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
323f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson}  // namespace fst
324f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson
325f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif  // FST_SCRIPT_INFO_IMPL_H_
326