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.owl; 020 021import org.dllearner.reasoning.OWLAPIReasoner; 022import org.semanticweb.owlapi.apibinding.OWLManager; 023import org.semanticweb.owlapi.formats.RDFXMLDocumentFormat; 024import org.semanticweb.owlapi.model.*; 025 026import java.net.URI; 027import java.util.*; 028 029public class OntologyCloserOWLAPI { 030 031 OWLOntology onto; 032 OWLAPIReasoner rs; 033// ReasonerComponent rs; 034 HashMap<OWLIndividual, Set<OWLObjectExactCardinality>> indToRestr; 035 OWLDataFactory factory; 036 OWLOntologyManager manager; 037 public int numberOfStatementsChanged = 0; 038 039 public OntologyCloserOWLAPI(OWLAPIReasoner reasoner) { 040 this.rs = reasoner; 041 this.indToRestr = new HashMap<>(); 042// this.rs = new ReasonerComponent(reasoner); 043 this.manager = OWLManager.createOWLOntologyManager(); 044 this.factory = manager.getOWLDataFactory(); 045 this.onto = reasoner.getOntology(); 046 } 047 048 /** 049 * counts the number of roles used by each individual and assigns 050 * ExactCardinalityRestriction to Individuals 051 */ 052 public void applyNumberRestrictions() { 053 System.out.println("apply ExactCardinalityRestriction to Individuals"); 054 Set<OWLObjectProperty> allRoles = this.rs.getObjectProperties(); 055 System.out.println("found: " + allRoles.size() + " roles"); 056 testForTransitiveProperties(true); 057 058 for (OWLObjectProperty oneRole : allRoles) { 059 060 Map<OWLIndividual, SortedSet<OWLIndividual>> allRoleMembers = this.rs 061 .getPropertyMembers(oneRole); 062 for (OWLIndividual oneInd : allRoleMembers.keySet()) { 063 SortedSet<OWLIndividual> fillers = allRoleMembers.get(oneInd); 064 // only where roles exist 065 if (fillers.size() > 0) { 066 OWLObjectExactCardinality oecr = factory 067 .getOWLObjectExactCardinality(fillers.size(), factory.getOWLObjectProperty(IRI 068 .create(oneRole.toStringID())), factory.getOWLThing()); 069 070 OWLAxiom axiom = factory.getOWLClassAssertionAxiom(oecr, factory 071 .getOWLNamedIndividual(IRI.create(oneInd.toStringID()))); 072 AddAxiom addAxiom = new AddAxiom(this.onto, axiom); 073 try { 074 // add change 075 manager.applyChange(addAxiom); 076 } catch (Exception e) { 077 e.printStackTrace(); 078 } 079 } 080 } 081 082 } 083 084 } 085 086 /** 087 * counts the number of roles used by each individual and assigns 088 * ExactCardinalityRestriction, but uses only one Intersection: role1 089 * exactly 1 and role2 exactly 2 and .... 090 * 091 */ 092 public void applyNumberRestrictionsConcise() { 093 094 Set<OWLObjectProperty> allRoles = this.rs.getObjectProperties(); 095 testForTransitiveProperties(true); 096 097 // collect info for roles and individuals 098 for (OWLObjectProperty oneRole : allRoles) { 099 Map<OWLIndividual, SortedSet<OWLIndividual>> allRoleMembers = this.rs 100 .getPropertyMembers(oneRole); 101 for (OWLIndividual oneInd : allRoleMembers.keySet()) { 102 SortedSet<OWLIndividual> fillers = allRoleMembers.get(oneInd); 103 if (fillers.size() > 0) { 104 OWLObjectExactCardinality oecr = factory.getOWLObjectExactCardinality(fillers.size(), factory.getOWLObjectProperty(IRI 105 .create(oneRole.toStringID())), 106 factory.getOWLThing()); 107 collectExObjRestrForInd(oneInd, oecr); 108 } 109 } 110 }// end for 111 112 Set<OWLClassExpression> target = new HashSet<>(); 113 Set<OWLObjectExactCardinality> s = null; 114 115 for (OWLIndividual oneInd : indToRestr.keySet()) { 116 s = indToRestr.get(oneInd); 117 for (OWLObjectExactCardinality oecr : s) { 118 target.add(oecr); 119 } 120 // collect everything in an intersection 121 OWLObjectIntersectionOf intersection = factory.getOWLObjectIntersectionOf(target); 122 s = null; 123 target = new HashSet<>(); 124 125 OWLAxiom axiom = factory.getOWLClassAssertionAxiom(intersection, factory 126 .getOWLNamedIndividual(IRI.create(oneInd.toStringID()))); 127 AddAxiom addAxiom = new AddAxiom(this.onto, axiom); 128 try { 129 manager.applyChange(addAxiom); 130 numberOfStatementsChanged++; 131 } catch (Exception e) { 132 e.printStackTrace(); 133 } 134 135 }// end for 136 } 137 138 /** 139 * @param printflag 140 * boolean for some output 141 * @return true if some roles are transitive 142 */ 143 public boolean testForTransitiveProperties(boolean printflag) { 144 145 Set<OWLTransitiveObjectPropertyAxiom> ax = onto.getAxioms(AxiomType.TRANSITIVE_OBJECT_PROPERTY); 146 boolean retval = !ax.isEmpty(); 147 for (OWLPropertyAxiom propertyAxiom : ax) { 148 if (printflag) { 149 System.out.println("WARNING transitive object property can't be used in cardinality restriction\n" 150 + propertyAxiom.toString() + "but I'm ignoring it"); 151 } 152 } 153 if (printflag) { 154 System.out.println("No transitive Properties found"); 155 } 156 return retval; 157 } 158 159 public void writeOWLFile(URI filename) { 160 try { 161 manager.saveOntology(this.onto, new RDFXMLDocumentFormat(), 162 IRI.create(filename)); 163 } catch (Exception e) { 164 e.printStackTrace(); 165 } 166 } 167 168 private boolean collectExObjRestrForInd(OWLIndividual ind, 169 OWLObjectExactCardinality oecr) { 170 Set<OWLObjectExactCardinality> s = indToRestr.get(ind); 171 172 if (s == null) { 173 174 indToRestr.put(ind, 175 new HashSet<>()); 176 s = indToRestr.get(ind); 177 } 178 return s.add(oecr); 179 } 180 181}