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.reasoning; 020 021import com.clarkparsia.pellet.owlapiv3.PelletReasonerFactory; 022import org.dllearner.core.StringRenderer; 023import org.dllearner.core.StringRenderer.Rendering; 024import org.semanticweb.owlapi.apibinding.OWLManager; 025import org.semanticweb.owlapi.model.*; 026import org.semanticweb.owlapi.reasoner.OWLReasoner; 027import org.semanticweb.owlapi.reasoner.OWLReasonerFactory; 028import org.semanticweb.owlapi.search.EntitySearcher; 029import org.semanticweb.owlapi.util.OWLClassExpressionVisitorAdapter; 030 031import java.io.ByteArrayInputStream; 032import java.util.*; 033 034/** 035 * Materialize the existential restrictions, i.e. for all instances x_i that belong to a concept \exists.r.C, 036 * we add facts r(x_i, _:newID), C(_:newID), and this recursively. 037 * 038 * @author Lorenz Buehmann 039 * 040 */ 041public class ExistentialRestrictionMaterialization { 042 043 044 private OWLOntology ontology; 045 private OWLReasoner reasoner; 046 private OWLDataFactory df; 047 048 public ExistentialRestrictionMaterialization(OWLOntology ontology) { 049 this.ontology = ontology; 050 051 OWLReasonerFactory reasonerFactory = PelletReasonerFactory.getInstance(); 052 reasoner = reasonerFactory.createNonBufferingReasoner(ontology); 053 054 df = ontology.getOWLOntologyManager().getOWLDataFactory(); 055 } 056 057 private Set<OWLClassExpression> getSuperClasses(OWLClass cls){ 058 return new SuperClassFinder().getSuperClasses(cls); 059 } 060 061 public Set<OWLClassExpression> materialize(String classIRI){ 062 return materialize(df.getOWLClass(IRI.create(classIRI))); 063 } 064 065 public Set<OWLClassExpression> materialize(OWLClass cls){ 066 return getSuperClasses(cls); 067 } 068 069 class SuperClassFinder extends OWLClassExpressionVisitorAdapter{ 070 071 private Map<OWLClass, Set<OWLClassExpression>> map = new HashMap<>(); 072 Stack<Set<OWLClassExpression>> stack = new Stack<>(); 073 OWLDataFactory df; 074 boolean onlyIfExistentialOnPath = true; 075 076 int indent = 0; 077 078 public SuperClassFinder() { 079 df = ontology.getOWLOntologyManager().getOWLDataFactory(); 080 } 081 082 public Set<OWLClassExpression> getSuperClasses(OWLClass cls){ 083// System.out.println("#################"); 084 map.clear(); 085 computeSuperClasses(cls); 086 Set<OWLClassExpression> superClasses = map.get(cls); 087 superClasses.remove(cls); 088 089 // filter out non existential superclasses 090 if(onlyIfExistentialOnPath){ 091 superClasses.removeIf(sup -> !(sup instanceof OWLObjectSomeValuesFrom || sup instanceof OWLDataAllValuesFrom)); 092 } 093 return superClasses; 094 } 095 096 private void computeSuperClasses(OWLClass cls){ 097// StringBuilder s = new StringBuilder(); 098// for(int i = 0; i < indent; i++){ 099// s.append(" "); 100// } 101// System.out.println(s + cls); 102 indent++; 103 Set<OWLClassExpression> superClasses = new HashSet<>(); 104 superClasses.add(cls); 105 106 //get the directly asserted super classes 107 Collection<OWLClassExpression> superClassExpressions = EntitySearcher.getSuperClasses(cls, ontology); 108 109 //omit trivial super class 110 superClassExpressions.remove(cls); 111 112 //go subsumption hierarchy up for each directly asserted super class 113 for (OWLClassExpression sup : superClassExpressions) { 114 sup.accept(this); 115 superClasses.addAll(stack.pop()); 116 } 117 118 stack.push(superClasses); 119 map.put(cls, superClasses); 120 } 121 122 /* (non-Javadoc) 123 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLClass) 124 */ 125 @Override 126 public void visit(OWLClass ce) { 127 computeSuperClasses(ce); 128 } 129 130 /* (non-Javadoc) 131 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectIntersectionOf) 132 */ 133 @Override 134 public void visit(OWLObjectIntersectionOf ce) { 135 Set<OWLClassExpression> newIntersections = new HashSet<>(); 136 Set<OWLClassExpression> operands = ce.getOperands(); 137 for (OWLClassExpression op : operands) { 138 op.accept(this); 139 Set<OWLClassExpression> operandSuperClassExpressions = stack.pop(); 140 Set<OWLClassExpression> newOperands = new HashSet<>(operands); 141 newOperands.remove(op); 142 for (OWLClassExpression opSup : operandSuperClassExpressions) { 143 newOperands.add(opSup); 144 newIntersections.add(df.getOWLObjectIntersectionOf(newOperands)); 145 newOperands.remove(opSup); 146 } 147 } 148 stack.push(newIntersections); 149 } 150 151 /* (non-Javadoc) 152 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectUnionOf) 153 */ 154 @Override 155 public void visit(OWLObjectUnionOf ce) { 156 Set<OWLClassExpression> operands = ce.getOperands(); 157 for (OWLClassExpression op : operands) { 158 op.accept(this); 159 } 160 } 161 162 /* (non-Javadoc) 163 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectComplementOf) 164 */ 165 @Override 166 public void visit(OWLObjectComplementOf ce) { 167 } 168 169 /* (non-Javadoc) 170 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectSomeValuesFrom) 171 */ 172 @Override 173 public void visit(OWLObjectSomeValuesFrom ce) { 174 Set<OWLClassExpression> newRestrictions = new HashSet<>(); 175 newRestrictions.add(ce); 176 OWLClassExpression filler = ce.getFiller(); 177 filler.accept(this); 178 Set<OWLClassExpression> fillerSuperClassExpressions = stack.pop(); 179 for (OWLClassExpression fillerSup : fillerSuperClassExpressions) { 180 newRestrictions.add(df.getOWLObjectSomeValuesFrom(ce.getProperty(), fillerSup)); 181 } 182 stack.push(newRestrictions); 183 } 184 185 /* (non-Javadoc) 186 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectAllValuesFrom) 187 */ 188 @Override 189 public void visit(OWLObjectAllValuesFrom ce) { 190 } 191 192 /* (non-Javadoc) 193 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectHasValue) 194 */ 195 @Override 196 public void visit(OWLObjectHasValue ce) { 197 } 198 199 /* (non-Javadoc) 200 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectMinCardinality) 201 */ 202 @Override 203 public void visit(OWLObjectMinCardinality ce) { 204 } 205 206 /* (non-Javadoc) 207 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectExactCardinality) 208 */ 209 @Override 210 public void visit(OWLObjectExactCardinality ce) { 211 } 212 213 /* (non-Javadoc) 214 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectMaxCardinality) 215 */ 216 @Override 217 public void visit(OWLObjectMaxCardinality ce) { 218 } 219 220 /* (non-Javadoc) 221 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectHasSelf) 222 */ 223 @Override 224 public void visit(OWLObjectHasSelf ce) { 225 } 226 227 /* (non-Javadoc) 228 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLObjectOneOf) 229 */ 230 @Override 231 public void visit(OWLObjectOneOf ce) { 232 } 233 234 /* (non-Javadoc) 235 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLDataSomeValuesFrom) 236 */ 237 @Override 238 public void visit(OWLDataSomeValuesFrom ce) { 239 } 240 241 /* (non-Javadoc) 242 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLDataAllValuesFrom) 243 */ 244 @Override 245 public void visit(OWLDataAllValuesFrom ce) { 246 } 247 248 /* (non-Javadoc) 249 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLDataHasValue) 250 */ 251 @Override 252 public void visit(OWLDataHasValue ce) { 253 } 254 255 /* (non-Javadoc) 256 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLDataMinCardinality) 257 */ 258 @Override 259 public void visit(OWLDataMinCardinality ce) { 260 } 261 262 /* (non-Javadoc) 263 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLDataExactCardinality) 264 */ 265 @Override 266 public void visit(OWLDataExactCardinality ce) { 267 } 268 269 /* (non-Javadoc) 270 * @see org.semanticweb.owlapi.model.OWLClassExpressionVisitor#visit(org.semanticweb.owlapi.model.OWLDataMaxCardinality) 271 */ 272 @Override 273 public void visit(OWLDataMaxCardinality ce) { 274 } 275 } 276 277 278 public static void main(String[] args) throws Exception{ 279 StringRenderer.setRenderer(Rendering.DL_SYNTAX); 280 String s = "@prefix : <http://example.org/> ." 281 + "@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> ." 282 + "@prefix owl: <http://www.w3.org/2002/07/owl#> ." 283 + "@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> ." 284 + ":A a owl:Class . " 285 + ":B a owl:Class . " 286 + ":C a owl:Class . " 287 + ":D a owl:Class . " 288 + ":r a owl:ObjectProperty . " 289 + ":A rdfs:subClassOf [ a owl:Restriction; owl:onProperty :r; owl:someValuesFrom :B]." 290 + ":B rdfs:subClassOf :C." 291 + ":C rdfs:subClassOf [ a owl:Restriction; owl:onProperty :r; owl:someValuesFrom :D]." 292 + ":a a :A."; 293 294 OWLOntologyManager man = OWLManager.createOWLOntologyManager(); 295 OWLOntology ontology = man.loadOntologyFromOntologyDocument(new ByteArrayInputStream(s.getBytes())); 296 ExistentialRestrictionMaterialization mat = new ExistentialRestrictionMaterialization(ontology); 297 Set<OWLClassExpression> superClassExpressions = mat.materialize("http://example.org/A"); 298 for (OWLClassExpression sup : superClassExpressions) { 299 System.out.println(sup); 300 } 301 } 302 303}