// test-properties.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 // Functions to manipulate and test property bits #ifndef FST_LIB_TEST_PROPERTIES_H__ #define FST_LIB_TEST_PROPERTIES_H__ #include using std::tr1::unordered_set; using std::tr1::unordered_multiset; #include #include DECLARE_bool(fst_verify_properties); namespace fst { // For a binary property, the bit is always returned set. // For a trinary (i.e. two-bit) property, both bits are // returned set iff either corresponding input bit is set. inline uint64 KnownProperties(uint64 props) { return kBinaryProperties | (props & kTrinaryProperties) | ((props & kPosTrinaryProperties) << 1) | ((props & kNegTrinaryProperties) >> 1); } // Tests compatibility between two sets of properties inline bool CompatProperties(uint64 props1, uint64 props2) { uint64 known_props1 = KnownProperties(props1); uint64 known_props2 = KnownProperties(props2); uint64 known_props = known_props1 & known_props2; uint64 incompat_props = (props1 & known_props) ^ (props2 & known_props); if (incompat_props) { uint64 prop = 1; for (int i = 0; i < 64; ++i, prop <<= 1) if (prop & incompat_props) LOG(ERROR) << "CompatProperties: mismatch: " << PropertyNames[i] << ": props1 = " << (props1 & prop ? "true" : "false") << ", props2 = " << (props2 & prop ? "true" : "false"); return false; } else { return true; } } // Computes FST property values defined in properties.h. The value of // each property indicated in the mask will be determined and returned // (these will never be unknown here). In the course of determining // the properties specifically requested in the mask, certain other // properties may be determined (those with little additional expense) // and their values will be returned as well. The complete set of // known properties (whether true or false) determined by this // operation will be assigned to the the value pointed to by KNOWN. // If 'use_stored' is true, pre-computed FST properties may be used // when possible. This routine is seldom called directly; instead it // is used to implement fst.Properties(mask, true). template uint64 ComputeProperties(const Fst &fst, uint64 mask, uint64 *known, bool use_stored) { typedef typename Arc::Label Label; typedef typename Arc::Weight Weight; typedef typename Arc::StateId StateId; uint64 fst_props = fst.Properties(kFstProperties, false); // Fst-stored // Check stored FST properties first if allowed. if (use_stored) { uint64 known_props = KnownProperties(fst_props); // If FST contains required info, return it. if ((known_props & mask) == mask) { *known = known_props; return fst_props; } } // Compute (trinary) properties explicitly. // Initialize with binary properties (already known). uint64 comp_props = fst_props & kBinaryProperties; // Compute these trinary properties with a DFS. We compute only those // that need a DFS here, since we otherwise would like to avoid a DFS // since its stack could grow large. uint64 dfs_props = kCyclic | kAcyclic | kInitialCyclic | kInitialAcyclic | kAccessible | kNotAccessible | kCoAccessible | kNotCoAccessible; if (mask & dfs_props) { SccVisitor scc_visitor(&comp_props); DfsVisit(fst, &scc_visitor); } // Compute any remaining trinary properties via a state and arcs iterations if (mask & ~(kBinaryProperties | dfs_props)) { comp_props |= kAcceptor | kNoEpsilons | kNoIEpsilons | kNoOEpsilons | kILabelSorted | kOLabelSorted | kUnweighted | kTopSorted | kString; if (mask & (kIDeterministic | kNonIDeterministic)) comp_props |= kIDeterministic; if (mask & (kODeterministic | kNonODeterministic)) comp_props |= kODeterministic; unordered_set