This file is indexed.

/usr/include/fst/reweight.h is in libfst-dev 1.6.3-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// See www.openfst.org for extensive documentation on this weighted
// finite-state transducer library.
//
// Function to reweight an FST.

#ifndef FST_LIB_REWEIGHT_H_
#define FST_LIB_REWEIGHT_H_

#include <vector>
#include <fst/log.h>

#include <fst/mutable-fst.h>


namespace fst {

enum ReweightType { REWEIGHT_TO_INITIAL, REWEIGHT_TO_FINAL };

// Reweights an FST according to a vector of potentials in a given direction.
// The weight must be left distributive when reweighting towards the initial
// state and right distributive when reweighting towards the final states.
//
// An arc of weight w, with an origin state of potential p and destination state
// of potential q, is reweighted by p^-1 \otimes (w \otimes q) when reweighting
// torwards the initial state, and by (p \otimes w) \otimes q^-1 when
// reweighting towards the final states.
template <class Arc>
void Reweight(MutableFst<Arc> *fst,
              const std::vector<typename Arc::Weight> &potential,
              ReweightType type) {
  using Weight = typename Arc::Weight;
  if (fst->NumStates() == 0) return;
  // TODO(kbg): Make this a compile-time static_assert once:
  // 1) All weight properties are made constexpr for all weight types.
  // 2) We have a pleasant way to "deregister" this operation for non-path
  //    semirings so an informative error message is produced. The best
  //    solution will probably involve some kind of SFINAE magic.
  if (type == REWEIGHT_TO_FINAL && !(Weight::Properties() & kRightSemiring)) {
    FSTERROR() << "Reweight: Reweighting to the final states requires "
               << "Weight to be right distributive: " << Weight::Type();
    fst->SetProperties(kError, kError);
    return;
  }
  // TODO(kbg): Make this a compile-time static_assert once:
  // 1) All weight properties are made constexpr for all weight types.
  // 2) We have a pleasant way to "deregister" this operation for non-path
  //    semirings so an informative error message is produced. The best
  //    solution will probably involve some kind of SFINAE magic.
  if (type == REWEIGHT_TO_INITIAL && !(Weight::Properties() & kLeftSemiring)) {
    FSTERROR() << "Reweight: Reweighting to the initial state requires "
               << "Weight to be left distributive: " << Weight::Type();
    fst->SetProperties(kError, kError);
    return;
  }
  StateIterator<MutableFst<Arc>> siter(*fst);
  for (; !siter.Done(); siter.Next()) {
    const auto s = siter.Value();
    if (s == potential.size()) break;
    const auto &weight = potential[s];
    if (weight != Weight::Zero()) {
      for (MutableArcIterator<MutableFst<Arc>> aiter(fst, s); !aiter.Done();
           aiter.Next()) {
        auto arc = aiter.Value();
        if (arc.nextstate >= potential.size()) continue;
        const auto &nextweight = potential[arc.nextstate];
        if (nextweight == Weight::Zero()) continue;
        if (type == REWEIGHT_TO_INITIAL) {
          arc.weight =
              Divide(Times(arc.weight, nextweight), weight, DIVIDE_LEFT);
        }
        if (type == REWEIGHT_TO_FINAL) {
          arc.weight =
              Divide(Times(weight, arc.weight), nextweight, DIVIDE_RIGHT);
        }
        aiter.SetValue(arc);
      }
      if (type == REWEIGHT_TO_INITIAL) {
        fst->SetFinal(s, Divide(fst->Final(s), weight, DIVIDE_LEFT));
      }
    }
    if (type == REWEIGHT_TO_FINAL) {
      fst->SetFinal(s, Times(weight, fst->Final(s)));
    }
  }
  // This handles elements past the end of the potentials array.
  for (; !siter.Done(); siter.Next()) {
    const auto s = siter.Value();
    if (type == REWEIGHT_TO_FINAL) {
      fst->SetFinal(s, Times(Weight::Zero(), fst->Final(s)));
    }
  }
  const auto startweight = fst->Start() < potential.size()
                               ? potential[fst->Start()]
                               : Weight::Zero();
  if ((startweight != Weight::One()) && (startweight != Weight::Zero())) {
    if (fst->Properties(kInitialAcyclic, true) & kInitialAcyclic) {
      const auto s = fst->Start();
      for (MutableArcIterator<MutableFst<Arc>> aiter(fst, s); !aiter.Done();
           aiter.Next()) {
        auto arc = aiter.Value();
        if (type == REWEIGHT_TO_INITIAL) {
          arc.weight = Times(startweight, arc.weight);
        } else {
          arc.weight = Times(Divide(Weight::One(), startweight, DIVIDE_RIGHT),
                             arc.weight);
        }
        aiter.SetValue(arc);
      }
      if (type == REWEIGHT_TO_INITIAL) {
        fst->SetFinal(s, Times(startweight, fst->Final(s)));
      } else {
        fst->SetFinal(s, Times(Divide(Weight::One(), startweight, DIVIDE_RIGHT),
                               fst->Final(s)));
      }
    } else {
      const auto s = fst->AddState();
      const auto weight =
          (type == REWEIGHT_TO_INITIAL)
              ? startweight
              : Divide(Weight::One(), startweight, DIVIDE_RIGHT);
      fst->AddArc(s, Arc(0, 0, weight, fst->Start()));
      fst->SetStart(s);
    }
  }
  fst->SetProperties(ReweightProperties(fst->Properties(kFstProperties, false)),
                     kFstProperties);
}

}  // namespace fst

#endif  // FST_LIB_REWEIGHT_H_