| #ifndef UIMA_LOWLEVEL_TYPESYSTEM_HPP |
| #define UIMA_LOWLEVEL_TYPESYSTEM_HPP |
| /** \file lowlevel_typesystem.hpp . |
| ----------------------------------------------------------------------------- |
| |
| |
| |
| |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| |
| ----------------------------------------------------------------------------- |
| |
| Description: |
| |
| ----------------------------------------------------------------------------- |
| |
| |
| -------------------------------------------------------------------------- */ |
| |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Include dependencies */ |
| /* ----------------------------------------------------------------------- */ |
| #include "uima/pragmas.hpp" |
| |
| #include <vector> |
| #include <map> |
| |
| #include "uima/lowlevel_typedefs.hpp" |
| |
| #include "uima/internal_typeshortcuts.hpp" |
| #include "uima/casexception.hpp" |
| #include "uima/typesystem.hpp" |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Constants */ |
| /* ----------------------------------------------------------------------- */ |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Forward declarations */ |
| /* ----------------------------------------------------------------------- */ |
| namespace uima { |
| namespace internal { |
| class CASDefinition; |
| class CASDeserializer; |
| } |
| } |
| /* ----------------------------------------------------------------------- */ |
| /* Types / Classes */ |
| /* ----------------------------------------------------------------------- */ |
| |
| namespace uima { |
| namespace lowlevel { |
| |
| UIMA_EXC_CLASSDECLARE(FeatureIntroductionFailedException, CASException); |
| UIMA_EXC_CLASSDECLARE(TypeCreationFailedException, CASException); |
| |
| /** |
| * The lowlevel type system. |
| * Inherits from the type system of the OO API. |
| */ |
| class UIMA_LINK_IMPORTSPEC TypeSystem : public uima::TypeSystem { |
| friend class uima::internal::CASDefinition; |
| friend class uima::internal::CASDeserializer; |
| protected: |
| bool iv_bIsCommitted; |
| bool iv_bBuiltinTypesCreated; |
| |
| TyFSType iv_tyTop; |
| |
| // for building the hierarchy |
| |
| // tree[t] are the daughters of type t |
| |
| std::vector<std::vector<TyFSType> > iv_vecTree; |
| // introducedFeatures[t] are the features introduced at type t |
| std::vector<std::vector<TyFSFeature> > iv_vecIntroducedFeatures; |
| // useful map to parents of type t |
| std::vector<TyFSType> iv_vecParents; |
| |
| // iv_vecRangeTypes[f] is the range type for feature f |
| std::vector<TyFSType> iv_vecRangeTypes; |
| // iv_vecMultiRefs[f] is the multipleReferencesAllowed property for feature f |
| std::vector<bool> iv_vecMultiRefs; |
| |
| // names of types and features |
| std::vector<icu::UnicodeString> iv_vecTypeNames; |
| std::vector<icu::UnicodeString> iv_vecTypeCreatorIDs; |
| std::vector<icu::UnicodeString> iv_vecFeatureBaseNames; |
| std::vector<icu::UnicodeString> iv_vecFeatureCreatorIDs; |
| |
| // string sub types |
| std::vector<std::vector<icu::UnicodeString> > iv_enumStrings; |
| std::map<TyFSType, TyFeatureOffset> iv_stringSubtypeToStringSet; |
| |
| // list of priority pairs |
| std::vector< std::pair<TyFSType, TyFSType> > iv_typePriorityList; |
| |
| // the next fields are computed during commit() |
| |
| // featureNumber[t] is the number of features of type t |
| std::vector<TyFeatureOffset> iv_vecFeatureNumber; |
| |
| // featureOffset[f] is the offset of feature f |
| std::vector< TyFeatureOffset > iv_vecFeatureOffset; |
| |
| // iv_vecTypeFeatureOffsetMapping[t][o] is the feature appropriate |
| // for type t with offset o |
| std::vector< std::vector<TyFSFeature> > iv_vecTypeFeatureOffsetMapping; |
| |
| // approp[t][f] is true if feature f is appropriate for type t |
| std::vector< std::vector< bool > > iv_vecApprop; |
| |
| // the total order embedding the user defined type priorities |
| std::map<TyFSType, size_t> iv_mapTypePriority; |
| // use to avoid calling expensive routine if no custom priorities defined |
| bool iv_customTypePrioritySet; |
| |
| // find typeToBeFound in the subtree of the hierarchy rooted at root |
| bool findInTree(TyFSType root, TyFSType typeToBeFound) const; |
| |
| /** |
| * compute appropriateness conditions on t, in particular, |
| * compute which feature is defined on each type, i.e., introduced |
| * of an ancestor type |
| */ |
| void computeApprop(TyFSType t); |
| |
| /** |
| * compute the mapping from types and offsets to features. |
| */ |
| void computeTypeFeatureOffsetMapping(); |
| |
| /** |
| * assign a type priority number to all types. |
| */ |
| void computeTypePriorityClosure(); |
| |
| /** |
| * combine the type priorities explictly defined by the configuration |
| * with the the ones of the sibling order (special Talent requirement). |
| */ |
| void combineUserDefinedPrioritiesWithSiblingPriority(); |
| |
| TypeSystem(TypeSystem const &); |
| TypeSystem & operator=(TypeSystem const &); |
| |
| TypeSystem(); |
| ~TypeSystem(); |
| |
| |
| /** |
| * check if <code>tyType</code> is a builtin type |
| * (int, string, float). |
| */ |
| bool isBuiltinType(TyFSType tyType) const { |
| assert( isValidType(tyType) ); |
| return ( tyType == uima::internal::gs_tyIntegerType ) |
| || ( tyType == uima::internal::gs_tyFloatType ) |
| || ( tyType == uima::internal::gs_tyStringType ); |
| } |
| |
| void createPredefinedCASTypes(); |
| |
| TyFSType createTypeNoChecks(TyFSType tyParent, icu::UnicodeString const & crName, icu::UnicodeString const & crusCreatorID); |
| |
| protected: |
| virtual uima::lowlevel::TypeSystem const & getLowlevelTypeSystem() const { |
| return *this; |
| } |
| public: |
| static uima::lowlevel::TypeSystem const & promoteTypeSystem(uima::TypeSystem const & typeSystem) { |
| return typeSystem.getLowlevelTypeSystem(); |
| } |
| |
| static uima::lowlevel::TypeSystem & promoteTypeSystem(uima::TypeSystem & typeSystem) { |
| return CONST_CAST(uima::lowlevel::TypeSystem&, typeSystem.getLowlevelTypeSystem() ); |
| } |
| |
| typedef struct { |
| char const * iv_cpszName; |
| char const * iv_cpszParentName; |
| char const * iv_cpszDescription; |
| } |
| StTypeInfo; |
| |
| typedef struct { |
| char const * iv_cpszName; |
| char const * iv_cpszIntroTypeName; |
| char const * iv_cpszRangeTypeName; |
| bool const iv_multipleRefsAllowed; |
| char const * iv_cpszDescription; |
| } |
| StFeatureInfo; |
| |
| |
| static const TyFSType INVALID_TYPE; |
| static const TyFSFeature INVALID_FEATURE; |
| |
| /* |
| // names of types and features |
| static UIMA_LINK_IMPORTSPEC char const * TYPENAME_INVALID; |
| static UIMA_LINK_IMPORTSPEC char const * TYPENAME_TOP; |
| |
| static UIMA_LINK_IMPORTSPEC char const * FEATURENAME_INVALID; |
| */ |
| |
| #ifndef NDEBUG |
| bool debugIsTreeConsistent() const; |
| void printTree(int, TyFSType, std::ostream&) const; |
| #endif |
| // These two are used in test_cas when built debug |
| void print(std::ostream&) const; |
| bool debugIsConsistent() const; |
| |
| /** |
| * call commit() after you added the complete type hierarchy. It compiles |
| * out several tables for faster lookup. |
| */ |
| void commit(); |
| |
| /** |
| * @return true if the type system was already committed. |
| */ |
| bool isCommitted() const { |
| return iv_bIsCommitted; |
| } |
| |
| /** |
| * resets the type system, all types and features will be deleted. |
| * Advanced use only. |
| */ |
| void reset(); |
| |
| /*@{*/ |
| /** |
| * @name Building the Type Hierarchy |
| */ |
| |
| /** |
| * create a type as a subtype of <code>tyParent</code> with |
| * name <code>crName</code>. |
| */ |
| TyFSType createType(TyFSType tyParent, icu::UnicodeString const & crName, icu::UnicodeString const & crusCreatorID); |
| |
| TyFSType createStringSubtype(icu::UnicodeString const & crName, std::vector<icu::UnicodeString> const & crStrings, icu::UnicodeString const & crusCreatorID); |
| |
| /** |
| * create a feature on <code>tyIntro</code> with value type <code>tyValueType</code> |
| * and name <code>crName</code>. |
| */ |
| TyFSFeature createFeature(TyFSType tyIntro, TyFSType tyValueType, bool multiRef, icu::UnicodeString const & crName, icu::UnicodeString const & crusCreatorID); |
| |
| /** |
| * create a type from a type info struct. |
| */ |
| TyFSType createType( StTypeInfo const & , icu::UnicodeString const & crusCreatorID); |
| |
| /** |
| * create a feature from a feature info struct. |
| */ |
| TyFSType createFeature( StFeatureInfo const & , icu::UnicodeString const & crusCreatorID); |
| |
| /** |
| * Add a type priority between t1 and t2. Returns true if the pair |
| * does not lead to a contradiction, false otherwise. |
| */ |
| bool addTypePriority(TyFSType t1, TyFSType t2); |
| |
| /** |
| * get the number of the type in an absolute ordering embedding the specified |
| * type priorities, i.e., |
| * hasPriorityOver(t1, t2) iff getTypePriorityNumber[t1] < getTypePriorityNumber[t2] |
| */ |
| size_t getTypePriorityNumber(TyFSType t) const; |
| |
| /*@}*/ |
| |
| |
| /** |
| * returns true iff it is allowed to add sub types to tyType. |
| */ |
| bool isAllowedToAddSubTypes(TyFSType tyType) const { |
| assert( isValidType(tyType) ); |
| // Integer, Float, String, ArrayBase, FSArray, IntArray, FloatArray, StringArray |
| return (!isBuiltinType(tyType)) |
| && (tyType != uima::internal::gs_tyArrayBaseType) |
| && (tyType != uima::internal::gs_tyFSArrayType) |
| && (tyType != uima::internal::gs_tyIntArrayType) |
| && (tyType != uima::internal::gs_tyFloatArrayType) |
| && (tyType != uima::internal::gs_tyStringArrayType); |
| } |
| |
| /** |
| * returns true iff it is allowed to create new feature on tyType. |
| */ |
| bool isAllowedToCreateFeatures(TyFSType tyType) const { |
| assert( isValidType(tyType) ); |
| return (isAllowedToAddSubTypes(tyType)) |
| && (tyType != iv_tyTop); |
| } |
| |
| /** |
| * returns true iff it is allowd to create an object of type tyType. |
| * (Not possible for e.g. integers) |
| */ |
| bool isAllowedToBeInstantiated(TyFSType tyType) const { |
| assert( isValidType(tyType) ); |
| return (! isBuiltinType(tyType) ); |
| } |
| |
| /** |
| * check if <code>tyFeature</code> is a valid feature ID. |
| */ |
| bool isValidFeature(TyFSFeature tyFeature) const { |
| return( tyFeature>0) && (tyFeature < iv_vecFeatureBaseNames.size()); |
| } |
| |
| /** |
| * check if <code>tyType</code> is a valid type ID. |
| */ |
| bool isValidType(TyFSType tyType) const { |
| return( tyType>0) && (tyType< iv_vecTypeNames.size()); |
| } |
| |
| /** |
| * check if <code>tyType</code> is maximal, i.e., |
| * has no subtypes. |
| */ |
| bool isMaximalType(TyFSType tyType) const { |
| assert( isValidType(tyType) ); |
| return iv_vecTree[tyType].size() == 0; |
| } |
| |
| /** |
| * get the number of all types in the type system. |
| */ |
| size_t getNumberOfTypes() const { |
| return iv_vecTypeNames.size() - 1; |
| } |
| |
| /** |
| * get the number of all features in the type system. |
| */ |
| size_t getNumberOfFeatures() const { |
| return iv_vecFeatureBaseNames.size() - 1; |
| } |
| |
| std::vector<icu::UnicodeString> const & getStringsForStringSubtype(TyFSType type) const; |
| |
| /** |
| * get a list of all the types in the type system. |
| * @param rvecResult output parameter |
| */ |
| void getAllTypes(std::vector<TyFSType>& rvecResult) const { |
| rvecResult.clear(); |
| TyFSType i; |
| for (i=1; i<iv_vecTypeNames.size(); ++i) { |
| rvecResult.push_back(i); |
| } |
| } |
| |
| /** |
| * get a list of all the features in the type system. |
| * @param rvecResult output parameter |
| */ |
| void getAllFeatures(std::vector<TyFSFeature>& rvecResult) const { |
| rvecResult.clear(); |
| TyFSFeature i; |
| for (i=1; i<iv_vecFeatureBaseNames.size(); ++i) { |
| rvecResult.push_back(i); |
| } |
| } |
| |
| /** |
| * find the type by its name. |
| * Returns <code>INVALID_TYPE</code> if no type with the name exists. |
| */ |
| TyFSType getTypeByName(icu::UnicodeString const & crusTypeName) const; |
| |
| /** |
| * get the name of the type. |
| */ |
| icu::UnicodeString const & getTypeName(TyFSType tyType) const { |
| assert( isValidType(tyType) ); |
| return iv_vecTypeNames[ (size_t) tyType]; |
| } |
| |
| /** |
| * get the creator id of the type. |
| */ |
| icu::UnicodeString const & getTypeCreatorID(TyFSType tyType) const { |
| assert( isValidType(tyType) ); |
| return iv_vecTypeCreatorIDs[ (size_t) tyType]; |
| } |
| |
| /** |
| * get the feature by its fully qualified name. |
| * Returns <code>INVALID_FEATURE</code> if no feature with the name exists. |
| */ |
| TyFSFeature getFeatureByFullName(icu::UnicodeString const & crusFeatureName) const; |
| |
| /** |
| * get the feature by its base name w.r.t. to a type it is defined for. |
| */ |
| TyFSFeature getFeatureByBaseName(TyFSType tyType, icu::UnicodeString const & crusFeatureName) const; |
| |
| TyFSFeature getFeatureByBaseName(icu::UnicodeString const & crusTypeName, icu::UnicodeString const & crusFeatureName) const; |
| |
| /** |
| * get the name of the feature. |
| */ |
| icu::UnicodeString const & getFeatureBaseName(TyFSFeature tyFeature) const { |
| assert( isValidFeature(tyFeature) ); |
| return iv_vecFeatureBaseNames[ tyFeature ]; |
| } |
| |
| /** |
| * returns the fully qualified name of the feature. |
| * The type name is its introduction type. |
| */ |
| icu::UnicodeString getFeatureName(TyFSFeature tyFeature) const; |
| |
| /** |
| * get the creator id of the feature. |
| */ |
| icu::UnicodeString const & getFeatureCreatorID(TyFSFeature tyFeature) const { |
| assert( isValidFeature(tyFeature) ); |
| return iv_vecFeatureCreatorIDs[ tyFeature ]; |
| } |
| |
| |
| /** |
| * get a list of all features appropriate for <code>tyType</code>, i.e., |
| * all features introduced by <code>tyType</code> or one of its ancestors. |
| * @param rResult output parameter |
| */ |
| void getAppropriateFeatures(TyFSType tyType, std::vector<TyFSFeature>& rResult) const; |
| |
| void getDirectSubTypes(TyFSType tyType, std::vector<TyFSType> & rResult) const; |
| |
| /** |
| * get the range of the feature, i.e., the value type <code>tyFeature</code> |
| * must have. |
| */ |
| TyFSType getRangeType(TyFSFeature tyFeature) const { |
| assert( isValidFeature(tyFeature) ); |
| return iv_vecRangeTypes[tyFeature]; |
| } |
| |
| /** |
| * get the feature property multipleReferencesAllowed. |
| * |
| */ |
| bool isMultipleReferencesAllowed(TyFSFeature tyFeature) const { |
| assert( isValidFeature(tyFeature) ); |
| return iv_vecMultiRefs[tyFeature]; |
| } |
| |
| |
| /** |
| * check if <code>tyFeature</code> is appropriate for <code>tyType</code>. |
| */ |
| bool isAppropriateFeature(TyFSType tyType, TyFSFeature tyFeature) const { |
| assert( iv_bIsCommitted ); |
| assert( isValidType(tyType) ); |
| assert( isValidFeature(tyFeature) ); |
| return iv_vecApprop[tyType][tyFeature]; |
| } |
| |
| |
| /** |
| * get the top type. |
| */ |
| TyFSType getTopType() const { |
| return iv_tyTop; |
| } |
| |
| TyFSType getMostSpecificCommonSupertype(TyFSType t1, TyFSType t2) const; |
| |
| /** |
| * get all subsumed types of <code>tyType</code>. |
| * @param rResult output parameter |
| */ |
| void getSubsumedTypes(TyFSType tyType, std::vector<TyFSType>& rResult) const; |
| |
| /** |
| * get the parent type of <code>tyType</code>. |
| */ |
| TyFSType getParentType(TyFSType tyType) const; |
| |
| /** |
| * check if <code>tyType1</code> subsumes <code>tyType2</code>. |
| */ |
| bool subsumes(TyFSType tyType1, TyFSType tyType2) const; |
| |
| bool hasPriorityOver(TyFSType tyType1, TyFSType tyType2) const { |
| assert( isValidType(tyType1) ); |
| assert( isValidType(tyType2) ); |
| assert( iv_mapTypePriority.find(tyType1) != iv_mapTypePriority.end() ); |
| assert( iv_mapTypePriority.find(tyType2) != iv_mapTypePriority.end() ); |
| size_t p1 = (*iv_mapTypePriority.find(tyType1)).second; |
| size_t p2 = (*iv_mapTypePriority.find(tyType2)).second; |
| return p1 < p2; |
| } |
| |
| /** |
| * get the type where <code>tyFeature</code> was introduced. |
| */ |
| TyFSType getIntroType(TyFSFeature tyFeature) const; |
| |
| /** |
| * method for determining positional encodings of features |
| * for heap representation. Since we impose feature introduction, |
| * we don't need type information. |
| * Use this in combination with uima::lowlevel::FSHeap::getFeatureWithOffset for |
| * fast access of features. |
| */ |
| TyFeatureOffset getFeatureOffset(TyFSFeature tyFeature) const { |
| assert( iv_bIsCommitted ); |
| assert( isValidFeature(tyFeature) ); |
| return iv_vecFeatureOffset[tyFeature]; |
| } |
| |
| TyFSFeature getFeatureFromOffset(TyFSType tyType, TyFeatureOffset tyOffset) const { |
| assert( isValidType(tyType) ); |
| assert( tyType < iv_vecTypeFeatureOffsetMapping.size() ); |
| assert( tyOffset < iv_vecTypeFeatureOffsetMapping[tyType].size() ); |
| return iv_vecTypeFeatureOffsetMapping[tyType][tyOffset]; |
| } |
| |
| /** |
| * get the number of features of <code>tyType</code>. |
| */ |
| TyFeatureOffset getFeatureNumber(TyFSType tyType) const { |
| assert( iv_bIsCommitted ); |
| assert( isValidType(tyType) ); |
| return iv_vecFeatureNumber[tyType]; |
| } |
| |
| static icu::UnicodeString const ustrCREATOR_ID_SYSTEM; |
| }; |
| |
| } |
| } |
| |
| /* ----------------------------------------------------------------------- */ |
| /* Implementation */ |
| /* ----------------------------------------------------------------------- */ |
| |
| |
| /* ----------------------------------------------------------------------- */ |
| |
| |
| #endif |
| |