/// <summary> /// Enlists the facts which are members of the given class within the given ontology /// </summary> internal static RDFOntologyData EnlistMembersOfClass(RDFOntologyClass ontClass, RDFOntology ontology) { var result = new RDFOntologyData(); //DataRange / Literal if (ontClass.IsDataRangeClass() || ontClass.Equals(RDFOntologyVocabulary.Classes.LITERAL) || RDFOntologyReasoningHelper.IsSubClassOf(ontClass, RDFOntologyVocabulary.Classes.LITERAL, ontology.Model.ClassModel) || RDFOntologyReasoningHelper.IsEquivalentClassOf(ontClass, RDFOntologyVocabulary.Classes.LITERAL, ontology.Model.ClassModel)) { //DataRange if (ontClass.IsDataRangeClass()) { result = RDFSemanticsUtilities.EnlistMembersOfDataRange((RDFOntologyDataRangeClass)ontClass, ontology); } //Literal else { //Pure Literal if (ontClass.Equals(RDFOntologyVocabulary.Classes.LITERAL) || RDFOntologyReasoningHelper.IsEquivalentClassOf(ontClass, RDFOntologyVocabulary.Classes.LITERAL, ontology.Model.ClassModel)) { foreach (var ontLit in ontology.Data.Literals.Values) { result.AddLiteral(ontLit); } } //Derived Literal else { //String-Literals var xsdStringClass = ontology.Model.ClassModel.SelectClass(RDFVocabulary.XSD.STRING.ToString()); if (ontClass.Equals(xsdStringClass) || RDFOntologyReasoningHelper.IsEquivalentClassOf(ontClass, xsdStringClass, ontology.Model.ClassModel)) { foreach (var ontLit in ontology.Data.Literals.Values) { if (ontLit.Value is RDFPlainLiteral) { result.AddLiteral(ontLit); } else { var dTypeClass = ontology.Model.ClassModel.SelectClass(((RDFTypedLiteral)ontLit.Value).Datatype.ToString()); if (dTypeClass != null) { if (dTypeClass.Equals(ontClass) || RDFOntologyReasoningHelper.IsSubClassOf(dTypeClass, ontClass, ontology.Model.ClassModel) || RDFOntologyReasoningHelper.IsEquivalentClassOf(dTypeClass, ontClass, ontology.Model.ClassModel)) { result.AddLiteral(ontLit); } } else { if (dTypeClass.Equals(ontClass)) { result.AddLiteral(ontLit); } } } } } //Other Literals else { foreach (var ontLit in ontology.Data.Literals.Values.Where(l => l.Value is RDFTypedLiteral)) { var dTypeClass = ontology.Model.ClassModel.SelectClass(((RDFTypedLiteral)ontLit.Value).Datatype.ToString()); if (dTypeClass != null) { if (dTypeClass.Equals(ontClass) || RDFOntologyReasoningHelper.IsSubClassOf(dTypeClass, ontClass, ontology.Model.ClassModel) || RDFOntologyReasoningHelper.IsEquivalentClassOf(dTypeClass, ontClass, ontology.Model.ClassModel)) { result.AddLiteral(ontLit); } } else { if (dTypeClass.Equals(ontClass)) { result.AddLiteral(ontLit); } } } } } } } //Composite else if (ontClass.IsCompositeClass()) { result = RDFSemanticsUtilities.EnlistMembersOfComposite(ontClass, ontology); } //Enumerate else if (ontClass.IsEnumerateClass()) { result = RDFSemanticsUtilities.EnlistMembersOfEnumerate((RDFOntologyEnumerateClass)ontClass, ontology); } //Class else { //Get the compatible classes var compCls = RDFOntologyReasoningHelper.EnlistSubClassesOf(ontClass, ontology.Model.ClassModel) .UnionWith(RDFOntologyReasoningHelper.EnlistEquivalentClassesOf(ontClass, ontology.Model.ClassModel)) .AddClass(ontClass); //Filter "classType" relations made with compatible classes var fTaxonomy = new RDFOntologyTaxonomy(); foreach (var c in compCls) { fTaxonomy = fTaxonomy.UnionWith(ontology.Data.Relations.ClassType.SelectEntriesByObject(c)); } foreach (var tEntry in fTaxonomy) { //Add the fact and its synonyms if (tEntry.TaxonomySubject.IsFact()) { result = result.UnionWith(RDFOntologyReasoningHelper.EnlistSameFactsAs((RDFOntologyFact)tEntry.TaxonomySubject, ontology.Data)) .AddFact((RDFOntologyFact)tEntry.TaxonomySubject); } } } return result; }
/// <summary> /// Enlists the facts which are members of the given restriction within the given ontology /// </summary> internal static RDFOntologyData EnlistMembersOfRestriction(RDFOntologyRestriction ontRestriction, RDFOntology ontology) { var result = new RDFOntologyData(); //Enlist the properties which are compatible with the restriction's "OnProperty" var compProps = RDFOntologyReasoningHelper.EnlistSubPropertiesOf(ontRestriction.OnProperty, ontology.Model.PropertyModel) .UnionWith(RDFOntologyReasoningHelper.EnlistEquivalentPropertiesOf(ontRestriction.OnProperty, ontology.Model.PropertyModel)) .AddProperty(ontRestriction.OnProperty); //Filter assertions made with enlisted compatible properties var fTaxonomy = new RDFOntologyTaxonomy(); foreach (var p in compProps) { fTaxonomy = fTaxonomy.UnionWith(ontology.Data.Relations.Assertions.SelectEntriesByPredicate(p)); } #region Cardinality if (ontRestriction is RDFOntologyCardinalityRestriction) { //Item2 is a counter for occurrences of the restricted property within the subject fact var fCount = new Dictionary<Int64, Tuple<RDFOntologyFact, Int64>>(); //Iterate the compatible assertions foreach (var tEntry in fTaxonomy) { if (!fCount.ContainsKey(tEntry.TaxonomySubject.PatternMemberID)) { fCount.Add(tEntry.TaxonomySubject.PatternMemberID, new Tuple<RDFOntologyFact, Int64>((RDFOntologyFact)tEntry.TaxonomySubject, 1)); } else { var occurrencyCounter = fCount[tEntry.TaxonomySubject.PatternMemberID].Item2; fCount[tEntry.TaxonomySubject.PatternMemberID] = new Tuple<RDFOntologyFact, Int64>((RDFOntologyFact)tEntry.TaxonomySubject, occurrencyCounter + 1); } } //Apply the cardinality restriction on the tracked facts var fCountEnum = fCount.Values.GetEnumerator(); while (fCountEnum.MoveNext()) { var passesMinCardinality = true; var passesMaxCardinality = true; //MinCardinality: signal tracked facts having "#occurrences < MinCardinality" if (((RDFOntologyCardinalityRestriction)ontRestriction).MinCardinality > 0) { if (fCountEnum.Current.Item2 < ((RDFOntologyCardinalityRestriction)ontRestriction).MinCardinality) { passesMinCardinality = false; } } //MaxCardinality: signal tracked facts having "#occurrences > MaxCardinality" if (((RDFOntologyCardinalityRestriction)ontRestriction).MaxCardinality > 0) { if (fCountEnum.Current.Item2 > ((RDFOntologyCardinalityRestriction)ontRestriction).MaxCardinality) { passesMaxCardinality = false; } } //Save the candidate fact if it passes cardinality restrictions if (passesMinCardinality && passesMaxCardinality) { result.AddFact(fCountEnum.Current.Item1); } } } #endregion #region AllValuesFrom else if (ontRestriction is RDFOntologyAllValuesFromRestriction) { //Item2 is a counter for occurrences of the restricted property with a range member of the restricted "FromClass" //Item3 is a counter for occurrences of the restricted property with a range member not of the restricted "FromClass" var fCount = new Dictionary<Int64, Tuple<RDFOntologyFact, Int64, Int64>>(); //Enlist the classes which are compatible with the restricted "FromClass" var compClasses = RDFOntologyReasoningHelper.EnlistSubClassesOf(((RDFOntologyAllValuesFromRestriction)ontRestriction).FromClass, ontology.Model.ClassModel) .UnionWith(RDFOntologyReasoningHelper.EnlistEquivalentClassesOf(((RDFOntologyAllValuesFromRestriction)ontRestriction).FromClass, ontology.Model.ClassModel)) .AddClass(((RDFOntologyAllValuesFromRestriction)ontRestriction).FromClass); //Iterate the compatible assertions foreach (var tEntry in fTaxonomy) { //Initialize the occurrence counters of the subject fact if (!fCount.ContainsKey(tEntry.TaxonomySubject.PatternMemberID)) { fCount.Add(tEntry.TaxonomySubject.PatternMemberID, new Tuple<RDFOntologyFact, Int64, Int64>((RDFOntologyFact)tEntry.TaxonomySubject, 0, 0)); } //Iterate the class types of the object fact, checking presence of the restricted "FromClass" var fromClassFound = false; var objFactClassTypes = ontology.Data.Relations.ClassType.SelectEntriesBySubject(tEntry.TaxonomyObject); foreach (var objFactClassType in objFactClassTypes) { var compObjFactClassTypes = RDFOntologyReasoningHelper.EnlistSubClassesOf((RDFOntologyClass)objFactClassType.TaxonomyObject, ontology.Model.ClassModel) .UnionWith(RDFOntologyReasoningHelper.EnlistEquivalentClassesOf((RDFOntologyClass)objFactClassType.TaxonomyObject, ontology.Model.ClassModel)) .AddClass((RDFOntologyClass)objFactClassType.TaxonomyObject); if (compObjFactClassTypes.IntersectWith(compClasses).ClassesCount > 0) { fromClassFound = true; break; } } //Update the occurrence counters of the subject fact var equalityCounter = fCount[tEntry.TaxonomySubject.PatternMemberID].Item2; var differenceCounter = fCount[tEntry.TaxonomySubject.PatternMemberID].Item3; if (fromClassFound) { fCount[tEntry.TaxonomySubject.PatternMemberID] = new Tuple<RDFOntologyFact, Int64, Int64>((RDFOntologyFact)tEntry.TaxonomySubject, equalityCounter + 1, differenceCounter); } else { fCount[tEntry.TaxonomySubject.PatternMemberID] = new Tuple<RDFOntologyFact, Int64, Int64>((RDFOntologyFact)tEntry.TaxonomySubject, equalityCounter, differenceCounter + 1); } } //Apply the restriction on the subject facts var fCountEnum = fCount.Values.GetEnumerator(); while (fCountEnum.MoveNext()) { if (fCountEnum.Current.Item2 >= 1 && fCountEnum.Current.Item3 == 0) { result.AddFact(fCountEnum.Current.Item1); } } } #endregion #region SomeValuesFrom else if (ontRestriction is RDFOntologySomeValuesFromRestriction) { //Item2 is a counter for occurrences of the restricted property with a range member of the restricted "FromClass" //Item3 is a counter for occurrences of the restricted property with a range member not of the restricted "FromClass" var fCount = new Dictionary<Int64, Tuple<RDFOntologyFact, Int64, Int64>>(); //Enlist the classes which are compatible with the restricted "FromClass" var compClasses = RDFOntologyReasoningHelper.EnlistSubClassesOf(((RDFOntologySomeValuesFromRestriction)ontRestriction).FromClass, ontology.Model.ClassModel) .UnionWith(RDFOntologyReasoningHelper.EnlistEquivalentClassesOf(((RDFOntologySomeValuesFromRestriction)ontRestriction).FromClass, ontology.Model.ClassModel)) .AddClass(((RDFOntologySomeValuesFromRestriction)ontRestriction).FromClass); //Iterate the compatible assertions foreach (var tEntry in fTaxonomy) { //Initialize the occurrence counters of the subject fact if (!fCount.ContainsKey(tEntry.TaxonomySubject.PatternMemberID)) { fCount.Add(tEntry.TaxonomySubject.PatternMemberID, new Tuple<RDFOntologyFact, Int64, Int64>((RDFOntologyFact)tEntry.TaxonomySubject, 0, 0)); } //Iterate the class types of the object fact, checking presence of the restricted "FromClass" var fromClassFound = false; var objFactClassTypes = ontology.Data.Relations.ClassType.SelectEntriesBySubject(tEntry.TaxonomyObject); foreach (var objFactClassType in objFactClassTypes) { var compObjFactClassTypes = RDFOntologyReasoningHelper.EnlistSubClassesOf((RDFOntologyClass)objFactClassType.TaxonomyObject, ontology.Model.ClassModel) .UnionWith(RDFOntologyReasoningHelper.EnlistEquivalentClassesOf((RDFOntologyClass)objFactClassType.TaxonomyObject, ontology.Model.ClassModel)) .AddClass((RDFOntologyClass)objFactClassType.TaxonomyObject); if (compObjFactClassTypes.IntersectWith(compClasses).ClassesCount > 0) { fromClassFound = true; break; } } //Update the occurrence counters of the subject fact var equalityCounter = fCount[tEntry.TaxonomySubject.PatternMemberID].Item2; var differenceCounter = fCount[tEntry.TaxonomySubject.PatternMemberID].Item3; if (fromClassFound) { fCount[tEntry.TaxonomySubject.PatternMemberID] = new Tuple<RDFOntologyFact, Int64, Int64>((RDFOntologyFact)tEntry.TaxonomySubject, equalityCounter + 1, differenceCounter); } else { fCount[tEntry.TaxonomySubject.PatternMemberID] = new Tuple<RDFOntologyFact, Int64, Int64>((RDFOntologyFact)tEntry.TaxonomySubject, equalityCounter, differenceCounter + 1); } } //Apply the restriction on the subject facts var fCountEnum = fCount.Values.GetEnumerator(); while (fCountEnum.MoveNext()) { if (fCountEnum.Current.Item2 >= 1) { result.AddFact(fCountEnum.Current.Item1); } } } #endregion #region HasValue else if (ontRestriction is RDFOntologyHasValueRestriction) { if (((RDFOntologyHasValueRestriction)ontRestriction).RequiredValue.IsFact()) { //Enlist the same facts of the restriction's "RequiredValue" var compFacts = RDFOntologyReasoningHelper.EnlistSameFactsAs((RDFOntologyFact)((RDFOntologyHasValueRestriction)ontRestriction).RequiredValue, ontology.Data) .AddFact((RDFOntologyFact)((RDFOntologyHasValueRestriction)ontRestriction).RequiredValue); //Iterate the compatible assertions foreach (var tEntry in fTaxonomy) { if (tEntry.TaxonomyObject.IsFact()) { if (compFacts.SelectFact(tEntry.TaxonomyObject.ToString()) != null) { result.AddFact((RDFOntologyFact)tEntry.TaxonomyObject); } } } } else if (((RDFOntologyHasValueRestriction)ontRestriction).RequiredValue.IsLiteral()) { //Iterate the compatible assertions and track the occurrence informations foreach (var tEntry in fTaxonomy) { if (tEntry.TaxonomyObject.IsLiteral()) { try { var semanticLiteralsCompare = RDFQueryUtilities.CompareRDFPatternMembers(((RDFOntologyHasValueRestriction)ontRestriction).RequiredValue.Value, tEntry.TaxonomyObject.Value); if (semanticLiteralsCompare == 0) { result.AddFact((RDFOntologyFact)tEntry.TaxonomySubject); } } finally { } } } } } #endregion return result; }