1f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// test-properties.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// Functions to manipulate and test property bits 20f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 21f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#ifndef FST_LIB_TEST_PROPERTIES_H__ 22f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#define FST_LIB_TEST_PROPERTIES_H__ 23f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 243da1eb108d36da35333b2d655202791af854996bPrzemyslaw Szczepaniak#include <tr1/unordered_set> 25f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_set; 26f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonusing std::tr1::unordered_multiset; 27f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 28f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/dfs-visit.h> 29f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#include <fst/connect.h> 30f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 31f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 32f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian HodsonDECLARE_bool(fst_verify_properties); 33f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 34f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonnamespace fst { 35f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 36f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// For a binary property, the bit is always returned set. 37f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// For a trinary (i.e. two-bit) property, both bits are 38f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// returned set iff either corresponding input bit is set. 39f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline uint64 KnownProperties(uint64 props) { 40f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return kBinaryProperties | (props & kTrinaryProperties) | 41f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ((props & kPosTrinaryProperties) << 1) | 42f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ((props & kNegTrinaryProperties) >> 1); 43f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 44f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 45f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Tests compatibility between two sets of properties 46f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsoninline bool CompatProperties(uint64 props1, uint64 props2) { 47f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 known_props1 = KnownProperties(props1); 48f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 known_props2 = KnownProperties(props2); 49f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 known_props = known_props1 & known_props2; 50f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 incompat_props = (props1 & known_props) ^ (props2 & known_props); 51f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (incompat_props) { 52f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 prop = 1; 53f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson for (int i = 0; i < 64; ++i, prop <<= 1) 54f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (prop & incompat_props) 55f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LOG(ERROR) << "CompatProperties: mismatch: " << PropertyNames[i] 56f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson << ": props1 = " << (props1 & prop ? "true" : "false") 57f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson << ", props2 = " << (props2 & prop ? "true" : "false"); 58f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return false; 59f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 60f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return true; 61f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 62f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 63f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 64f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// Computes FST property values defined in properties.h. The value of 65f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// each property indicated in the mask will be determined and returned 66f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// (these will never be unknown here). In the course of determining 67f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// the properties specifically requested in the mask, certain other 68f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// properties may be determined (those with little additional expense) 69f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// and their values will be returned as well. The complete set of 70f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// known properties (whether true or false) determined by this 71f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// operation will be assigned to the the value pointed to by KNOWN. 72f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// If 'use_stored' is true, pre-computed FST properties may be used 73f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// when possible. This routine is seldom called directly; instead it 74f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// is used to implement fst.Properties(mask, true). 75f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class Arc> 76f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonuint64 ComputeProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known, 77f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson bool use_stored) { 78f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Label Label; 79f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::Weight Weight; 80f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson typedef typename Arc::StateId StateId; 81f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 82f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 fst_props = fst.Properties(kFstProperties, false); // Fst-stored 83f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 84f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Check stored FST properties first if allowed. 85f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (use_stored) { 86f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 known_props = KnownProperties(fst_props); 87f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // If FST contains required info, return it. 88f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if ((known_props & mask) == mask) { 89f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson *known = known_props; 90f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return fst_props; 91f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 92f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 93f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 94f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Compute (trinary) properties explicitly. 95f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 96f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Initialize with binary properties (already known). 97f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 comp_props = fst_props & kBinaryProperties; 98f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 99f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Compute these trinary properties with a DFS. We compute only those 100f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // that need a DFS here, since we otherwise would like to avoid a DFS 101f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // since its stack could grow large. 102f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 dfs_props = kCyclic | kAcyclic | kInitialCyclic | kInitialAcyclic | 103f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kAccessible | kNotAccessible | 104f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kCoAccessible | kNotCoAccessible; 105f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (mask & dfs_props) { 106f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson SccVisitor<Arc> scc_visitor(&comp_props); 107f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson DfsVisit(fst, &scc_visitor); 108f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 109f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 110f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Compute any remaining trinary properties via a state and arcs iterations 111f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (mask & ~(kBinaryProperties | dfs_props)) { 112f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kAcceptor | kNoEpsilons | kNoIEpsilons | kNoOEpsilons | 113f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson kILabelSorted | kOLabelSorted | kUnweighted | kTopSorted | kString; 114f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (mask & (kIDeterministic | kNonIDeterministic)) 115f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kIDeterministic; 116f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (mask & (kODeterministic | kNonODeterministic)) 117f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kODeterministic; 118f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 119f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson unordered_set<Label> *ilabels = 0; 120f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson unordered_set<Label> *olabels = 0; 121f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 122f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson StateId nfinal = 0; 123f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson for (StateIterator< Fst<Arc> > siter(fst); 124f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson !siter.Done(); 125f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson siter.Next()) { 126f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson StateId s = siter.Value(); 127f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 128dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin Arc prev_arc; 129f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson // Create these only if we need to 130f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (mask & (kIDeterministic | kNonIDeterministic)) 131f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ilabels = new unordered_set<Label>; 132f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (mask & (kODeterministic | kNonODeterministic)) 133f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson olabels = new unordered_set<Label>; 134f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 135dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin bool first_arc = true; 136f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson for (ArcIterator< Fst<Arc> > aiter(fst, s); 137f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson !aiter.Done(); 138f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson aiter.Next()) { 139f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson const Arc &arc =aiter.Value(); 140f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 141f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (ilabels && ilabels->find(arc.ilabel) != ilabels->end()) { 142f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kNonIDeterministic; 143f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kIDeterministic; 144f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 145f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (olabels && olabels->find(arc.olabel) != olabels->end()) { 146f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kNonODeterministic; 147f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kODeterministic; 148f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 149f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (arc.ilabel != arc.olabel) { 150f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kNotAcceptor; 151f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kAcceptor; 152f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 153f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (arc.ilabel == 0 && arc.olabel == 0) { 154f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kEpsilons; 155f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kNoEpsilons; 156f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 157f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (arc.ilabel == 0) { 158f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kIEpsilons; 159f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kNoIEpsilons; 160f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 161f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (arc.olabel == 0) { 162f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kOEpsilons; 163f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kNoOEpsilons; 164f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 165dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (!first_arc) { 166dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (arc.ilabel < prev_arc.ilabel) { 167dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin comp_props |= kNotILabelSorted; 168dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin comp_props &= ~kILabelSorted; 169dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 170dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin if (arc.olabel < prev_arc.olabel) { 171dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin comp_props |= kNotOLabelSorted; 172dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin comp_props &= ~kOLabelSorted; 173dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin } 174f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 175f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (arc.weight != Weight::One() && arc.weight != Weight::Zero()) { 176f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kWeighted; 177f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kUnweighted; 178f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 179f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (arc.nextstate <= s) { 180f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kNotTopSorted; 181f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kTopSorted; 182f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 183f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (arc.nextstate != s + 1) { 184f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kNotString; 185f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kString; 186f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 187f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson prev_arc = arc; 188dfd8b8327b93660601d016cdc6f29f433b45a8d8Alexander Gutkin first_arc = false; 189f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (ilabels) 190f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ilabels->insert(arc.ilabel); 191f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (olabels) 192f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson olabels->insert(arc.olabel); 193f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 194f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 195f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (nfinal > 0) { // final state not last 196f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kNotString; 197f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kString; 198f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 199f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 200f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson Weight final = fst.Final(s); 201f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 202f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (final != Weight::Zero()) { // final state 203f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (final != Weight::One()) { 204f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kWeighted; 205f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kUnweighted; 206f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 207f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson ++nfinal; 208f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { // non-final state 209f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (fst.NumArcs(s) != 1) { 210f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kNotString; 211f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kString; 212f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 213f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 214f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 215f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete ilabels; 216f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson delete olabels; 217f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 218f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 219f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (fst.Start() != kNoStateId && fst.Start() != 0) { 220f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props |= kNotString; 221f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson comp_props &= ~kString; 222f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 223f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 224f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 225f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson *known = KnownProperties(comp_props); 226f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return comp_props; 227f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 228f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 229f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// This is a wrapper around ComputeProperties that will cause a fatal 230f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// error if the stored properties and the computed properties are 231f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// incompatible when 'FLAGS_fst_verify_properties' is true. This 232f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// routine is seldom called directly; instead it is used to implement 233f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson// fst.Properties(mask, true). 234f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsontemplate<class Arc> 235f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodsonuint64 TestProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known) { 236f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (FLAGS_fst_verify_properties) { 237f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 stored_props = fst.Properties(kFstProperties, false); 238f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson uint64 computed_props = ComputeProperties(fst, mask, known, false); 239f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson if (!CompatProperties(stored_props, computed_props)) 240f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson LOG(FATAL) << "TestProperties: stored Fst properties incorrect" 241f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson << " (stored: props1, computed: props2)"; 242f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return computed_props; 243f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } else { 244f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson return ComputeProperties(fst, mask, known, true); 245f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson } 246f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} 247f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 248f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson} // namespace fst 249f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson 250f4c12fce1ee58e670f9c3fce46c40296ba9ee8a2Ian Hodson#endif // FST_LIB_TEST_PROPERTIES_H__ 251