/// <summary>
        /// Validation rule checking usage of reserved RDF/RDFS/OWL terms in vocabulary of classes, properties and facts
        /// </summary>
        internal static void Vocabulary_Reservation(RDFOntology ontology, RDFOntologyValidationReport report) {
            RDFSemanticsEvents.RaiseSemanticsInfo("Launched execution of validation rule 'Vocabulary_Reservation'");

            #region Classes
            foreach (var  c in ontology.Model.ClassModel.Where(cls => cls.ToString().StartsWith(RDFVocabulary.RDF.BASE_URI)  ||
                                                                      cls.ToString().StartsWith(RDFVocabulary.RDFS.BASE_URI) ||
                                                                      cls.ToString().StartsWith(RDFVocabulary.OWL.BASE_URI))) {
                if (!c.Equals(RDFVocabulary.OWL.THING)       && !c.Equals(RDFVocabulary.OWL.NOTHING) &&
                    !c.Equals(RDFVocabulary.RDFS.LITERAL)    && 
                    !c.Equals(RDFVocabulary.RDF.XML_LITERAL) && !c.Equals(RDFVocabulary.RDF.HTML)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                         "Vocabulary_Reservation",
                         String.Format("RDF/RDFS/OWL vocabularies are reserved, they cannot be used for class names."),
                         String.Format("Remove ontology class '{0}' from the class model.", c)
                     ));
                }
            }
            #endregion

            #region Properties
            foreach (var  p in ontology.Model.PropertyModel.Where(prop => prop.ToString().StartsWith(RDFVocabulary.RDF.BASE_URI)  ||
                                                                          prop.ToString().StartsWith(RDFVocabulary.RDFS.BASE_URI) ||
                                                                          prop.ToString().StartsWith(RDFVocabulary.OWL.BASE_URI))) {
                report.AddEvidence(new RDFOntologyValidationEvidence(
                    RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                    "Vocabulary_Reservation",
                    String.Format("RDF/RDFS/OWL vocabularies are reserved, they cannot be used for property names."),
                    String.Format("Remove ontology property '{0}' from the property model.", p)
                ));
            }
            #endregion

            #region Facts
            foreach (var  f in ontology.Data.Where(fact => fact.ToString().StartsWith(RDFVocabulary.RDF.BASE_URI)  ||
                                                           fact.ToString().StartsWith(RDFVocabulary.RDFS.BASE_URI) ||
                                                           fact.ToString().StartsWith(RDFVocabulary.OWL.BASE_URI))) {
                report.AddEvidence(new RDFOntologyValidationEvidence(
                    RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                    "Vocabulary_Reservation",
                    String.Format("RDF/RDFS/OWL vocabularies are reserved, they cannot be used for fact names."),
                    String.Format("Remove ontology fact '{0}' from the data.", f)
                ));
            }
            #endregion

            RDFSemanticsEvents.RaiseSemanticsInfo("Completed execution of validation rule 'Vocabulary_Reservation'");
        }
        /// <summary>
        /// Validation rule checking for usage of deprecated classes and properties
        /// </summary>
        internal static void Deprecation(RDFOntology ontology, RDFOntologyValidationReport report) {
            RDFSemanticsEvents.RaiseSemanticsInfo("Launched execution of validation rule 'Deprecation'");

            #region Class
            foreach (var deprCls   in ontology.Data.Relations.ClassType.Where(c => c.TaxonomyObject.IsDeprecatedClass())) {
                report.AddEvidence(new RDFOntologyValidationEvidence(
                    RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                    "Deprecation",
                    String.Format("Ontology fact '{0}' has a classtype '{1}', which is deprecated (may be removed in a future ontology version!).", deprCls.TaxonomySubject, deprCls.TaxonomyObject),
                    String.Format("Update the classtype of ontology fact '{0}' to a non-deprecated class definition.", deprCls.TaxonomySubject)
                ));
            }
            #endregion

            #region Property
            foreach (var deprProp  in ontology.Data.Relations.Assertions.Where(p => p.TaxonomyPredicate.IsDeprecatedProperty())) {
                report.AddEvidence(new RDFOntologyValidationEvidence(
                    RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                    "Deprecation",
                    String.Format("Ontology fact '{0}' has an assertion using ontology property '{1}', which is deprecated (may be removed in a future ontology version!).", deprProp.TaxonomySubject, deprProp.TaxonomyPredicate),
                    String.Format("Update the assertion of ontology fact '{0}' to a non-deprecated property definition.", deprProp.TaxonomySubject)
                ));
            }
            #endregion

            RDFSemanticsEvents.RaiseSemanticsInfo("Completed execution of validation rule 'Deprecation'");
        }
        /// <summary>
        /// Validation rule checking for disjointness of vocabulary of classes, properties and facts
        /// </summary>
        internal static void Vocabulary_Disjointness(RDFOntology ontology, RDFOntologyValidationReport report) {
            RDFSemanticsEvents.RaiseSemanticsInfo("Launched execution of validation rule 'Vocabulary_Disjointness'");

            #region ClassModel
            foreach (var c in ontology.Model.ClassModel) {
                if (ontology.Model.PropertyModel.Properties.ContainsKey(c.PatternMemberID)) {
                    report.AddEvidence(new RDFOntologyValidationEvidence(
                        RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                        "Vocabulary_Disjointness",
                        String.Format("Disjointess of class model and property model is violated because the name '{0}' refers both to a class and a property.", c),
                        String.Format("Remove, or rename, one of the two entities.")
                    ));
                }
                if (ontology.Data.Facts.ContainsKey(c.PatternMemberID)) {
                    report.AddEvidence(new RDFOntologyValidationEvidence(
                        RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                        "Vocabulary_Disjointness",
                        String.Format("Disjointess of class model and data is violated because the name '{0}' refers both to a class and a fact.", c),
                        String.Format("Remove, or rename, one of the two entities.")
                    ));
                }
            }
            #endregion

            #region PropertyModel
            foreach (var p in ontology.Model.PropertyModel) {
                if (ontology.Data.Facts.ContainsKey(p.PatternMemberID)) {
                    report.AddEvidence(new RDFOntologyValidationEvidence(
                        RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                        "Vocabulary_Disjointness",
                        String.Format("Disjointess of property model and data is violated because the name '{0}' refers both to a property and a fact.", p),
                        String.Format("Remove, or rename, one of the two entities.")
                    ));
                }
            }
            #endregion

            RDFSemanticsEvents.RaiseSemanticsInfo("Completed execution of validation rule 'Vocabulary_Disjointness'");
        }
        /// <summary>
        /// Validation rule checking consistency of local cardinality constraints
        /// </summary>
        internal static void LocalCardinalityConstraint(RDFOntology ontology, RDFOntologyValidationReport report) {
            RDFSemanticsEvents.RaiseSemanticsInfo("Launched execution of validation rule 'LocalCardinalityConstraint'");

            #region LocalCardinalityConstraint
            //OWL-DL requires that for a transitive property no local cardinality constraints should
            //be declared on the property itself, or its super properties, or its inverse properties.
            foreach (var cardRestr in ontology.Model.ClassModel.Where(c => c is RDFOntologyCardinalityRestriction).OfType<RDFOntologyCardinalityRestriction>()) {
                var  restrProp      = ontology.Model.PropertyModel.SelectProperty(cardRestr.OnProperty.ToString());
                if  (restrProp     != null) {
                    if (restrProp.IsObjectProperty()) {
                        if (((RDFOntologyObjectProperty)restrProp).Transitive) {
                              report.AddEvidence(new RDFOntologyValidationEvidence(
                                  RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                  "LocalCardinalityConstraint",
                                  String.Format("Ontology property '{0}' is an 'owl:TransitiveProperty', but it has a local cardinality constraint '{1}'. This is not permitted in OWL-DL.", restrProp, cardRestr),
                                  String.Format("Unset the ontology property '{0}' as 'owl:TransitiveProperty', or remove the local cardinality constraint '{1}' applied on it.", restrProp, cardRestr)
                              ));
                        }
                        foreach (var subProps in RDFOntologyReasoningHelper.EnlistSubPropertiesOf(restrProp, ontology.Model.PropertyModel)) {
                            if  (subProps.IsObjectProperty()) {
                                 if (((RDFOntologyObjectProperty)subProps).Transitive) {
                                       report.AddEvidence(new RDFOntologyValidationEvidence(
                                           RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                           "LocalCardinalityConstraint",
                                           String.Format("Ontology property '{0}' has a local cardinality constraint '{1}', but it is also super property of ontology property '{2}', which is an 'owl:TransitiveProperty'. This is not permitted in OWL-DL.", restrProp, cardRestr, subProps),
                                           String.Format("Unset the ontology property '{0}' as 'owl:TransitiveProperty', or remove the local cardinality constraint '{1}' applied on its super property '{2}'.", subProps, cardRestr, restrProp)
                                       ));
                                 }
                            }
                        }
                        foreach (var inverseProps in ontology.Model.PropertyModel.Relations.InverseOf.SelectEntriesBySubject(restrProp)) {
                            if  (((RDFOntologyObjectProperty)inverseProps.TaxonomyObject).Transitive) {
                                   report.AddEvidence(new RDFOntologyValidationEvidence(
                                       RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                       "LocalCardinalityConstraint",
                                       String.Format("Ontology property '{0}' has a local cardinality constraint '{1}', but it also has an 'owl:inverseOf' relation with ontology property '{2}', which is an 'owl:TransitiveProperty'. This is not permitted in OWL-DL.", restrProp, cardRestr, inverseProps.TaxonomyObject),
                                       String.Format("Unset the ontology property '{0}' as 'owl:TransitiveProperty', or remove the local cardinality constraint '{1}' applied on its inverse ontology property '{2}'.", inverseProps.TaxonomyObject, cardRestr, restrProp)
                                   ));
                            }
                        }
                    }
                }
            }
            #endregion

            RDFSemanticsEvents.RaiseSemanticsInfo("Completed execution of validation rule 'LocalCardinalityConstraint'");
        }
        /// <summary>
        /// Validation rule checking consistency of global cardinality constraints
        /// </summary>
        internal static void GlobalCardinalityConstraint(RDFOntology ontology, RDFOntologyValidationReport report) {
            RDFSemanticsEvents.RaiseSemanticsInfo("Launched execution of validation rule 'GlobalCardinalityConstraint'");

            #region GlobalCardinalityConstraint
            foreach (var prop    in ontology.Model.PropertyModel.Where(p => p.Functional || (p.IsObjectProperty() && ((RDFOntologyObjectProperty)p).InverseFunctional))) {
                var assertions    = ontology.Data.Relations.Assertions.SelectEntriesByPredicate(prop);
                var subjCache     = new Dictionary<Int64, RDFOntologyResource>();
                var objCache      = new Dictionary<Int64, RDFOntologyResource>();

                foreach (var asn in assertions) {

                    #region Functional
                    if  (prop.IsFunctionalProperty()) {

                         if (!subjCache.ContainsKey(asn.TaxonomySubject.PatternMemberID)) {
                              subjCache.Add(asn.TaxonomySubject.PatternMemberID, asn.TaxonomySubject);
                         }
                         else {

                              //FunctionalProperty can only occur once per subject fact within assertions
                              report.AddEvidence(new RDFOntologyValidationEvidence(
                                  RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                  "GlobalCardinalityConstraint",
                                  String.Format("Ontology property '{0}' has an 'owl:FunctionalProperty' global cardinality constraint, which is violated by subject ontology fact '{1}'.", asn.TaxonomyPredicate, asn.TaxonomySubject),
                                  String.Format("Remove the '{0} {1} {2}' assertion from the data.", asn.TaxonomySubject, asn.TaxonomyPredicate, asn.TaxonomyObject)
                              ));

                         }

                         //FunctionalProperty cannot be TransitiveProperty (even indirectly)
                         if (prop.IsTransitiveProperty() || RDFOntologyReasoningHelper.EnlistSuperPropertiesOf(prop, ontology.Model.PropertyModel).Any(p => p.IsTransitiveProperty())) {
                             report.AddEvidence(new RDFOntologyValidationEvidence(
                                 RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                 "GlobalCardinalityConstraint",
                                 String.Format("Ontology property '{0}' has an 'owl:FunctionalProperty' global cardinality constraint, but it is also declared as 'owl:TransitiveProperty'. This is not allowed in OWL-DL.", prop),
                                 String.Format("Remove the 'owl:FunctionalProperty' global cardinality constraint from the ontology property '{0}', or unset this property as 'owl:TransitiveProperty'.", prop)
                             ));
                         }

                    }
                    #endregion

                    #region InverseFunctional
                    if  (prop.IsInverseFunctionalProperty()) {
                         if (!objCache.ContainsKey(asn.TaxonomyObject.PatternMemberID)) {
                              objCache.Add(asn.TaxonomyObject.PatternMemberID, asn.TaxonomyObject);
                         }
                         else {

                              //InverseFunctionalProperty can only occur once per object fact within assertions
                              report.AddEvidence(new RDFOntologyValidationEvidence(
                                  RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                  "GlobalCardinalityConstraint",
                                  String.Format("Ontology property '{0}' has an 'owl:InverseFunctionalProperty' global cardinality constraint, which is violated by object ontology fact '{1}'.", asn.TaxonomyPredicate, asn.TaxonomyObject),
                                  String.Format("Remove the '{0} {1} {2}' assertion from the data.", asn.TaxonomySubject, asn.TaxonomyPredicate, asn.TaxonomyObject)
                              ));

                         }

                         //InverseFunctionalProperty cannot be TransitiveProperty (even indirectly)
                         if (prop.IsTransitiveProperty() || RDFOntologyReasoningHelper.EnlistSuperPropertiesOf(prop, ontology.Model.PropertyModel).Any(p => p.IsTransitiveProperty())) {
                               report.AddEvidence(new RDFOntologyValidationEvidence(
                                   RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                   "GlobalCardinalityConstraint",
                                   String.Format("Ontology property '{0}' has an 'owl:InverseFunctionalProperty' global cardinality constraint, but it is also declared as 'owl:TransitiveProperty'. This is not allowed in OWL-DL.", prop),
                                   String.Format("Remove the 'owl:InverseFunctionalProperty' global cardinality constraint from the ontology property '{0}', or unset this property as 'owl:TransitiveProperty'.", prop)
                               ));
                         }

                    }
                    #endregion

                }
            }
            #endregion

            RDFSemanticsEvents.RaiseSemanticsInfo("Completed execution of validation rule 'GlobalCardinalityConstraint'");
        }
        /// <summary>
        /// Validation rule checking for consistency of rdf:type axioms
        /// </summary>
        internal static void ClassType(RDFOntology ontology, RDFOntologyValidationReport report) {
            RDFSemanticsEvents.RaiseSemanticsInfo("Launched execution of validation rule 'ClassType'");
            
            #region Facts
            var disjWithCache       = new Dictionary<Int64, RDFOntologyClassModel>();
            var litCheckCache       = new Dictionary<Int64, Boolean>();
            foreach (var  fact     in ontology.Data) {
                var classTypes      = new RDFOntologyClassModel();
                foreach (var cType in ontology.Data.Relations.ClassType.SelectEntriesBySubject(fact)) {

                    //ClassTypes of a fact cannot be compatible with "rdfs:Literal"
                    var cTypeClass  = ontology.Model.ClassModel.SelectClass(cType.TaxonomyObject.ToString());
                    if (cTypeClass != null) {
                        if (!litCheckCache.ContainsKey(cTypeClass.PatternMemberID)) {
                             litCheckCache.Add(cTypeClass.PatternMemberID, RDFOntologyReasoningHelper.IsLiteralCompatibleClass(cTypeClass, ontology.Model.ClassModel));
                        }
                        if (litCheckCache[cTypeClass.PatternMemberID]) {
                            report.AddEvidence(new RDFOntologyValidationEvidence(
                                RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                "ClassType",
                                String.Format("Ontology fact '{0}' has a classtype '{1}' which is compatible with 'rdfs:Literal' and this cannot be possible.", fact, cTypeClass),
                                String.Format("Review classtypes of ontology fact '{0}'.", fact)
                            ));
                        }
                        else {
                            classTypes.AddClass(cTypeClass);
                        }
                    }

                }

                //ClassTypes of a fact cannot be disjoint
                foreach (var cType in classTypes) {
                    if  (!disjWithCache.ContainsKey(cType.PatternMemberID)) {
                          disjWithCache.Add(cType.PatternMemberID, RDFOntologyReasoningHelper.EnlistDisjointClassesWith(cType, ontology.Model.ClassModel));
                    }
                    foreach (var disjWithCType in disjWithCache[cType.PatternMemberID].IntersectWith(classTypes)) {
                        report.AddEvidence(new RDFOntologyValidationEvidence(
                            RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                            "ClassType",
                            String.Format("Ontology fact '{0}' has both classtypes '{1}' and '{2}', which cannot be compatible because of an 'owl:disjointWith' constraint.", fact, cType, disjWithCType),
                            String.Format("Review classtypes of ontology fact '{0}'.", fact)
                        ));
                    }
                }

            }
            #endregion

            RDFSemanticsEvents.RaiseSemanticsInfo("Completed execution of validation rule 'ClassType'");
        }
        /// <summary>
        /// Validation rule checking for consistency of owl:SymmetricProperty axioms
        /// </summary>
        internal static void SymmetricProperty(RDFOntology ontology, RDFOntologyValidationReport report) {
            RDFSemanticsEvents.RaiseSemanticsInfo("Launched execution of validation rule 'SymmetricProperty'");

            #region SymmetricProperty
            foreach(var symProp in ontology.Model.PropertyModel.Where(prop => prop.IsSymmetricProperty() && (prop.Domain != null || prop.Range != null))) {
                foreach(var asn in ontology.Data.Relations.Assertions.Where(asn => asn.TaxonomyPredicate.Equals(symProp))) {

                    #region Domain
                    if(symProp.Domain != null) {
                       if(!RDFOntologyReasoningHelper.IsMemberOf((RDFOntologyFact)asn.TaxonomyObject, symProp.Domain, ontology)) {
                           report.AddEvidence(new RDFOntologyValidationEvidence(
                               RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                               "SymmetricProperty",
                               String.Format("Violation of 'owl:SymmetricProperty' constraint on property '{0}': range fact '{1}' is not compatible with domain class '{2}' of the property.", symProp, asn.TaxonomyObject, symProp.Domain),
                               String.Format("Review classtypes of ontology fact '{0}' in order to be compatible with 'rdfs:domain' constraint on ontology property '{1}'.", asn.TaxonomyObject, symProp)
                           ));
                        }
                    }
                    #endregion

                    #region Range
                    if(symProp.Range  != null) {
                        if(!RDFOntologyReasoningHelper.IsMemberOf((RDFOntologyFact)asn.TaxonomySubject, symProp.Range, ontology)) {
                            report.AddEvidence(new RDFOntologyValidationEvidence(
                                RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                "SymmetricProperty",
                                String.Format("Violation of 'owl:SymmetricProperty' constraint on property '{0}': domain fact '{1}' is not compatible with range class '{2}' of the property.", symProp, asn.TaxonomySubject, symProp.Range),
                                String.Format("Review classtypes of ontology fact '{0}' in order to be compatible with 'rdfs:range' constraint on ontology property '{1}'.", asn.TaxonomySubject, symProp)
                            ));
                        }
                    }
                    #endregion

                }

            }
            #endregion

            RDFSemanticsEvents.RaiseSemanticsInfo("Completed execution of validation rule 'SymmetricProperty'");
        }
        /// <summary>
        /// Validation rule checking for consistency of owl:inverseOf axioms
        /// </summary>
        internal static void InverseOf(RDFOntology ontology, RDFOntologyValidationReport report) {
            RDFSemanticsEvents.RaiseSemanticsInfo("Launched execution of validation rule 'InverseOf'");

            #region InverseOf
            foreach (var invOf in ontology.Model.PropertyModel.Relations.InverseOf) {

                #region Domain VS Range
                if (((RDFOntologyObjectProperty)invOf.TaxonomySubject).Domain != null  &&
                    ((RDFOntologyObjectProperty)invOf.TaxonomyObject).Range   != null)  {
                      if (!RDFOntologyReasoningHelper.IsRangeClassOf(((RDFOntologyObjectProperty)invOf.TaxonomySubject).Domain, 
                                                                     (RDFOntologyObjectProperty)invOf.TaxonomyObject, 
                                                                      ontology.Model.ClassModel)) {
                           report.AddEvidence(new RDFOntologyValidationEvidence(
                               RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                               "InverseOf",
                               String.Format("Violation of 'rdfs:domain' constraint on 'owl:inverseOf' taxonomy between property '{0}' and property '{1}'.", invOf.TaxonomySubject, invOf.TaxonomyObject),
                               String.Format("Review 'rdfs:domain' constraint on ontology property '{0}' in order to be compatible with 'rdfs:range' constraint on ontology property '{1}'.", invOf.TaxonomySubject, invOf.TaxonomyObject)
                           ));
                      }
                }
                #endregion

                #region Range VS Domain
                if (((RDFOntologyObjectProperty)invOf.TaxonomySubject).Range != null  &&
                    ((RDFOntologyObjectProperty)invOf.TaxonomyObject).Domain != null)  {
                      if (!RDFOntologyReasoningHelper.IsDomainClassOf(((RDFOntologyObjectProperty)invOf.TaxonomySubject).Range, 
                                                                      (RDFOntologyObjectProperty)invOf.TaxonomyObject, 
                                                                       ontology.Model.ClassModel)) {
                           report.AddEvidence(new RDFOntologyValidationEvidence(
                               RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                               "InverseOf",
                               String.Format("Violation of 'rdfs:range' constraint on 'owl:inverseOf' taxonomy between property '{0}' and property '{1}'.", invOf.TaxonomySubject, invOf.TaxonomyObject),
                               String.Format("Review 'rdfs:range' constraint on ontology property '{0}' in order to be compatible with 'rdfs:domain' constraint on ontology property '{1}'.", invOf.TaxonomySubject, invOf.TaxonomyObject)
                           ));
                      }
                }
                #endregion

            }
            #endregion

            RDFSemanticsEvents.RaiseSemanticsInfo("Completed execution of validation rule 'InverseOf'");
        }
        /// <summary>
        /// Validation rule checking for consistency of rdfs:domain and rdfs:range axioms
        /// </summary>
        internal static void Domain_Range(RDFOntology ontology, RDFOntologyValidationReport report) {
            RDFSemanticsEvents.RaiseSemanticsInfo("Launched execution of validation rule 'Domain_Range'");

            #region Domain_Range
            var classCache    = new Dictionary<Int64, RDFOntologyData>();
            var litCheckCache = new Dictionary<Int64, Boolean>();
            foreach (var assertion  in ontology.Data.Relations.Assertions.Where(asn =>
                                                        ((RDFOntologyProperty)asn.TaxonomyPredicate).Domain != null  ||
                                                        ((RDFOntologyProperty)asn.TaxonomyPredicate).Range  != null)) {

                #region Domain
                var domain    = ((RDFOntologyProperty)assertion.TaxonomyPredicate).Domain;
                if (domain   != null) {

                    //Domain class cannot be a datarange or compatible with rdfs:Literal
                    if (!litCheckCache.ContainsKey(domain.PatternMemberID)) {
                         litCheckCache.Add(domain.PatternMemberID, RDFOntologyReasoningHelper.IsLiteralCompatibleClass(domain, ontology.Model.ClassModel));
                    }
                    if (litCheckCache[domain.PatternMemberID]) {
                        report.AddEvidence(new RDFOntologyValidationEvidence(
                            RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                            "Domain_Range",
                            String.Format("Violation of 'rdfs:domain' constraint on property '{0}': ontology class '{1}' cannot be compatible with 'rdfs:Literal'.", assertion.TaxonomyPredicate, domain),
                            String.Format("Review relations of ontology class '{0}'.", domain)
                        ));
                    }
                    else {

                        //Cache-Miss
                        if (!classCache.ContainsKey(domain.PatternMemberID)) {
                             classCache.Add(domain.PatternMemberID, RDFOntologyReasoningHelper.EnlistMembersOf(domain, ontology));
                        }

                        //Cache-Check
                        if (classCache[domain.PatternMemberID].SelectFact(assertion.TaxonomySubject.ToString()) == null) {
                            report.AddEvidence(new RDFOntologyValidationEvidence(
                                RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                "Domain_Range",
                                String.Format("Violation of 'rdfs:domain' constraint on property '{0}': ontology fact '{1}' is incompatible with domain class '{2}'.", assertion.TaxonomyPredicate, assertion.TaxonomySubject, domain),
                                String.Format("Review classtypes of ontology fact '{0}'.", assertion.TaxonomySubject)
                            ));
                        }

                    }

                }
                #endregion

                #region Range
                var range     = ((RDFOntologyProperty)assertion.TaxonomyPredicate).Range;
                if (range    != null) {
                    if (((RDFOntologyProperty)assertion.TaxonomyPredicate).IsObjectProperty()) {

                        //Cache-Miss
                        if (!classCache.ContainsKey(range.PatternMemberID)) {
                             classCache.Add(range.PatternMemberID, RDFOntologyReasoningHelper.EnlistMembersOf(range, ontology));
                        }

                        //Cache-Check
                        if (classCache[range.PatternMemberID].SelectFact(assertion.TaxonomyObject.ToString()) == null) {
                            report.AddEvidence(new RDFOntologyValidationEvidence(
                                RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                "Domain_Range",
                                String.Format("Violation of 'rdfs:range' constraint on property '{0}': ontology fact '{1}' is incompatible with range class '{2}'.", assertion.TaxonomyPredicate, assertion.TaxonomyObject, range),
                                String.Format("Review classtypes of ontology fact '{0}'.", assertion.TaxonomyObject)
                            ));
                        }

                    }
                    else {

                        //Cache-Miss
                        if (!classCache.ContainsKey(range.PatternMemberID)) {
                             classCache.Add(range.PatternMemberID, RDFOntologyReasoningHelper.EnlistMembersOf(range, ontology));
                        }

                        //Cache-Check
                        if (classCache[range.PatternMemberID].SelectLiteral(assertion.TaxonomyObject.ToString()) == null) {
                            report.AddEvidence(new RDFOntologyValidationEvidence(
                                RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                                "Domain_Range",
                                String.Format("Violation of 'rdfs:range' constraint on property '{0}': ontology literal '{1}' is incompatible with range class '{2}'.", assertion.TaxonomyPredicate, assertion.TaxonomyObject, range),
                                String.Format("Review datatype of ontology literal '{0}'.", assertion.TaxonomyObject)
                            ));
                        }

                    }
                }
                #endregion

            }
            #endregion

            RDFSemanticsEvents.RaiseSemanticsInfo("Completed execution of validation rule 'Domain_Range'");
        }
        /// <summary>
        /// Validation rule checking for declaration of classes, properties and facts
        /// </summary>
        internal static void Vocabulary_Declaration(RDFOntology ontology, RDFOntologyValidationReport report) {
            RDFSemanticsEvents.RaiseSemanticsInfo("Launched execution of validation rule 'Vocabulary_Declaration'");

            #region Classes

            //SubClassOf
            foreach (var   c in ontology.Model.ClassModel.Relations.SubClassOf) {
                if  (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomySubject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by a 'rdfs:subclassOf' relation.", c),
                          String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomySubject)
                      ));
                }
                if (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomyObject.PatternMemberID)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                         "Vocabulary_Declaration",
                         String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by a 'rdfs:subclassOf' relation.", c),
                         String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomyObject)
                     ));
                }
            }

            //EquivalentClass
            foreach (var   c in ontology.Model.ClassModel.Relations.EquivalentClass) {
                if  (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomySubject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by an 'owl:EquivalentClass' relation.", c),
                          String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomySubject)
                      ));
                }
                if (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomyObject.PatternMemberID)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                         "Vocabulary_Declaration",
                         String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by an 'owl:EquivalentClass' relation.", c),
                         String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomyObject)
                     ));
                }
            }

            //DisjointWith
            foreach (var   c in ontology.Model.ClassModel.Relations.DisjointWith) {
                if  (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomySubject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by an 'owl:DisjointWith' relation.", c),
                          String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomySubject)
                     ));
                }
                if (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomyObject.PatternMemberID)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                         "Vocabulary_Declaration",
                         String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by an 'owl:DisjointWith' relation.", c),
                         String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomyObject)
                     ));
                }
            }

            //OneOf
            foreach (var   c in ontology.Model.ClassModel.Relations.OneOf) {
                if  (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomySubject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by an 'owl:oneOf' relation.", c),
                          String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomySubject)
                     ));
                }
            }

            //IntersectionOf
            foreach (var   c in ontology.Model.ClassModel.Relations.IntersectionOf) {
                if  (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomySubject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by an 'owl:intersectionOf' relation.", c),
                          String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomySubject)
                     ));
                }
                if (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomyObject.PatternMemberID)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                         "Vocabulary_Declaration",
                         String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by an 'owl:intersectionOf' relation.", c),
                         String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomyObject)
                     ));
                }
            }

            //UnionOf
            foreach (var   c in ontology.Model.ClassModel.Relations.UnionOf) {
                if  (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomySubject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by an 'owl:unionOf' relation.", c),
                          String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomySubject)
                     ));
                }
                if (!ontology.Model.ClassModel.Classes.ContainsKey(c.TaxonomyObject.PatternMemberID)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                         "Vocabulary_Declaration",
                         String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by an 'owl:unionOf' relation.", c),
                         String.Format("Add declaration of ontology class '{0}' to the class model.", c.TaxonomyObject)
                     ));
                }
            }

            //ComplementOf
            foreach (var complCls  in ontology.Model.ClassModel.Where(c => c is RDFOntologyComplementClass).OfType<RDFOntologyComplementClass>()) {
                if  (!ontology.Model.ClassModel.Classes.ContainsKey(complCls.ComplementOf.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology class '{0}' is not found in the class model: complement class '{1}' requires it.", complCls.ComplementOf, complCls),
                          String.Format("Add declaration of ontology class '{0}' to the class model.", complCls.ComplementOf)
                      ));
                }
            }

            //Domain / Range
            foreach (var p in ontology.Model.PropertyModel.Where(prop => prop.Domain != null || prop.Range != null)) {
                if  (p.Domain != null) {
                     if (!ontology.Model.ClassModel.Classes.ContainsKey(p.Domain.PatternMemberID)) {
                          report.AddEvidence(new RDFOntologyValidationEvidence(
                              RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                              "Vocabulary_Declaration",
                              String.Format("Declaration of ontology class '{0}' is not found in the class model: ontology property '{1}' requires it as 'rdfs:domain'.", p.Domain, p),
                              String.Format("Add declaration of ontology class '{0}' to the class model.", p.Domain)
                          ));
                     }
                }
                if  (p.Range != null) {
                     if (!ontology.Model.ClassModel.Classes.ContainsKey(p.Range.PatternMemberID)) {
                          report.AddEvidence(new RDFOntologyValidationEvidence(
                              RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                              "Vocabulary_Declaration",
                              String.Format("Declaration of ontology class '{0}' is not found in the class model: ontology property '{1}' requires it as 'rdfs:range'.", p.Range, p),
                              String.Format("Add declaration of ontology class '{0}' to the class model.", p.Range)
                          ));
                     }
                }
            }

            #endregion

            #region Restrictions

            var restrEnum  = ontology.Model.ClassModel.RestrictionsEnumerator;
            while(restrEnum.MoveNext()) {

                //OnProperty
                var onProp = restrEnum.Current.OnProperty;
                if (!ontology.Model.PropertyModel.Properties.ContainsKey(onProp.Value.PatternMemberID)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                         "Vocabulary_Declaration",
                         String.Format("Declaration of ontology property '{0}' is not found in the property model: restriction class '{1}' requires it as 'owl:OnProperty'.", onProp, restrEnum.Current),
                         String.Format("Add declaration of ontology property '{0}' to the property model.", onProp)
                     ));
                }

                // AllValuesFrom
                if (restrEnum.Current is RDFOntologyAllValuesFromRestriction) {
                    var fromClass = ((RDFOntologyAllValuesFromRestriction)restrEnum.Current).FromClass;
                    if (!ontology.Model.ClassModel.Classes.ContainsKey(fromClass.Value.PatternMemberID)) {
                         report.AddEvidence(new RDFOntologyValidationEvidence(
                             RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                             "Vocabulary_Declaration",
                             String.Format("Declaration of ontology class '{0}' is not found in the class model: restriction class '{1}' requires it as 'owl:FromClass'.", fromClass, restrEnum.Current),
                             String.Format("Add declaration of ontology class '{0}' to the class model.", fromClass)
                         ));
                    }
                }

                // SomeValuesFrom
                else if (restrEnum.Current is RDFOntologySomeValuesFromRestriction) {
                    var fromClass = ((RDFOntologySomeValuesFromRestriction)restrEnum.Current).FromClass;
                    if (!ontology.Model.ClassModel.Classes.ContainsKey(fromClass.Value.PatternMemberID)) {
                         report.AddEvidence(new RDFOntologyValidationEvidence(
                             RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                             "Vocabulary_Declaration",
                             String.Format("Declaration of ontology class '{0}' is not found in the class model: restriction class '{1}' requires it as 'owl:FromClass'.", fromClass, restrEnum.Current),
                             String.Format("Add declaration of ontology class '{0}' to the class model.", fromClass)
                         ));
                    }
                }

                // HasValue
                else if (restrEnum.Current is RDFOntologyHasValueRestriction) {
                    var  requiredValue =    ((RDFOntologyHasValueRestriction)restrEnum.Current).RequiredValue;
                    if  (requiredValue.IsFact() && !ontology.Data.Facts.ContainsKey(requiredValue.Value.PatternMemberID)) {
                         report.AddEvidence(new RDFOntologyValidationEvidence(
                             RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                             "Vocabulary_Declaration",
                             String.Format("Declaration of ontology fact '{0}' is not found in the data: restriction class '{1}' requires it as 'owl:RequiredValue'.", requiredValue, restrEnum.Current),
                             String.Format("Add declaration of ontology fact '{0}' to the data.", requiredValue)
                         ));
                    }
                }

            }

            #endregion

            #region Properties

            //SubPropertyOf
            foreach (var   p in ontology.Model.PropertyModel.Relations.SubPropertyOf) {
                if  (!ontology.Model.PropertyModel.Properties.ContainsKey(p.TaxonomySubject.Value.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology property '{0}' is not found in the property model: it is required by a 'rdfs:subpropertyOf' relation.", p),
                          String.Format("Add declaration of ontology property '{0}' to the property model.", p.TaxonomySubject)
                     ));
                }
                if (!ontology.Model.PropertyModel.Properties.ContainsKey(p.TaxonomyObject.Value.PatternMemberID)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                         "Vocabulary_Declaration",
                         String.Format("Declaration of ontology property '{0}' is not found in the property model: it is required by a 'rdfs:subpropertyOf' relation.", p),
                         String.Format("Add declaration of ontology property '{0}' to the property model.", p.TaxonomyObject)
                     ));
                }
            }

            //EquivalentProperty
            foreach (var   p in ontology.Model.PropertyModel.Relations.EquivalentProperty) {
                if  (!ontology.Model.PropertyModel.Properties.ContainsKey(p.TaxonomySubject.Value.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology property '{0}' is not found in the property model: it is required by an 'owl:EquivalentProperty' relation.", p),
                          String.Format("Add declaration of ontology property '{0}' to the property model.", p.TaxonomySubject)
                     ));
                }
                if (!ontology.Model.PropertyModel.Properties.ContainsKey(p.TaxonomyObject.Value.PatternMemberID)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                         "Vocabulary_Declaration",
                         String.Format("Declaration of ontology property '{0}' is not found in the property model: it is required by an 'owl:EquivalentProperty' relation.", p),
                         String.Format("Add declaration of ontology property '{0}' to the property model.", p.TaxonomyObject)
                     ));
                }
            }

            //InverseOf
            foreach (var   p in ontology.Model.PropertyModel.Relations.InverseOf) {
                if (!ontology.Model.PropertyModel.Properties.ContainsKey(p.TaxonomySubject.Value.PatternMemberID)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                         "Vocabulary_Declaration",
                         String.Format("Declaration of ontology property '{0}' is not found in the property model: it is required by an 'owl:InverseOf' relation.", p),
                         String.Format("Add declaration of ontology property '{0}' to the property model.", p.TaxonomySubject)
                     ));
                }
                if (!ontology.Model.PropertyModel.Properties.ContainsKey(p.TaxonomyObject.Value.PatternMemberID)) {
                     report.AddEvidence(new RDFOntologyValidationEvidence(
                         RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                         "Vocabulary_Declaration",
                         String.Format("Declaration of ontology property '{0}' is not found in the property model: it is required by an 'owl:InverseOf' relation.", p),
                         String.Format("Add declaration of ontology property '{0}' to the property model.", p.TaxonomyObject)
                     ));
                }
            }

            #endregion

            #region Facts

            //ClassType
            foreach (var f in ontology.Data.Relations.ClassType) {
                if  (!ontology.Data.Facts.ContainsKey(f.TaxonomySubject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology fact '{0}' is not found in the data: it is required by a 'rdf:type' relation.", f.TaxonomySubject),
                          String.Format("Add declaration of ontology fact '{0}' to the data.", f.TaxonomySubject)
                      ));
                }
                if  (!ontology.Model.ClassModel.Classes.ContainsKey(f.TaxonomyObject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology class '{0}' is not found in the class model: it is required by a 'rdf:type' relation.", f.TaxonomyObject),
                          String.Format("Add declaration of ontology class '{0}' to the class model.", f.TaxonomyObject)
                      ));
                }
            }
            foreach (var f in ontology.Data.Where(fact => ontology.Data.Relations.ClassType.SelectEntriesBySubject(fact).EntriesCount == 0)) {
                report.AddEvidence(new RDFOntologyValidationEvidence(
                    RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Error,
                    "Vocabulary_Declaration",
                    String.Format("Ontology fact '{0}' is found in the data, but it does not have classtype definitions.", f),
                    String.Format("Add at least one classtype definition for ontology fact '{0}' to the data.", f)
                ));
            }

            //SameAs
            foreach (var f in ontology.Data.Relations.SameAs) {
                if  (!ontology.Data.Facts.ContainsKey(f.TaxonomySubject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology fact '{0}' is not found in the data: it is required by a 'owl:sameAs' relation.", f.TaxonomySubject),
                          String.Format("Add declaration of ontology fact '{0}' to the data.", f.TaxonomySubject)
                      ));
                }
                if  (!ontology.Data.Facts.ContainsKey(f.TaxonomyObject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology fact '{0}' is not found in the data: it is required by a 'owl:sameAs' relation.", f.TaxonomyObject),
                          String.Format("Add declaration of ontology fact '{0}' to the data.", f.TaxonomyObject)
                      ));
                }
            }

            //DifferentFrom
            foreach (var f in ontology.Data.Relations.DifferentFrom) {
                if  (!ontology.Data.Facts.ContainsKey(f.TaxonomySubject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology fact '{0}' is not found in the data: it is required by a 'owl:differentFrom' relation.", f.TaxonomySubject),
                          String.Format("Add declaration of ontology fact '{0}' to the data.", f.TaxonomySubject)
                      ));
                }
                if  (!ontology.Data.Facts.ContainsKey(f.TaxonomyObject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology fact '{0}' is not found in the data: it is required by a 'owl:differentFrom' relation.", f.TaxonomyObject),
                          String.Format("Add declaration of ontology fact '{0}' to the data.", f.TaxonomyObject)
                      ));
                }
            }

            //Assertions
            foreach (var f in ontology.Data.Relations.Assertions) {
                if  (!ontology.Data.Facts.ContainsKey(f.TaxonomySubject.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology fact '{0}' is not found in the data: it is required by an assertion relation.", f.TaxonomySubject),
                          String.Format("Add declaration of ontology fact '{0}' to the data.", f.TaxonomySubject)
                      ));
                }
                if  (!ontology.Model.PropertyModel.Properties.ContainsKey(f.TaxonomyPredicate.PatternMemberID)) {
                      report.AddEvidence(new RDFOntologyValidationEvidence(
                          RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                          "Vocabulary_Declaration",
                          String.Format("Declaration of ontology property '{0}' is not found in the property model: it is required by an assertion relation.", f.TaxonomyPredicate),
                          String.Format("Add declaration of ontology property '{0}' to the property model.", f.TaxonomyPredicate)
                      ));
                }
                if  (f.TaxonomyPredicate.IsObjectProperty()) {
                     if (!ontology.Data.Facts.ContainsKey(f.TaxonomyObject.PatternMemberID)) {
                          report.AddEvidence(new RDFOntologyValidationEvidence(
                              RDFSemanticsEnums.RDFOntologyValidationEvidenceCategory.Warning,
                              "Vocabulary_Declaration",
                              String.Format("Declaration of ontology fact '{0}' is not found in the data: it is required by an assertion relation.", f.TaxonomyObject),
                              String.Format("Add declaration of ontology fact '{0}' to the data.", f.TaxonomyObject)
                          ));
                     }
                }
            }

            #endregion

            RDFSemanticsEvents.RaiseSemanticsInfo("Completed execution of validation rule 'Vocabulary_Declaration'");
        }
        /// <summary>
        /// Analyzes the given ontology and produces a detailed report of found evidences
        /// </summary>
        internal RDFOntologyValidationReport AnalyzeOntology(RDFOntology ontology) {
            var report = new RDFOntologyValidationReport(ontology.Value.PatternMemberID);

            //Execute the validation rules
            Parallel.ForEach(this.Rules, rule => {
                rule.ExecuteRule(ontology, report);
            });

            return report;
        }