14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// test-properties.h 24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Licensed under the Apache License, Version 2.0 (the "License"); 44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// you may not use this file except in compliance with the License. 54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// You may obtain a copy of the License at 64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// http://www.apache.org/licenses/LICENSE-2.0 84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Unless required by applicable law or agreed to in writing, software 104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// distributed under the License is distributed on an "AS IS" BASIS, 114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// See the License for the specific language governing permissions and 134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// limitations under the License. 144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// 164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// \file 174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Functions to manipulate and test property bits 184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#ifndef FST_LIB_TEST_PROPERTIES_H__ 204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#define FST_LIB_TEST_PROPERTIES_H__ 214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include <ext/hash_set> 234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectusing __gnu_cxx::hash_set; 244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/connect.h" 274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/dfs-visit.h" 284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "fst/lib/mutable-fst.h" 294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectDECLARE_bool(fst_verify_properties); 314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectnamespace fst { 334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// For a binary property, the bit is always returned set. 354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// For a trinary (i.e. two-bit) property, both bits are 364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// returned set iff either corresponding input bit is set. 374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline uint64 KnownProperties(uint64 props) { 384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return kBinaryProperties | props & kTrinaryProperties | 394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project (props & kPosTrinaryProperties) << 1 | 404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project (props & kNegTrinaryProperties) >> 1; 414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Tests compatibility between two sets of properties 444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectinline bool CompatProperties(uint64 props1, uint64 props2) { 454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 known_props1 = KnownProperties(props1); 464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 known_props2 = KnownProperties(props2); 474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 known_props = known_props1 & known_props2; 484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 incompat_props = (props1 & known_props) ^ (props2 & known_props); 494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (incompat_props) { 504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 prop = 1; 514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (int i = 0; i < 64; ++i, prop <<= 1) 524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (prop & incompat_props) 534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(ERROR) << "CompatProperties: mismatch: " << PropertyNames[i] 544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << ": props1 = " << (props1 & prop ? "true" : "false") 554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << ", props2 = " << (props2 & prop ? "true" : "false"); 564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return false; 574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return true; 594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// Computes FST property values defined in properties.h. The value of 634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// each property indicated in the mask will be determined and returned 644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// (these will never be unknown here). In the course of determining 654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// the properties specifically requested in the mask, certain other 664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// properties may be determined (those with little additional expense) 674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// and their values will be returned as well. The complete set of 684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// known properties (whether true or false) determined by this 694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// operation will be assigned to the the value pointed to by KNOWN. 704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// If 'use_stored' is true, pre-computed FST properties may be used 714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// when possible. This routine is seldom called directly; instead it 724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// is used to implement fst.Properties(mask, true). 734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class Arc> 744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectuint64 ComputeProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known, 754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project bool use_stored) { 764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project typedef typename Arc::Label Label; 774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project typedef typename Arc::Weight Weight; 784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project typedef typename Arc::StateId StateId; 794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 fst_props = fst.Properties(kFstProperties, false); // Fst-stored 814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Check stored FST properties first if allowed. 834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (use_stored) { 844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 known_props = KnownProperties(fst_props); 854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // If FST contains required info, return it. 864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if ((known_props & mask) == mask) { 874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *known = known_props; 884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return fst_props; 894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Compute (trinary) properties explicitly. 934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Initialize with binary properties (already known). 954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 comp_props = fst_props & kBinaryProperties; 964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Compute these trinary properties with a DFS. We compute only those 984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // that need a DFS here, since we otherwise would like to avoid a DFS 994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // since its stack could grow large. 1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 dfs_props = kCyclic | kAcyclic | kInitialCyclic | kInitialAcyclic | 1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kAccessible | kNotAccessible | 1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kCoAccessible | kNotCoAccessible; 1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (mask & dfs_props) { 1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project SccVisitor<Arc> scc_visitor(&comp_props); 1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project DfsVisit(fst, &scc_visitor); 1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Compute any remaining trinary properties via a state and arcs iterations 1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (mask & ~(kBinaryProperties | dfs_props)) { 1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kAcceptor | kNoEpsilons | kNoIEpsilons | kNoOEpsilons | 1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project kILabelSorted | kOLabelSorted | kUnweighted | kTopSorted | kString; 1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (mask & (kIDeterministic | kNonIDeterministic)) 1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kIDeterministic; 1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (mask & (kODeterministic | kNonODeterministic)) 1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kODeterministic; 1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project hash_set<Label> *ilabels = 0; 1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project hash_set<Label> *olabels = 0; 1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project StateId nfinal = 0; 1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (StateIterator< Fst<Arc> > siter(fst); 1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !siter.Done(); 1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project siter.Next()) { 1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project StateId s = siter.Value(); 1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Arc prev_arc(kNoLabel, kNoLabel, Weight::One(), 0); 1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project // Create these only if we need to 1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (mask & (kIDeterministic | kNonIDeterministic)) 1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ilabels = new hash_set<Label>; 1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (mask & (kODeterministic | kNonODeterministic)) 1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project olabels = new hash_set<Label>; 1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project for (ArcIterator< Fst<Arc> > aiter(fst, s); 1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project !aiter.Done(); 1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project aiter.Next()) { 1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project const Arc &arc =aiter.Value(); 1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (ilabels && ilabels->find(arc.ilabel) != ilabels->end()) { 1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kNonIDeterministic; 1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kIDeterministic; 1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (olabels && olabels->find(arc.olabel) != olabels->end()) { 1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kNonODeterministic; 1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kODeterministic; 1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (arc.ilabel != arc.olabel) { 1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kNotAcceptor; 1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kAcceptor; 1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (arc.ilabel == 0 && arc.olabel == 0) { 1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kEpsilons; 1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kNoEpsilons; 1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (arc.ilabel == 0) { 1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kIEpsilons; 1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kNoIEpsilons; 1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (arc.olabel == 0) { 1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kOEpsilons; 1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kNoOEpsilons; 1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (prev_arc.ilabel != kNoLabel && arc.ilabel < prev_arc.ilabel) { 1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kNotILabelSorted; 1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kILabelSorted; 1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (prev_arc.olabel != kNoLabel && arc.olabel < prev_arc.olabel) { 1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kNotOLabelSorted; 1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kOLabelSorted; 1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (arc.weight != Weight::One() && arc.weight != Weight::Zero()) { 1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kWeighted; 1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kUnweighted; 1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (arc.nextstate <= s) { 1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kNotTopSorted; 1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kTopSorted; 1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (arc.nextstate != s + 1) { 1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kNotString; 1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kString; 1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project prev_arc = arc; 1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (ilabels) 1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ilabels->insert(arc.ilabel); 1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (olabels) 1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project olabels->insert(arc.olabel); 1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (nfinal > 0) { // final state not last 1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kNotString; 1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kString; 1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project Weight final = fst.Final(s); 1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (final != Weight::Zero()) { // final state 1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (final != Weight::One()) { 1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kWeighted; 1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kUnweighted; 2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project ++nfinal; 2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { // non-final state 2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fst.NumArcs(s) != 1) { 2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kNotString; 2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kString; 2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete ilabels; 2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project delete olabels; 2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (fst.Start() != kNoStateId && fst.Start() != 0) { 2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props |= kNotString; 2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project comp_props &= ~kString; 2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *known = KnownProperties(comp_props); 2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return comp_props; 2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// This is a wrapper around ComputeProperties that will cause a fatal 2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// error if the stored properties and the computed properties are 2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// incompatible when 'FLAGS_fst_verify_properties' is true. This 2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// routine is seldom called directly; instead it is used to implement 2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project// fst.Properties(mask, true). 2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projecttemplate<class Arc> 2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectuint64 TestProperties(const Fst<Arc> &fst, uint64 mask, uint64 *known) { 2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (FLAGS_fst_verify_properties) { 2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 stored_props = fst.Properties(kFstProperties, false); 2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project uint64 computed_props = ComputeProperties(fst, mask, known, false); 2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project if (!CompatProperties(stored_props, computed_props)) 2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project LOG(FATAL) << "TestProperties: stored Fst properties incorrect" 2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project << " (stored: props1, computed: props2)"; 2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return computed_props; 2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } else { 2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project return ComputeProperties(fst, mask, known, true); 2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project } 2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} 2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project} // namespace fst 2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project 2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#endif // FST_LIB_TEST_PROPERTIES_H__ 245