// fstext/determinize-star-test.cc // Copyright 2009-2011 Microsoft Corporation // 2015 Hainan Xu // See ../../COPYING for clarification regarding multiple authors // // 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 // // THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED // WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, // MERCHANTABLITY OR NON-INFRINGEMENT. // See the Apache 2 License for the specific language governing permissions and // limitations under the License. #include "base/kaldi-math.h" #include "fstext/pre-determinize.h" #include "fstext/determinize-star.h" #include "fstext/trivial-factor-weight.h" #include "fstext/fst-test-utils.h" namespace fst { // test that determinization proceeds correctly on general // FSTs (not guaranteed determinzable, but we use the // max-states option to stop it getting out of control). template void TestDeterminizeGeneral() { int max_states = 100; // don't allow more det-states than this. for(int i = 0; i < 100; i++) { VectorFst *fst = RandFst(); std::cout << "FST before determinizing is:\n"; { FstPrinter fstprinter(*fst, NULL, NULL, NULL, false, true, "\t"); fstprinter.Print(&std::cout, "standard output"); } VectorFst ofst; try { DeterminizeStar >(*fst, &ofst, kDelta, NULL, max_states); std::cout << "FST after determinizing is:\n"; { FstPrinter fstprinter(ofst, NULL, NULL, NULL, false, true, "\t"); fstprinter.Print(&std::cout, "standard output"); } assert(RandEquivalent(*fst, ofst, 5/*paths*/, 0.01/*delta*/, kaldi::Rand()/*seed*/, 100/*path length, max*/)); } catch (...) { std::cout << "Failed to determinize *this FST (probably not determinizable)\n"; } delete fst; } } // Don't instantiate with log semiring, as RandEquivalent may fail. template void TestDeterminize() { typedef typename Arc::Label Label; typedef typename Arc::StateId StateId; typedef typename Arc::Weight Weight; VectorFst *fst = new VectorFst(); int n_syms = 2 + kaldi::Rand() % 5, n_states = 3 + kaldi::Rand() % 10, n_arcs = 5 + kaldi::Rand() % 30, n_final = 1 + kaldi::Rand()%3; // Up to 2 unique symbols. cout << "Testing pre-determinize with "< all_syms; // including epsilon. // Put symbols in the symbol table from 1..n_syms-1. for (size_t i = 0;i < (size_t)n_syms;i++) all_syms.push_back(i); // Create states. vector all_states; for (size_t i = 0;i < (size_t)n_states;i++) { StateId this_state = fst->AddState(); if (i == 0) fst->SetStart(i); all_states.push_back(this_state); } // Set final states. for (size_t j = 0;j < (size_t)n_final;j++) { StateId id = all_states[kaldi::Rand() % n_states]; Weight weight = (Weight)(0.33*(kaldi::Rand() % 5) ); printf("calling SetFinal with %d and %f\n", id, weight.Value()); fst->SetFinal(id, weight); } // Create arcs. for (size_t i = 0;i < (size_t)n_arcs;i++) { Arc a; a.nextstate = all_states[kaldi::Rand() % n_states]; a.ilabel = all_syms[kaldi::Rand() % n_syms]; a.olabel = all_syms[kaldi::Rand() % n_syms]; // same input+output vocab. a.weight = (Weight) (0.33*(kaldi::Rand() % 2)); StateId start_state = all_states[kaldi::Rand() % n_states]; fst->AddArc(start_state, a); } std::cout <<" printing before trimming\n"; { FstPrinter fstprinter(*fst, sptr, sptr, NULL, false, true, "\t"); fstprinter.Print(&std::cout, "standard output"); } // Trim resulting FST. Connect(fst); std::cout <<" printing after trimming\n"; { FstPrinter fstprinter(*fst, sptr, sptr, NULL, false, true, "\t"); fstprinter.Print(&std::cout, "standard output"); } VectorFst *fst_copy_orig = new VectorFst(*fst); vector