/// <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> /// Subsumes the "owl:equivalentClass" taxonomy to discover direct and indirect equivalentClasses of the given class /// </summary> internal static RDFOntologyClassModel EnlistEquivalentClassesOf_Core(RDFOntologyClass ontClass, RDFOntologyClassModel classModel, Dictionary<Int64, RDFOntologyClass> visitContext) { var result = new RDFOntologyClassModel(); #region visitContext if (visitContext == null) { visitContext = new Dictionary<Int64, RDFOntologyClass>() { { ontClass.PatternMemberID, ontClass } }; } else { if (!visitContext.ContainsKey(ontClass.PatternMemberID)) { visitContext.Add(ontClass.PatternMemberID, ontClass); } else { return result; } } #endregion // Transitivity of "owl:equivalentClass" taxonomy: ((A EQUIVALENTCLASSOF B) && (B EQUIVALENTCLASS C)) => (A EQUIVALENTCLASS C) foreach (var ec in classModel.Relations.EquivalentClass.SelectEntriesBySubject(ontClass)) { result.AddClass((RDFOntologyClass)ec.TaxonomyObject); result = result.UnionWith(RDFSemanticsUtilities.EnlistEquivalentClassesOf_Core((RDFOntologyClass)ec.TaxonomyObject, classModel, visitContext)); } return result; }
internal static RDFOntologyClassModel EnlistDisjointClassesWith_Core(RDFOntologyClass ontClass, RDFOntologyClassModel classModel, Dictionary<Int64, RDFOntologyClass> visitContext) { var result1 = new RDFOntologyClassModel(); var result2 = new RDFOntologyClassModel(); #region visitContext if (visitContext == null) { visitContext = new Dictionary<Int64, RDFOntologyClass>() { { ontClass.PatternMemberID, ontClass } }; } else { if (!visitContext.ContainsKey(ontClass.PatternMemberID)) { visitContext.Add(ontClass.PatternMemberID, ontClass); } else { return result1; } } #endregion // Inference: ((A DISJOINTWITH B) && (B EQUIVALENTCLASS C)) => (A DISJOINTWITH C) foreach (var dw in classModel.Relations.DisjointWith.SelectEntriesBySubject(ontClass)) { result1.AddClass((RDFOntologyClass)dw.TaxonomyObject); result1 = result1.UnionWith(RDFSemanticsUtilities.EnlistEquivalentClassesOf_Core((RDFOntologyClass)dw.TaxonomyObject, classModel, visitContext)); } // Inference: ((A DISJOINTWITH B) && (B SUPERCLASS C)) => (A DISJOINTWITH C) result2 = result2.UnionWith(result1); foreach (var c in result1) { result2 = result2.UnionWith(RDFSemanticsUtilities.EnlistSubClassesOf_Core(c, classModel)); } result1 = result1.UnionWith(result2); // Inference: ((A EQUIVALENTCLASS B || A SUBCLASSOF B) && (B DISJOINTWITH C)) => (A DISJOINTWITH C) var compatibleCls = RDFOntologyReasoningHelper.EnlistSuperClassesOf(ontClass, classModel) .UnionWith(RDFOntologyReasoningHelper.EnlistEquivalentClassesOf(ontClass, classModel)); foreach (var ec in compatibleCls) { result1 = result1.UnionWith(RDFSemanticsUtilities.EnlistDisjointClassesWith_Core(ec, classModel, visitContext)); } return result1; }
/// <summary> /// Subsumes the "rdfs:subClassOf" taxonomy to discover direct and indirect superClasses of the given class /// </summary> internal static RDFOntologyClassModel EnlistSuperClassesOf(RDFOntologyClass ontClass, RDFOntologyClassModel classModel) { var result = new RDFOntologyClassModel(); // Transitivity of "rdfs:subClassOf" taxonomy: ((A SUPERCLASSOF B) && (B SUPERCLASSOF C)) => (A SUPERCLASSOF C) foreach(var sc in classModel.Relations.SubClassOf.SelectEntriesBySubject(ontClass)) { result.AddClass((RDFOntologyClass)sc.TaxonomyObject); result = result.UnionWith(RDFSemanticsUtilities.EnlistSuperClassesOf((RDFOntologyClass)sc.TaxonomyObject, classModel)); } return result; }