001 /**
002 * Copyright (C) 2007-2011, Jens Lehmann
003 *
004 * This file is part of DL-Learner.
005 *
006 * DL-Learner is free software; you can redistribute it and/or modify
007 * it under the terms of the GNU General Public License as published by
008 * the Free Software Foundation; either version 3 of the License, or
009 * (at your option) any later version.
010 *
011 * DL-Learner is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014 * GNU General Public License for more details.
015 *
016 * You should have received a copy of the GNU General Public License
017 * along with this program. If not, see <http://www.gnu.org/licenses/>.
018 */
019
020 package org.dllearner.utilities.learn;
021
022 import java.util.Comparator;
023 import java.util.Iterator;
024 import java.util.Map;
025 import java.util.Set;
026 import java.util.TreeMap;
027 import java.util.TreeSet;
028 import java.util.Map.Entry;
029
030 import org.dllearner.core.AbstractReasonerComponent;
031 import org.dllearner.core.owl.Individual;
032 import org.dllearner.core.owl.NamedClass;
033 import org.dllearner.core.owl.ObjectProperty;
034
035 /**
036 * This class takes a reasoner and individuals as input and detects
037 * the relevant (wrt. a learning process) classes and properties
038 * at a certain distance of the examples.
039 *
040 * @author Jens Lehmann
041 *
042 */
043 public class UsedEntitiesDetection {
044
045 Comparator<Set<ObjectProperty>> keyComp = new Comparator<Set<ObjectProperty>>() {
046
047 @Override
048 public int compare(Set<ObjectProperty> key1, Set<ObjectProperty> key2) {
049 // first criterion: size of key
050 int sizeDiff = key1.size() - key2.size();
051 if(sizeDiff == 0) {
052 Iterator<ObjectProperty> it1 = key1.iterator();
053 Iterator<ObjectProperty> it2 = key2.iterator();
054 // compare elements one by one (assumes that both use the same
055 // ordering, which is the case)
056 while(it1.hasNext()) {
057 ObjectProperty prop1 = it1.next();
058 ObjectProperty prop2 = it2.next();
059 int comp = prop1.compareTo(prop2);
060 if(comp != 0) {
061 return comp;
062 }
063 }
064 // all elements of the set are equal
065 return 0;
066 } else {
067 return sizeDiff;
068 }
069 }
070
071 };
072
073 private Map<Set<ObjectProperty>,Set<NamedClass>> usedClasses;
074
075 private Map<Set<ObjectProperty>,Set<ObjectProperty>> usedObjectProperties;
076
077 private AbstractReasonerComponent reasoner;
078 private int maxDepth;
079
080 /**
081 * Computes used properties in classes.
082 * TODO more explanation
083 *
084 * @param reasoner A reasoner.
085 * @param individuals A set of individuals to start from.
086 * @param depth The maximum depth for the search.
087 */
088 public UsedEntitiesDetection(AbstractReasonerComponent reasoner, Set<Individual> individuals, int maxDepth) {
089 this.reasoner = reasoner;
090 this.maxDepth = maxDepth;
091 usedClasses = new TreeMap<Set<ObjectProperty>,Set<NamedClass>>(keyComp);
092 usedObjectProperties = new TreeMap<Set<ObjectProperty>,Set<ObjectProperty>>(keyComp);
093
094 Set<ObjectProperty> startKey = new TreeSet<ObjectProperty>();
095 computeUsedEntitiesRec(startKey, individuals);
096
097 }
098
099 private void computeUsedEntitiesRec(Set<ObjectProperty> key, Set<Individual> individuals) {
100 Set<NamedClass> types = new TreeSet<NamedClass>();
101 // Set<ObjectProperty> properties = new TreeSet<ObjectProperty>();
102 // we must use the object property comparator to avoid double occurences of properties
103 Map<ObjectProperty,Set<Individual>> relations = new TreeMap<ObjectProperty,Set<Individual>>();
104
105 for(Individual individual : individuals) {
106 // add all types
107 types.addAll(reasoner.getTypes(individual));
108
109 // compute outgoing properties
110 Map<ObjectProperty,Set<Individual>> map = reasoner.getObjectPropertyRelationships(individual);
111 for(Entry<ObjectProperty,Set<Individual>> entry : map.entrySet()) {
112 ObjectProperty prop = entry.getKey();
113 // we must use the individual comparator to avoid
114 // multiple occurrences of the same individual
115 Set<Individual> inds = new TreeSet<Individual>(entry.getValue());
116
117 // if property exists, add the found individuals
118 if(relations.containsKey(prop)) {
119 relations.get(prop).addAll(inds);
120 // if property not encountered before, add it
121 } else {
122 relations.put(prop, inds);
123 }
124 }
125 }
126
127 // store all found relations
128 usedClasses.put(key, types);
129 usedObjectProperties.put(key, relations.keySet());
130
131 // recurse if limit not reached yet
132 if(key.size() < maxDepth) {
133 for(Entry<ObjectProperty,Set<Individual>> entry : relations.entrySet()) {
134 // construct new key (copy and add)
135 Set<ObjectProperty> newKey = new TreeSet<ObjectProperty>(key);
136 newKey.add(entry.getKey());
137
138 // recursion
139 computeUsedEntitiesRec(newKey, entry.getValue());
140 }
141 }
142
143 }
144
145 public Set<Set<ObjectProperty>> getKeys() {
146 return usedClasses.keySet();
147 }
148
149 /**
150 * @return the usedClasses
151 */
152 public Map<Set<ObjectProperty>, Set<NamedClass>> getUsedClasses() {
153 return usedClasses;
154 }
155
156 /**
157 * @return the usedObjectProperties
158 */
159 public Map<Set<ObjectProperty>, Set<ObjectProperty>> getUsedObjectProperties() {
160 return usedObjectProperties;
161 }
162
163 @Override
164 public String toString() {
165 String str = "";
166 Set<Set<ObjectProperty>> keys = getKeys();
167 for(Set<ObjectProperty> key : keys) {
168 str += key.toString() + ": \n";
169 str += " classes: " + usedClasses.get(key) + "\n";
170 str += " object properties: " + usedObjectProperties.get(key) + "\n";
171 }
172 return str;
173 }
174
175 }