// algo_test.h

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// Copyright 2005-2010 Google, Inc.
// Author: riley@google.com (Michael Riley)
//
// \file
// Regression test for various FST algorithms.

#ifndef FST_TEST_ALGO_TEST_H__
#define FST_TEST_ALGO_TEST_H__

#include <fst/fstlib.h>
#include <fst/random-weight.h>

DECLARE_int32(repeat);  // defined in ./algo_test.cc

namespace fst {

// Mapper to change input and output label of every transition into
// epsilons.
template <class A>
class EpsMapper {
 public:
  EpsMapper() {}

  A operator()(const A &arc) const {
    return A(0, 0, arc.weight, arc.nextstate);
  }

  uint64 Properties(uint64 props) const {
    props &= ~kNotAcceptor;
    props |= kAcceptor;
    props &= ~kNoIEpsilons & ~kNoOEpsilons &  ~kNoEpsilons;
    props |= kIEpsilons | kOEpsilons | kEpsilons;
    props &= ~kNotILabelSorted & ~kNotOLabelSorted;
    props |= kILabelSorted | kOLabelSorted;
    return props;
  }

  MapFinalAction FinalAction() const { return MAP_NO_SUPERFINAL; }


  MapSymbolsAction InputSymbolsAction() const { return MAP_COPY_SYMBOLS;}

  MapSymbolsAction OutputSymbolsAction() const { return MAP_COPY_SYMBOLS;}
};

// This class tests a variety of identities and properties that must
// hold for various algorithms on weighted FSTs.
template <class Arc, class WeightGenerator>
class WeightedTester {
 public:
  typedef typename Arc::Label Label;
  typedef typename Arc::StateId StateId;
  typedef typename Arc::Weight Weight;

  WeightedTester(int seed, const Fst<Arc> &zero_fst, const Fst<Arc> &one_fst,
                 const Fst<Arc> &univ_fst, WeightGenerator *weight_generator)
      : seed_(seed), zero_fst_(zero_fst), one_fst_(one_fst),
        univ_fst_(univ_fst), weight_generator_(weight_generator) {}

  void Test(const Fst<Arc> &T1, const Fst<Arc> &T2, const Fst<Arc> &T3) {
    TestRational(T1, T2, T3);
    TestMap(T1);
    TestCompose(T1, T2, T3);
    TestSort(T1);
    TestOptimize(T1);
    TestSearch(T1);
  }

 private:
  // Tests rational operations with identities
  void TestRational(const Fst<Arc> &T1, const Fst<Arc> &T2,
                    const Fst<Arc> &T3) {

    {
      VLOG(1) << "Check destructive and delayed union are equivalent.";
      VectorFst<Arc> U1(T1);
      Union(&U1,  T2);
      UnionFst<Arc> U2(T1, T2);
      CHECK(Equiv(U1, U2));
    }


    {
      VLOG(1) << "Check destructive and delayed concatenation are equivalent.";
      VectorFst<Arc> C1(T1);
      Concat(&C1,  T2);
      ConcatFst<Arc> C2(T1, T2);
      CHECK(Equiv(C1, C2));
      VectorFst<Arc> C3(T2);
      Concat(T1, &C3);
      CHECK(Equiv(C3, C2));
    }

    {
      VLOG(1) << "Check destructive and delayed closure* are equivalent.";
      VectorFst<Arc> C1(T1);
      Closure(&C1, CLOSURE_STAR);
      ClosureFst<Arc> C2(T1, CLOSURE_STAR);
      CHECK(Equiv(C1, C2));
    }

    {
      VLOG(1) << "Check destructive and delayed closure+ are equivalent.";
      VectorFst<Arc> C1(T1);
      Closure(&C1, CLOSURE_PLUS);
      ClosureFst<Arc> C2(T1, CLOSURE_PLUS);
      CHECK(Equiv(C1, C2));
    }

    {
      VLOG(1)  << "Check union is associative (destructive).";
      VectorFst<Arc> U1(T1);
      Union(&U1, T2);
      Union(&U1, T3);

      VectorFst<Arc> U3(T2);
      Union(&U3, T3);
      VectorFst<Arc> U4(T1);
      Union(&U4, U3);

      CHECK(Equiv(U1, U4));
    }

    {
      VLOG(1) << "Check union is associative (delayed).";
      UnionFst<Arc> U1(T1, T2);
      UnionFst<Arc> U2(U1, T3);

      UnionFst<Arc> U3(T2, T3);
      UnionFst<Arc> U4(T1, U3);

      CHECK(Equiv(U2, U4));
    }


    {
      VLOG(1) << "Check union is associative (destructive delayed).";
      UnionFst<Arc> U1(T1, T2);
      Union(&U1, T3);

      UnionFst<Arc> U3(T2, T3);
      UnionFst<Arc> U4(T1, U3);

      CHECK(Equiv(U1, U4));
    }

    {
      VLOG(1) << "Check concatenation is associative (destructive).";
      VectorFst<Arc> C1(T1);
      Concat(&C1, T2);
      Concat(&C1, T3);

      VectorFst<Arc> C3(T2);
      Concat(&C3, T3);
      VectorFst<Arc> C4(T1);
      Concat(&C4, C3);

      CHECK(Equiv(C1, C4));
    }

    {
      VLOG(1) << "Check concatenation is associative (delayed).";
      ConcatFst<Arc> C1(T1, T2);
      ConcatFst<Arc> C2(C1, T3);

      ConcatFst<Arc> C3(T2, T3);
      ConcatFst<Arc> C4(T1, C3);

      CHECK(Equiv(C2, C4));
    }

    {
      VLOG(1) << "Check concatenation is associative (destructive delayed).";
      ConcatFst<Arc> C1(T1, T2);
      Concat(&C1, T3);

      ConcatFst<Arc> C3(T2, T3);
      ConcatFst<Arc> C4(T1, C3);

      CHECK(Equiv(C1, C4));
    }

    if (Weight::Properties() & kLeftSemiring) {
      VLOG(1) << "Check concatenation left distributes"
              << " over union (destructive).";

      VectorFst<Arc> U1(T1);
      Union(&U1, T2);
      VectorFst<Arc> C1(T3);
      Concat(&C1, U1);

      VectorFst<Arc> C2(T3);
      Concat(&C2, T1);
      VectorFst<Arc> C3(T3);
      Concat(&C3, T2);
      VectorFst<Arc> U2(C2);
      Union(&U2, C3);

      CHECK(Equiv(C1, U2));
    }

    if (Weight::Properties() & kRightSemiring) {
      VLOG(1) << "Check concatenation right distributes"
              <<  " over union (destructive).";
      VectorFst<Arc> U1(T1);
      Union(&U1, T2);
      VectorFst<Arc> C1(U1);
      Concat(&C1, T3);

      VectorFst<Arc> C2(T1);
      Concat(&C2, T3);
      VectorFst<Arc> C3(T2);
      Concat(&C3, T3);
      VectorFst<Arc> U2(C2);
      Union(&U2, C3);

      CHECK(Equiv(C1, U2));
    }

    if (Weight::Properties() & kLeftSemiring) {
      VLOG(1) << "Check concatenation left distributes over union (delayed).";
      UnionFst<Arc> U1(T1, T2);
      ConcatFst<Arc> C1(T3, U1);

      ConcatFst<Arc> C2(T3, T1);
      ConcatFst<Arc> C3(T3, T2);
      UnionFst<Arc> U2(C2, C3);

      CHECK(Equiv(C1, U2));
    }

    if (Weight::Properties() & kRightSemiring) {
      VLOG(1) << "Check concatenation right distributes over union (delayed).";
      UnionFst<Arc> U1(T1, T2);
      ConcatFst<Arc> C1(U1, T3);

      ConcatFst<Arc> C2(T1, T3);
      ConcatFst<Arc> C3(T2, T3);
      UnionFst<Arc> U2(C2, C3);

      CHECK(Equiv(C1, U2));
    }


    if (Weight::Properties() & kLeftSemiring) {
      VLOG(1) << "Check T T* == T+ (destructive).";
      VectorFst<Arc> S(T1);
      Closure(&S, CLOSURE_STAR);
      VectorFst<Arc> C(T1);
      Concat(&C, S);

      VectorFst<Arc> P(T1);
      Closure(&P, CLOSURE_PLUS);

      CHECK(Equiv(C, P));
    }


    if (Weight::Properties() & kRightSemiring) {
      VLOG(1) << "Check T* T == T+ (destructive).";
      VectorFst<Arc> S(T1);
      Closure(&S, CLOSURE_STAR);
      VectorFst<Arc> C(S);
      Concat(&C, T1);

      VectorFst<Arc> P(T1);
      Closure(&P, CLOSURE_PLUS);

      CHECK(Equiv(C, P));
   }

    if (Weight::Properties() & kLeftSemiring) {
      VLOG(1) << "Check T T* == T+ (delayed).";
      ClosureFst<Arc> S(T1, CLOSURE_STAR);
      ConcatFst<Arc> C(T1, S);

      ClosureFst<Arc> P(T1, CLOSURE_PLUS);

      CHECK(Equiv(C, P));
    }

    if (Weight::Properties() & kRightSemiring) {
      VLOG(1) << "Check T* T == T+ (delayed).";
      ClosureFst<Arc> S(T1, CLOSURE_STAR);
      ConcatFst<Arc> C(S, T1);

      ClosureFst<Arc> P(T1, CLOSURE_PLUS);

      CHECK(Equiv(C, P));
    }
  }

  // Tests map-based operations.
  void TestMap(const Fst<Arc> &T) {

    {
      VLOG(1) << "Check destructive and delayed projection are equivalent.";
      VectorFst<Arc> P1(T);
      Project(&P1, PROJECT_INPUT);
      ProjectFst<Arc> P2(T, PROJECT_INPUT);
      CHECK(Equiv(P1, P2));
    }


    {
      VLOG(1) << "Check destructive and delayed inversion are equivalent.";
      VectorFst<Arc> I1(T);
      Invert(&I1);
      InvertFst<Arc> I2(T);
      CHECK(Equiv(I1, I2));
    }

    {
      VLOG(1) << "Check Pi_1(T) = Pi_2(T^-1) (destructive).";
      VectorFst<Arc> P1(T);
      VectorFst<Arc> I1(T);
      Project(&P1, PROJECT_INPUT);
      Invert(&I1);
      Project(&I1, PROJECT_OUTPUT);
      CHECK(Equiv(P1, I1));
    }

    {
      VLOG(1) << "Check Pi_2(T) = Pi_1(T^-1) (destructive).";
      VectorFst<Arc> P1(T);
      VectorFst<Arc> I1(T);
      Project(&P1, PROJECT_OUTPUT);
      Invert(&I1);
      Project(&I1, PROJECT_INPUT);
      CHECK(Equiv(P1, I1));
    }

    {
      VLOG(1) << "Check Pi_1(T) = Pi_2(T^-1) (delayed).";
      ProjectFst<Arc> P1(T, PROJECT_INPUT);
      InvertFst<Arc> I1(T);
      ProjectFst<Arc> P2(I1, PROJECT_OUTPUT);
      CHECK(Equiv(P1, P2));
    }


    {
      VLOG(1) << "Check Pi_2(T) = Pi_1(T^-1) (delayed).";
      ProjectFst<Arc> P1(T, PROJECT_OUTPUT);
      InvertFst<Arc> I1(T);
      ProjectFst<Arc> P2(I1, PROJECT_INPUT);
      CHECK(Equiv(P1, P2));
    }


    {
      VLOG(1) << "Check destructive relabeling";
      static const int kNumLabels = 10;
      // set up relabeling pairs
      vector<Label> labelset(kNumLabels);
      for (size_t i = 0; i < kNumLabels; ++i) labelset[i] = i;
      for (size_t i = 0; i < kNumLabels; ++i) {
        swap(labelset[i], labelset[rand() % kNumLabels]);
      }

      vector<pair<Label, Label> > ipairs1(kNumLabels);
      vector<pair<Label, Label> > opairs1(kNumLabels);
      for (size_t i = 0; i < kNumLabels; ++i) {
        ipairs1[i] = make_pair(i, labelset[i]);
        opairs1[i] = make_pair(labelset[i], i);
      }
      VectorFst<Arc> R(T);
      Relabel(&R, ipairs1, opairs1);

      vector<pair<Label, Label> > ipairs2(kNumLabels);
      vector<pair<Label, Label> > opairs2(kNumLabels);
      for (size_t i = 0; i < kNumLabels; ++i) {
        ipairs2[i] = make_pair(labelset[i], i);
        opairs2[i] = make_pair(i, labelset[i]);
      }
      Relabel(&R, ipairs2, opairs2);
      CHECK(Equiv(R, T));

      VLOG(1) << "Check on-the-fly relabeling";
      RelabelFst<Arc> Rdelay(T, ipairs1, opairs1);

      RelabelFst<Arc> RRdelay(Rdelay, ipairs2, opairs2);
      CHECK(Equiv(RRdelay, T));
    }

    {
      VLOG(1) << "Check encoding/decoding (destructive).";
      VectorFst<Arc> D(T);
      uint32 encode_props = 0;
      if (rand() % 2)
        encode_props |= kEncodeLabels;
      if (rand() % 2)
        encode_props |= kEncodeWeights;
      EncodeMapper<Arc> encoder(encode_props, ENCODE);
      Encode(&D, &encoder);
      Decode(&D, encoder);
      CHECK(Equiv(D, T));
    }

    {
      VLOG(1) << "Check encoding/decoding (delayed).";
      uint32 encode_props = 0;
      if (rand() % 2)
        encode_props |= kEncodeLabels;
      if (rand() % 2)
        encode_props |= kEncodeWeights;
      EncodeMapper<Arc> encoder(encode_props, ENCODE);
      EncodeFst<Arc> E(T, &encoder);
      VectorFst<Arc> Encoded(E);
      DecodeFst<Arc> D(Encoded, encoder);
      CHECK(Equiv(D, T));
    }

    {
      VLOG(1) << "Check gallic mappers (constructive).";
      ToGallicMapper<Arc> to_mapper;
      FromGallicMapper<Arc> from_mapper;
      VectorFst< GallicArc<Arc> > G;
      VectorFst<Arc> F;
      ArcMap(T, &G, to_mapper);
      ArcMap(G, &F, from_mapper);
      CHECK(Equiv(T, F));
    }

    {
      VLOG(1) << "Check gallic mappers (delayed).";
      ToGallicMapper<Arc> to_mapper;
      FromGallicMapper<Arc> from_mapper;
      ArcMapFst<Arc, GallicArc<Arc>, ToGallicMapper<Arc> >
        G(T, to_mapper);
      ArcMapFst<GallicArc<Arc>, Arc, FromGallicMapper<Arc> >
        F(G, from_mapper);
      CHECK(Equiv(T, F));
    }
  }

  // Tests compose-based operations.
  void TestCompose(const Fst<Arc> &T1, const Fst<Arc> &T2,
                   const Fst<Arc> &T3) {
    if (!(Weight::Properties() & kCommutative))
      return;

    VectorFst<Arc> S1(T1);
    VectorFst<Arc> S2(T2);
    VectorFst<Arc> S3(T3);

    ILabelCompare<Arc> icomp;
    OLabelCompare<Arc> ocomp;

    ArcSort(&S1, ocomp);
    ArcSort(&S2, ocomp);
    ArcSort(&S3, icomp);

    {
      VLOG(1) << "Check composition is associative.";
      ComposeFst<Arc> C1(S1, S2);

      ComposeFst<Arc> C2(C1, S3);
      ComposeFst<Arc> C3(S2, S3);
      ComposeFst<Arc> C4(S1, C3);

      CHECK(Equiv(C2, C4));
    }

    {
      VLOG(1) << "Check composition left distributes over union.";
      UnionFst<Arc> U1(S2, S3);
      ComposeFst<Arc> C1(S1, U1);

      ComposeFst<Arc> C2(S1, S2);
      ComposeFst<Arc> C3(S1, S3);
      UnionFst<Arc> U2(C2, C3);

      CHECK(Equiv(C1, U2));
    }

    {
      VLOG(1) << "Check composition right distributes over union.";
      UnionFst<Arc> U1(S1, S2);
      ComposeFst<Arc> C1(U1, S3);

      ComposeFst<Arc> C2(S1, S3);
      ComposeFst<Arc> C3(S2, S3);
      UnionFst<Arc> U2(C2, C3);

      CHECK(Equiv(C1, U2));
    }

    VectorFst<Arc> A1(S1);
    VectorFst<Arc> A2(S2);
    VectorFst<Arc> A3(S3);
    Project(&A1, PROJECT_OUTPUT);
    Project(&A2, PROJECT_INPUT);
    Project(&A3, PROJECT_INPUT);

    {
      VLOG(1) << "Check intersection is commutative.";
      IntersectFst<Arc> I1(A1, A2);
      IntersectFst<Arc> I2(A2, A1);
      CHECK(Equiv(I1, I2));
    }

    {
      VLOG(1) << "Check all epsilon filters leads to equivalent results.";
      typedef Matcher< Fst<Arc> > M;
      ComposeFst<Arc> C1(S1, S2);
      ComposeFst<Arc> C2(
          S1, S2,
          ComposeFstOptions<Arc, M, AltSequenceComposeFilter<M> >());
      ComposeFst<Arc> C3(
          S1, S2,
          ComposeFstOptions<Arc, M, MatchComposeFilter<M> >());

      CHECK(Equiv(C1, C2));
      CHECK(Equiv(C1, C3));
    }
  }

  // Tests sorting operations
  void TestSort(const Fst<Arc> &T) {
    ILabelCompare<Arc> icomp;
    OLabelCompare<Arc> ocomp;

    {
      VLOG(1) << "Check arc sorted Fst is equivalent to its input.";
      VectorFst<Arc> S1(T);
      ArcSort(&S1, icomp);
      CHECK(Equiv(T, S1));
    }

    {
      VLOG(1) << "Check destructive and delayed arcsort are equivalent.";
      VectorFst<Arc> S1(T);
      ArcSort(&S1, icomp);
      ArcSortFst< Arc, ILabelCompare<Arc> > S2(T, icomp);
      CHECK(Equiv(S1, S2));
    }

    {
      VLOG(1) << "Check ilabel sorting vs. olabel sorting with inversions.";
      VectorFst<Arc> S1(T);
      VectorFst<Arc> S2(T);
      ArcSort(&S1, icomp);
      Invert(&S2);
      ArcSort(&S2, ocomp);
      Invert(&S2);
      CHECK(Equiv(S1, S2));
    }

    {
      VLOG(1) << "Check topologically sorted Fst is equivalent to its input.";
      VectorFst<Arc> S1(T);
      TopSort(&S1);
      CHECK(Equiv(T, S1));
    }

    {
      VLOG(1) << "Check reverse(reverse(T)) = T";
      VectorFst< ReverseArc<Arc> > R1;
      VectorFst<Arc> R2;
      Reverse(T, &R1);
      Reverse(R1, &R2);
      CHECK(Equiv(T, R2));
    }
  }

  // Tests optimization operations
  void TestOptimize(const Fst<Arc> &T) {
    uint64 tprops = T.Properties(kFstProperties, true);
    uint64 wprops = Weight::Properties();

    VectorFst<Arc> A(T);
    Project(&A, PROJECT_INPUT);

    {
      VLOG(1) << "Check connected FST is equivalent to its input.";
      VectorFst<Arc> C1(T);
      Connect(&C1);
      CHECK(Equiv(T, C1));
    }

    if ((wprops & kSemiring) == kSemiring &&
        (tprops & kAcyclic || wprops & kIdempotent)) {
      VLOG(1) << "Check epsilon-removed FST is equivalent to its input.";
      VectorFst<Arc> R1(T);
      RmEpsilon(&R1);
      CHECK(Equiv(T, R1));

      VLOG(1) << "Check destructive and delayed epsilon removal"
              << "are equivalent.";
      RmEpsilonFst<Arc> R2(T);
      CHECK(Equiv(R1, R2));

      VLOG(1) << "Check an FST with a large proportion"
              << " of epsilon transitions:";
      // Maps all transitions of T to epsilon-transitions and append
      // a non-epsilon transition.
      VectorFst<Arc> U;
      ArcMap(T, &U, EpsMapper<Arc>());
      VectorFst<Arc> V;
      V.SetStart(V.AddState());
      Arc arc(1, 1, Weight::One(), V.AddState());
      V.AddArc(V.Start(), arc);
      V.SetFinal(arc.nextstate, Weight::One());
      Concat(&U, V);
      // Check that epsilon-removal preserves the shortest-distance
      // from the initial state to the final states.
      vector<Weight> d;
      ShortestDistance(U, &d, true);
      Weight w = U.Start() < d.size() ? d[U.Start()] : Weight::Zero();
      VectorFst<Arc> U1(U);
      RmEpsilon(&U1);
      ShortestDistance(U1, &d, true);
      Weight w1 = U1.Start() < d.size() ? d[U1.Start()] : Weight::Zero();
      CHECK(ApproxEqual(w, w1, kTestDelta));
      RmEpsilonFst<Arc> U2(U);
      ShortestDistance(U2, &d, true);
      Weight w2 = U2.Start() < d.size() ? d[U2.Start()] : Weight::Zero();
      CHECK(ApproxEqual(w, w2, kTestDelta));
    }

    if ((wprops & kSemiring) == kSemiring && tprops & kAcyclic) {
      VLOG(1) << "Check determinized FSA is equivalent to its input.";
      DeterminizeFst<Arc> D(A);
      CHECK(Equiv(A, D));


      int n;
      {
        VLOG(1) << "Check size(min(det(A))) <= size(det(A))"
                << " and  min(det(A)) equiv det(A)";
        VectorFst<Arc> M(D);
        n = M.NumStates();
        Minimize(&M);
        CHECK(Equiv(D, M));
        CHECK(M.NumStates() <= n);
        n = M.NumStates();
      }

      if (n && (wprops & kIdempotent) == kIdempotent &&
          A.Properties(kNoEpsilons, true)) {
        VLOG(1) << "Check that Revuz's algorithm leads to the"
                << " same number of states as Brozozowski's algorithm";

        // Skip test if A is the empty machine or contains epsilons or
        // if the semiring is not idempotent (to avoid floating point
        // errors)
        VectorFst<Arc> R;
        Reverse(A, &R);
        RmEpsilon(&R);
        DeterminizeFst<Arc> DR(R);
        VectorFst<Arc> RD;
        Reverse(DR, &RD);
        DeterminizeFst<Arc> DRD(RD);
        VectorFst<Arc> M(DRD);
        CHECK_EQ(n + 1, M.NumStates());  // Accounts for the epsilon transition
                                         // to the initial state
      }
    }

    if (Arc::Type() == LogArc::Type() || Arc::Type() == StdArc::Type()) {
      VLOG(1) << "Check reweight(T) equiv T";
      vector<Weight> potential;
      VectorFst<Arc> RI(T);
      VectorFst<Arc> RF(T);
      while (potential.size() < RI.NumStates())
        potential.push_back((*weight_generator_)());

      Reweight(&RI, potential, REWEIGHT_TO_INITIAL);
      CHECK(Equiv(T, RI));

      Reweight(&RF, potential, REWEIGHT_TO_FINAL);
      CHECK(Equiv(T, RF));
    }

    if ((wprops & kIdempotent) || (tprops & kAcyclic)) {
      VLOG(1) << "Check pushed FST is equivalent to input FST.";
      // Pushing towards the final state.
      if (wprops & kRightSemiring) {
        VectorFst<Arc> P1;
        Push<Arc, REWEIGHT_TO_FINAL>(T, &P1, kPushLabels);
        CHECK(Equiv(T, P1));

        VectorFst<Arc> P2;
        Push<Arc, REWEIGHT_TO_FINAL>(T, &P2, kPushWeights);
        CHECK(Equiv(T, P2));

        VectorFst<Arc> P3;
        Push<Arc, REWEIGHT_TO_FINAL>(T, &P3, kPushLabels | kPushWeights);
        CHECK(Equiv(T, P3));
      }

      // Pushing towards the initial state.
      if (wprops & kLeftSemiring) {
        VectorFst<Arc> P1;
        Push<Arc, REWEIGHT_TO_INITIAL>(T, &P1, kPushLabels);
        CHECK(Equiv(T, P1));

        VectorFst<Arc> P2;
        Push<Arc, REWEIGHT_TO_INITIAL>(T, &P2, kPushWeights);
        CHECK(Equiv(T, P2));
        VectorFst<Arc> P3;
        Push<Arc, REWEIGHT_TO_INITIAL>(T, &P3, kPushLabels | kPushWeights);
        CHECK(Equiv(T, P3));
      }
    }

    if ((wprops & (kPath | kCommutative)) == (kPath | kCommutative)) {
      VLOG(1) << "Check pruning algorithm";
      {
        VLOG(1) << "Check equiv. of constructive and destructive algorithms";
        Weight thresold = (*weight_generator_)();
        VectorFst<Arc> P1(T);
        Prune(&P1, thresold);
        VectorFst<Arc> P2;
        Prune(T, &P2, thresold);
        CHECK(Equiv(P1,P2));
      }

      {
        VLOG(1) << "Check prune(reverse) equiv reverse(prune)";
        Weight thresold = (*weight_generator_)();
        VectorFst< ReverseArc<Arc> > R;
        VectorFst<Arc> P1(T);
        VectorFst<Arc> P2;
        Prune(&P1, thresold);
        Reverse(T, &R);
        Prune(&R, thresold.Reverse());
        Reverse(R, &P2);
        CHECK(Equiv(P1, P2));
      }
      {
        VLOG(1) << "Check: ShortestDistance(T- prune(T))"
                << " > ShortestDistance(T) times Thresold";
        Weight thresold = (*weight_generator_)();
        VectorFst<Arc> P;
        Prune(A, &P, thresold);
        DifferenceFst<Arc> C(A, DeterminizeFst<Arc>
                             (RmEpsilonFst<Arc>
                              (ArcMapFst<Arc, Arc,
                               RmWeightMapper<Arc> >
                               (P, RmWeightMapper<Arc>()))));
        Weight sum1 = Times(ShortestDistance(A), thresold);
        Weight sum2 = ShortestDistance(C);
        CHECK(Plus(sum1, sum2) == sum1);
      }
    }
    if (tprops & kAcyclic) {
      VLOG(1) << "Check synchronize(T) equiv T";
      SynchronizeFst<Arc> S(T);
      CHECK(Equiv(T, S));
    }
  }

  // Tests search operations
  void TestSearch(const Fst<Arc> &T) {
    uint64 wprops = Weight::Properties();

    VectorFst<Arc> A(T);
    Project(&A, PROJECT_INPUT);

    if ((wprops & (kPath | kRightSemiring)) == (kPath | kRightSemiring)) {
      VLOG(1) << "Check 1-best weight.";
      VectorFst<Arc> path;
      ShortestPath(T, &path);
      Weight tsum = ShortestDistance(T);
      Weight psum = ShortestDistance(path);
      CHECK(ApproxEqual(tsum, psum, kTestDelta));
    }

    if ((wprops & (kPath | kSemiring)) == (kPath | kSemiring)) {
      VLOG(1) << "Check n-best weights";
      VectorFst<Arc> R(A);
      RmEpsilon(&R);
      int nshortest = rand() % kNumRandomShortestPaths + 2;
      VectorFst<Arc> paths;
      ShortestPath(R, &paths, nshortest, true, false,
                   Weight::Zero(), kNumShortestStates);
      vector<Weight> distance;
      ShortestDistance(paths, &distance, true);
      StateId pstart = paths.Start();
      if (pstart != kNoStateId) {
        ArcIterator< Fst<Arc> > piter(paths, pstart);
        for (; !piter.Done(); piter.Next()) {
          StateId s = piter.Value().nextstate;
          Weight nsum = s < distance.size() ?
              Times(piter.Value().weight, distance[s]) : Weight::Zero();
          VectorFst<Arc> path;
          ShortestPath(R, &path);
          Weight dsum = ShortestDistance(path);
          CHECK(ApproxEqual(nsum, dsum, kTestDelta));
          ArcMap(&path, RmWeightMapper<Arc>());
          VectorFst<Arc> S;
          Difference(R, path, &S);
          R = S;
        }
      }
    }
  }

  // Tests if two FSTS are equivalent by checking if random
  // strings from one FST are transduced the same by both FSTs.
  bool Equiv(const Fst<Arc> &fst1, const Fst<Arc> &fst2) {
    VLOG(1) << "Check FSTs for sanity (including property bits).";
    CHECK(Verify(fst1));
    CHECK(Verify(fst2));

    UniformArcSelector<Arc> uniform_selector(seed_);
    RandGenOptions< UniformArcSelector<Arc> >
        opts(uniform_selector, kRandomPathLength);
    return RandEquivalent(fst1, fst2, kNumRandomPaths, kTestDelta, opts);
  }

  // Random seed
  int seed_;

  // FST with no states
  VectorFst<Arc> zero_fst_;

  // FST with one state that accepts epsilon.
  VectorFst<Arc> one_fst_;

  // FST with one state that accepts all strings.
  VectorFst<Arc> univ_fst_;

  // Generates weights used in testing.
  WeightGenerator *weight_generator_;

  // Maximum random path length.
  static const int kRandomPathLength;

  // Number of random paths to explore.
  static const int kNumRandomPaths;

  // Maximum number of nshortest paths.
  static const int kNumRandomShortestPaths;

  // Maximum number of nshortest states.
  static const int kNumShortestStates;

  // Delta for equivalence tests.
  static const float kTestDelta;

  DISALLOW_COPY_AND_ASSIGN(WeightedTester);
};


template <class A, class WG>
const int WeightedTester<A, WG>::kRandomPathLength = 25;

template <class A, class WG>
const int WeightedTester<A, WG>::kNumRandomPaths = 100;

template <class A, class WG>
const int WeightedTester<A, WG>::kNumRandomShortestPaths = 100;

template <class A, class WG>
const int WeightedTester<A, WG>::kNumShortestStates = 10000;

template <class A, class WG>
const float WeightedTester<A, WG>::kTestDelta = .05;

// This class tests a variety of identities and properties that must
// hold for various algorithms on unweighted FSAs and that are not tested
// by WeightedTester. Only the specialization does anything interesting.
template <class Arc>
class UnweightedTester {
 public:
  UnweightedTester(const Fst<Arc> &zero_fsa, const Fst<Arc> &one_fsa,
                   const Fst<Arc> &univ_fsa) {}

  void Test(const Fst<Arc> &A1, const Fst<Arc> &A2, const Fst<Arc> &A3) {}
};


// Specialization for StdArc. This should work for any commutative,
// idempotent semiring when restricted to the unweighted case
// (being isomorphic to the boolean semiring).
template <>
class UnweightedTester<StdArc> {
 public:
  typedef StdArc Arc;
  typedef Arc::Label Label;
  typedef Arc::StateId StateId;
  typedef Arc::Weight Weight;

  UnweightedTester(const Fst<Arc> &zero_fsa, const Fst<Arc> &one_fsa,
                   const Fst<Arc> &univ_fsa)
      : zero_fsa_(zero_fsa), one_fsa_(one_fsa), univ_fsa_(univ_fsa) {}

  void Test(const Fst<Arc> &A1, const Fst<Arc> &A2, const Fst<Arc> &A3) {
    TestRational(A1, A2, A3);
    TestIntersect(A1, A2, A3);
    TestOptimize(A1);
  }

 private:
  // Tests rational operations with identities
  void TestRational(const Fst<Arc> &A1, const Fst<Arc> &A2,
                    const Fst<Arc> &A3) {

    {
      VLOG(1) << "Check the union contains its arguments (destructive).";
      VectorFst<Arc> U(A1);
      Union(&U, A2);

      CHECK(Subset(A1, U));
      CHECK(Subset(A2, U));
    }

    {
      VLOG(1) << "Check the union contains its arguments (delayed).";
      UnionFst<Arc> U(A1, A2);

      CHECK(Subset(A1, U));
      CHECK(Subset(A2, U));
    }

    {
      VLOG(1) << "Check if A^n c A* (destructive).";
      VectorFst<Arc> C(one_fsa_);
      int n = rand() % 5;
      for (int i = 0; i < n; ++i)
        Concat(&C, A1);

      VectorFst<Arc> S(A1);
      Closure(&S, CLOSURE_STAR);
      CHECK(Subset(C, S));
    }

    {
      VLOG(1) << "Check if A^n c A* (delayed).";
      int n = rand() % 5;
      Fst<Arc> *C = new VectorFst<Arc>(one_fsa_);
      for (int i = 0; i < n; ++i) {
        ConcatFst<Arc> *F = new ConcatFst<Arc>(*C, A1);
        delete C;
        C = F;
      }
      ClosureFst<Arc> S(A1, CLOSURE_STAR);
      CHECK(Subset(*C, S));
      delete C;
    }
  }

  // Tests intersect-based operations.
  void TestIntersect(const Fst<Arc> &A1, const Fst<Arc> &A2,
                   const Fst<Arc> &A3) {
    VectorFst<Arc> S1(A1);
    VectorFst<Arc> S2(A2);
    VectorFst<Arc> S3(A3);

    ILabelCompare<Arc> comp;

    ArcSort(&S1, comp);
    ArcSort(&S2, comp);
    ArcSort(&S3, comp);

    {
      VLOG(1) << "Check the intersection is contained in its arguments.";
      IntersectFst<Arc> I1(S1, S2);
      CHECK(Subset(I1, S1));
      CHECK(Subset(I1, S2));
    }

    {
      VLOG(1) << "Check union distributes over intersection.";
      IntersectFst<Arc> I1(S1, S2);
      UnionFst<Arc> U1(I1, S3);

      UnionFst<Arc> U2(S1, S3);
      UnionFst<Arc> U3(S2, S3);
      ArcSortFst< Arc, ILabelCompare<Arc> > S4(U3, comp);
      IntersectFst<Arc> I2(U2, S4);

      CHECK(Equiv(U1, I2));
    }

    VectorFst<Arc> C1;
    VectorFst<Arc> C2;
    Complement(S1, &C1);
    Complement(S2, &C2);
    ArcSort(&C1, comp);
    ArcSort(&C2, comp);


    {
      VLOG(1) << "Check S U S' = Sigma*";
      UnionFst<Arc> U(S1, C1);
      CHECK(Equiv(U, univ_fsa_));
    }

    {
      VLOG(1) << "Check S n S' = {}";
      IntersectFst<Arc> I(S1, C1);
      CHECK(Equiv(I, zero_fsa_));
    }

    {
      VLOG(1) << "Check (S1' U S2') == (S1 n S2)'";
      UnionFst<Arc> U(C1, C2);

      IntersectFst<Arc> I(S1, S2);
      VectorFst<Arc> C3;
      Complement(I, &C3);
      CHECK(Equiv(U, C3));
    }

    {
      VLOG(1) << "Check (S1' n S2') == (S1 U S2)'";
      IntersectFst<Arc> I(C1, C2);

      UnionFst<Arc> U(S1, S2);
      VectorFst<Arc> C3;
      Complement(U, &C3);
      CHECK(Equiv(I, C3));
    }
  }

  // Tests optimization operations
  void TestOptimize(const Fst<Arc> &A) {
    {
      VLOG(1) << "Check determinized FSA is equivalent to its input.";
      DeterminizeFst<Arc> D(A);
      CHECK(Equiv(A, D));
    }

    {
      VLOG(1) << "Check minimized FSA is equivalent to its input.";
      int n;
      {
        RmEpsilonFst<Arc> R(A);
        DeterminizeFst<Arc> D(R);
        VectorFst<Arc> M(D);
        Minimize(&M);
        CHECK(Equiv(A, M));
        n = M.NumStates();
      }

      if (n) {  // Skip test if A is the empty machine
        VLOG(1) << "Check that Hopcroft's and Revuz's algorithms lead to the"
                << " same number of states as Brozozowski's algorithm";
        VectorFst<Arc> R;
        Reverse(A, &R);
        RmEpsilon(&R);
        DeterminizeFst<Arc> DR(R);
        VectorFst<Arc> RD;
        Reverse(DR, &RD);
        DeterminizeFst<Arc> DRD(RD);
        VectorFst<Arc> M(DRD);
        CHECK_EQ(n + 1, M.NumStates());  // Accounts for the epsilon transition
                                         // to the initial state
      }
    }
  }

  // Tests if two FSAS are equivalent.
  bool Equiv(const Fst<Arc> &fsa1, const Fst<Arc> &fsa2) {
    VLOG(1) << "Check FSAs for sanity (including property bits).";
    CHECK(Verify(fsa1));
    CHECK(Verify(fsa2));

    VectorFst<Arc> vfsa1(fsa1);
    VectorFst<Arc> vfsa2(fsa2);
    RmEpsilon(&vfsa1);
    RmEpsilon(&vfsa2);
    DeterminizeFst<Arc> dfa1(vfsa1);
    DeterminizeFst<Arc> dfa2(vfsa2);

    // Test equivalence using union-find algorithm
    bool equiv1 = Equivalent(dfa1, dfa2);

    // Test equivalence by checking if (S1 - S2) U (S2 - S1) is empty
    ILabelCompare<Arc> comp;
    VectorFst<Arc> sdfa1(dfa1);
    ArcSort(&sdfa1, comp);
    VectorFst<Arc> sdfa2(dfa2);
    ArcSort(&sdfa2, comp);

    DifferenceFst<Arc> dfsa1(sdfa1, sdfa2);
    DifferenceFst<Arc> dfsa2(sdfa2, sdfa1);

    VectorFst<Arc> ufsa(dfsa1);
    Union(&ufsa, dfsa2);
    Connect(&ufsa);
    bool equiv2 = ufsa.NumStates() == 0;

    // Check two equivalence tests match
    CHECK((equiv1 && equiv2) || (!equiv1 && !equiv2));

    return equiv1;
  }

  // Tests if FSA1 is a subset of FSA2 (disregarding weights).
  bool Subset(const Fst<Arc> &fsa1, const Fst<Arc> &fsa2) {
    VLOG(1) << "Check FSAs (incl. property bits) for sanity";
    CHECK(Verify(fsa1));
    CHECK(Verify(fsa2));

    VectorFst<StdArc> vfsa1;
    VectorFst<StdArc> vfsa2;
    RmEpsilon(&vfsa1);
    RmEpsilon(&vfsa2);
    ILabelCompare<StdArc> comp;
    ArcSort(&vfsa1, comp);
    ArcSort(&vfsa2, comp);
    IntersectFst<StdArc> ifsa(vfsa1, vfsa2);
    DeterminizeFst<StdArc> dfa1(vfsa1);
    DeterminizeFst<StdArc> dfa2(ifsa);
    return Equivalent(dfa1, dfa2);
  }

  // Returns complement Fsa
  void Complement(const Fst<Arc> &ifsa, MutableFst<Arc> *ofsa) {
    RmEpsilonFst<Arc> rfsa(ifsa);
    DeterminizeFst<Arc> dfa(rfsa);
    DifferenceFst<Arc> cfsa(univ_fsa_, dfa);
    *ofsa = cfsa;
  }

  // FSA with no states
  VectorFst<Arc> zero_fsa_;

  // FSA with one state that accepts epsilon.
  VectorFst<Arc> one_fsa_;

  // FSA with one state that accepts all strings.
  VectorFst<Arc> univ_fsa_;

  DISALLOW_COPY_AND_ASSIGN(UnweightedTester);
};


// This class tests a variety of identities and properties that must
// hold for various FST algorithms. It randomly generates FSTs, using
// function object 'weight_generator' to select weights. 'WeightTester'
// and 'UnweightedTester' are then called.
template <class Arc, class WeightGenerator>
class AlgoTester {
 public:
  typedef typename Arc::Label Label;
  typedef typename Arc::StateId StateId;
  typedef typename Arc::Weight Weight;

  AlgoTester(WeightGenerator generator, int seed) :
      weight_generator_(generator), seed_(seed) {
      one_fst_.AddState();
      one_fst_.SetStart(0);
      one_fst_.SetFinal(0, Weight::One());

      univ_fst_.AddState();
      univ_fst_.SetStart(0);
      univ_fst_.SetFinal(0, Weight::One());
      for (int i = 0; i < kNumRandomLabels; ++i)
        univ_fst_.AddArc(0, Arc(i, i, Weight::One(), 0));
  }

  void Test() {
    VLOG(1) << "weight type = " << Weight::Type();

    for (int i = 0; i < FLAGS_repeat; ++i) {
      // Random transducers
      VectorFst<Arc> T1;
      VectorFst<Arc> T2;
      VectorFst<Arc> T3;
      RandFst(&T1);
      RandFst(&T2);
      RandFst(&T3);
      WeightedTester<Arc, WeightGenerator>
        weighted_tester(seed_, zero_fst_, one_fst_,
                        univ_fst_, &weight_generator_);
      weighted_tester.Test(T1, T2, T3);

      VectorFst<Arc> A1(T1);
      VectorFst<Arc> A2(T2);
      VectorFst<Arc> A3(T3);
      Project(&A1, PROJECT_OUTPUT);
      Project(&A2, PROJECT_INPUT);
      Project(&A3, PROJECT_INPUT);
      ArcMap(&A1, rm_weight_mapper);
      ArcMap(&A2, rm_weight_mapper);
      ArcMap(&A3, rm_weight_mapper);
      UnweightedTester<Arc> unweighted_tester(zero_fst_, one_fst_, univ_fst_);
      unweighted_tester.Test(A1, A2, A3);
    }
  }

 private:
  // Generates a random FST.
  void RandFst(MutableFst<Arc> *fst) {
    // Determines direction of the arcs wrt state numbering. This way we
    // can force acyclicity when desired.
    enum ArcDirection { ANY_DIRECTION = 0, FORWARD_DIRECTION = 1,
                        REVERSE_DIRECTION = 2, NUM_DIRECTIONS = 3 };

    ArcDirection arc_direction = ANY_DIRECTION;
    if (rand()/(RAND_MAX  + 1.0) < kAcyclicProb)
      arc_direction =  rand() % 2 ? FORWARD_DIRECTION : REVERSE_DIRECTION;

    fst->DeleteStates();
    StateId ns = rand() % kNumRandomStates;

    if (ns == 0)
      return;
    for (StateId s = 0; s < ns; ++s)
      fst->AddState();

    StateId start = rand() % ns;
    fst->SetStart(start);

    size_t na = rand() % kNumRandomArcs;
    for (size_t n = 0; n < na; ++n) {
      StateId s = rand() % ns;
      Arc arc;
      arc.ilabel = rand() % kNumRandomLabels;
      arc.olabel = rand() % kNumRandomLabels;
      arc.weight = weight_generator_();
      arc.nextstate = rand() % ns;

      if (arc_direction == ANY_DIRECTION ||
          (arc_direction == FORWARD_DIRECTION && arc.ilabel > arc.olabel) ||
          (arc_direction == REVERSE_DIRECTION && arc.ilabel < arc.olabel))
        fst->AddArc(s, arc);
    }

    StateId nf = rand() % (ns + 1);
    for (StateId n = 0; n < nf; ++n) {
      StateId s = rand() % ns;
      Weight final = weight_generator_();
      fst->SetFinal(s, final);
    }
    VLOG(1) << "Check FST for sanity (including property bits).";
    CHECK(Verify(*fst));

    // Get/compute all properties.
    uint64 props = fst->Properties(kFstProperties, true);

    // Select random set of properties to be unknown.
    uint64 mask = 0;
    for (int n = 0; n < 8; ++n) {
      mask |= rand() & 0xff;
      mask <<= 8;
    }
    mask &= ~kTrinaryProperties;
    fst->SetProperties(props & ~mask, mask);
  }

  // Generates weights used in testing.
  WeightGenerator weight_generator_;

  // Random seed
  int seed_;

  // FST with no states
  VectorFst<Arc> zero_fst_;

  // FST with one state that accepts epsilon.
  VectorFst<Arc> one_fst_;

  // FST with one state that accepts all strings.
  VectorFst<Arc> univ_fst_;

  // Mapper to remove weights from an Fst
  RmWeightMapper<Arc> rm_weight_mapper;

  // Maximum number of states in random test Fst.
  static const int kNumRandomStates;

  // Maximum number of arcs in random test Fst.
  static const int kNumRandomArcs;

  // Number of alternative random labels.
  static const int kNumRandomLabels;

  // Probability to force an acyclic Fst
  static const float kAcyclicProb;

  // Maximum random path length.
  static const int kRandomPathLength;

  // Number of random paths to explore.
  static const int kNumRandomPaths;

  DISALLOW_COPY_AND_ASSIGN(AlgoTester);
};

template <class A, class G> const int AlgoTester<A, G>::kNumRandomStates = 10;

template <class A, class G> const int AlgoTester<A, G>::kNumRandomArcs = 25;

template <class A, class G> const int AlgoTester<A, G>::kNumRandomLabels = 5;

template <class A, class G> const float AlgoTester<A, G>::kAcyclicProb = .25;

template <class A, class G> const int AlgoTester<A, G>::kRandomPathLength = 25;

template <class A, class G> const int AlgoTester<A, G>::kNumRandomPaths = 100;

}  // namespace fst

#endif  // FST_TEST_ALGO_TEST_H__
