001/** 002 * Copyright (C) 2007 - 2016, 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 */ 019package org.dllearner.utilities; 020 021import com.google.common.collect.Sets; 022import org.dllearner.core.AbstractReasonerComponent; 023import org.dllearner.core.ComponentInitException; 024import org.dllearner.reasoning.SPARQLReasoner; 025import org.dllearner.utilities.datastructures.SortedSetTuple; 026import org.semanticweb.owlapi.model.*; 027import org.slf4j.Logger; 028import org.slf4j.LoggerFactory; 029import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl; 030 031import java.util.*; 032import java.util.stream.Collectors; 033 034/** 035 * TODO: JavaDoc 036 * 037 * @author Jens Lehmann 038 * 039 */ 040public class Helper { 041 042 private static Logger logger = LoggerFactory.getLogger(Helper.class); 043 private static final OWLDataFactory df = new OWLDataFactoryImpl(); 044 045 public static String prettyPrintNanoSeconds(long nanoSeconds) { 046 return prettyPrintNanoSeconds(nanoSeconds, false, false); 047 } 048 049 // formatiert Nano-Sekunden in einen leserlichen String 050 public static String prettyPrintNanoSeconds(long nanoSeconds, boolean printMicros, 051 boolean printNanos) { 052 // String str = ""; 053 // long seconds = 0; 054 // long milliSeconds = 0; 055 // long microseconds = 0; 056 057 long seconds = nanoSeconds / 1000000000; 058 nanoSeconds = nanoSeconds % 1000000000; 059 060 long milliSeconds = nanoSeconds / 1000000; 061 nanoSeconds = nanoSeconds % 1000000; 062 063 // Mikrosekunden werden immer angezeigt, Sekunden nur falls gröÃer 0 064 String str = ""; 065 if (seconds > 0) 066 str = seconds + "s "; 067 str += milliSeconds + "ms"; 068 069 if (printMicros) { 070 long microSeconds = nanoSeconds / 1000; 071 nanoSeconds = nanoSeconds % 1000; 072 str += " " + microSeconds + "usec"; 073 } 074 if (printNanos) { 075 str += " " + nanoSeconds + "ns"; 076 } 077 078 return str; 079 } 080 081 public static String prettyPrintMilliSeconds(long milliSeconds) { 082 083 084 long seconds = milliSeconds / 1000; 085 milliSeconds = milliSeconds % 1000; 086 087 // Mikrosekunden werden immer angezeigt, Sekunden nur falls gröÃer 0 088 String str = ""; 089 if (seconds > 0) 090 str = seconds + "s "; 091 str += milliSeconds + "ms"; 092 093 return str; 094 } 095 096 public static <T> Set<T> intersectionTuple(Set<T> set, SortedSetTuple<T> tuple) { 097 Set<T> ret = Sets.intersection(set, tuple.getPosSet()); 098 ret.retainAll(tuple.getNegSet()); 099 return ret; 100 } 101 102 // Umwandlung von Menge von Individuals auf Menge von Strings 103 public static SortedSet<OWLIndividual> getIndividualSet(Collection<String> individuals) { 104 return individuals.stream() 105 .map(s -> df.getOWLNamedIndividual(IRI.create(s))) 106 .collect(Collectors.toCollection(TreeSet::new)); 107 } 108 109 public static SortedSetTuple<OWLIndividual> getIndividualTuple(SortedSetTuple<String> tuple) { 110 return new SortedSetTuple<>(getIndividualSet(tuple.getPosSet()), 111 getIndividualSet(tuple.getNegSet())); 112 } 113 114 public static SortedSetTuple<String> getStringTuple(SortedSetTuple<OWLIndividual> tuple) { 115 return new SortedSetTuple<>(getStringSet(tuple.getPosSet()), getStringSet(tuple 116 .getNegSet())); 117 } 118 119 // Umwandlung von Menge von Individuals auf Menge von Strings 120 public static SortedSet<String> getStringSet(Collection<OWLIndividual> individuals) { 121 return individuals.stream(). 122 map(OWLIndividual::toStringID). 123 collect(Collectors.toCollection(TreeSet::new)); 124 } 125 126 public static Map<String, SortedSet<String>> getStringMap( 127 Map<OWLIndividual, SortedSet<OWLIndividual>> roleMembers) { 128 Map<String, SortedSet<String>> ret = new TreeMap<>(); 129 for (OWLIndividual i : roleMembers.keySet()) { 130 ret.put(i.toStringID(), getStringSet(roleMembers.get(i))); 131 } 132 return ret; 133 } 134 135 // concepts case 1: no ignore or allowed list 136 @SuppressWarnings("unchecked") 137 public static <T extends OWLEntity> Set<T> computeEntities(AbstractReasonerComponent rs, EntityType<T> entityType) { 138 // if there is no ignore or allowed list, we just ignore the concepts 139 // of uninteresting namespaces 140 if (entityType == EntityType.CLASS) { 141 return (Set<T>) rs.getClasses(); 142 } else if (entityType == EntityType.OBJECT_PROPERTY) { 143 return (Set<T>) rs.getObjectProperties(); 144 } else if (entityType == EntityType.DATA_PROPERTY) { 145 return (Set<T>) rs.getDatatypeProperties(); 146 } 147 return null; 148 } 149 150 // concepts case 1: no ignore or allowed list 151 public static Set<OWLClass> computeConcepts(AbstractReasonerComponent rs) { 152 // if there is no ignore or allowed list, we just ignore the concepts 153 // of uninteresting namespaces 154 Set<OWLClass> concepts = rs.getClasses(); 155// Helper.removeUninterestingConcepts(concepts); 156 return concepts; 157 } 158 159 @SuppressWarnings("unchecked") 160 public static <T extends OWLEntity> Set<T> computeEntitiesUsingIgnoreList(AbstractReasonerComponent rs, EntityType<T> entityType, Set<T> ignoredEntites) { 161 Set<T> entities; 162 163 if (entityType == EntityType.CLASS) { 164 entities = (Set<T>) rs.getClasses(); 165 } else if (entityType == EntityType.OBJECT_PROPERTY) { 166 entities = (Set<T>) rs.getObjectProperties(); 167 } else if (entityType == EntityType.DATA_PROPERTY) { 168 entities = (Set<T>) rs.getDatatypeProperties(); 169 } else { 170 throw new UnsupportedOperationException("Entity type " + entityType + " currently not supported."); 171 } 172 173 entities = new TreeSet<>(entities); 174 175 for (T entity : ignoredEntites) { 176 boolean success = entities.remove(entity); 177 if (!success) { 178 logger.warn("Warning: Ignored entity " + entity + " does not exist in knowledge base."); 179 } 180 } 181 return entities; 182 } 183 184 // concepts case 2: ignore list 185 public static Set<OWLClass> computeConceptsUsingIgnoreList(AbstractReasonerComponent rs, Set<OWLClass> ignoredConcepts) { 186 Set<OWLClass> concepts = new TreeSet<>(rs.getClasses()); 187// Helper.removeUninterestingConcepts(concepts); 188 for (OWLClass ac : ignoredConcepts) { 189 boolean success = concepts.remove(ac); 190 if (!success) 191 logger.warn("Warning: Ignored concept " + ac + " does not exist in knowledge base."); 192 } 193 return concepts; 194 } 195 196 /** 197 * Checks whether the roles exist in background knowledge 198 * @param roles The roles to check. 199 * @return The first non-existing role or null if they are all in the 200 * background knowledge. 201 */ 202 // 203 public static OWLObjectProperty checkRoles(AbstractReasonerComponent rs, Set<OWLObjectProperty> roles) { 204 Set<OWLObjectProperty> existingRoles = rs.getObjectProperties(); 205 for (OWLObjectProperty ar : roles) { 206 if(!existingRoles.contains(ar)) 207 return ar; 208 } 209 return null; 210 } 211 212 /** 213 * Checks whether the entities exist in background knowledge 214 * @param entities The entities to check. 215 * @return The first non-existing entity or null if they are all in the 216 * background knowledge. 217 */ 218 public static <T extends OWLEntity> T checkEntities(AbstractReasonerComponent rs, Set<T> entities) { 219 Set<T> existingEntities = (Set<T>) computeEntities(rs, entities.iterator().next().getEntityType()); 220 for (T entity : entities) { 221 if(!existingEntities.contains(entity)) 222 return entity; 223 } 224 return null; 225 } 226 227 /** 228 * Checks whether the roles exist in background knowledge 229 * @param concepts The concepts to check. 230 * @return The first non-existing role or null if they are all in the 231 * background knowledge. 232 */ 233 // 234 public static OWLClass checkConcepts(AbstractReasonerComponent rs, Set<OWLClass> concepts) { 235 Set<OWLClass> existingConcepts = rs.getClasses(); 236 for (OWLClass ar : concepts) { 237 if(!existingConcepts.contains(ar)) 238 return ar; 239 } 240 return null; 241 } 242 243 /** 244 * Checks whether all entities in the given class expression do also occur in the knowledge base. 245 * 246 * @param ce The concept to check. 247 * @return {@code true} if all entities of the class expression occur in the knowledge base, 248 * otherwise {@code false} 249 */ 250 public static boolean checkConceptEntities(AbstractReasonerComponent rc, OWLClassExpression ce) { 251 return rc.getClasses().containsAll(ce.getClassesInSignature()) && 252 rc.getObjectProperties().containsAll(ce.getObjectPropertiesInSignature()) && 253 rc.getDatatypeProperties().containsAll(ce.getDataPropertiesInSignature()); 254 255 } 256 257 public static void checkIndividuals(AbstractReasonerComponent reasoner, Set<OWLIndividual> individuals) throws ComponentInitException { 258 if (!(reasoner instanceof SPARQLReasoner)) { 259 SortedSet<OWLIndividual> allIndividuals = reasoner.getIndividuals(); 260 261 if (!allIndividuals.containsAll(individuals)) { 262 Set<OWLIndividual> missing = Sets.difference(individuals, allIndividuals); 263 double percentage = (double) missing.size() / individuals.size(); 264 percentage = Math.round(percentage * 1000.0) / 1000.0; 265 String str = "The examples (" + (percentage * 100) + " % of total) below are not contained in the knowledge base " + 266 "(check spelling and prefixes)\n"; 267 str += missing.toString(); 268 if (missing.size() == individuals.size()) { 269 throw new ComponentInitException(str); 270 } 271 if (percentage < 0.10) { 272 logger.warn(str); 273 } else { 274 logger.error(str); 275 } 276 } 277 } 278 } 279 280 public static void displayProgressPercentage(int done, int total) { 281 int size = 5; 282 String iconLeftBoundary = "["; 283 String iconDone = "="; 284 String iconRemain = "."; 285 String iconRightBoundary = "]"; 286 287 if (done > total) { 288 throw new IllegalArgumentException(); 289 } 290 int donePercents = (100 * done) / total; 291 int doneLength = size * donePercents / 100; 292 293 StringBuilder bar = new StringBuilder(iconLeftBoundary); 294 for (int i = 0; i < size; i++) { 295 if (i < doneLength) { 296 bar.append(iconDone); 297 } else { 298 bar.append(iconRemain); 299 } 300 } 301 bar.append(iconRightBoundary); 302 303 System.out.print("\r" + bar + " " + donePercents + "%"); 304 305 if (done == total) { 306 System.out.print("\n"); 307 } 308 } 309 310}