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.owl;
021
022 import java.net.URI;
023 import java.util.HashMap;
024 import java.util.HashSet;
025 import java.util.Map;
026 import java.util.Set;
027 import java.util.SortedSet;
028 import java.util.TreeSet;
029
030 import org.dllearner.core.owl.Description;
031 import org.dllearner.core.owl.Individual;
032 import org.dllearner.core.owl.ObjectProperty;
033 import org.dllearner.parser.KBParser;
034 import org.dllearner.reasoning.OWLAPIReasoner;
035 import org.dllearner.utilities.statistics.SimpleClock;
036 import org.semanticweb.owlapi.apibinding.OWLManager;
037 import org.semanticweb.owlapi.io.RDFXMLOntologyFormat;
038 import org.semanticweb.owlapi.model.AddAxiom;
039 import org.semanticweb.owlapi.model.AxiomType;
040 import org.semanticweb.owlapi.model.IRI;
041 import org.semanticweb.owlapi.model.OWLAxiom;
042 import org.semanticweb.owlapi.model.OWLClassExpression;
043 import org.semanticweb.owlapi.model.OWLDataFactory;
044 import org.semanticweb.owlapi.model.OWLObjectExactCardinality;
045 import org.semanticweb.owlapi.model.OWLObjectIntersectionOf;
046 import org.semanticweb.owlapi.model.OWLOntology;
047 import org.semanticweb.owlapi.model.OWLOntologyManager;
048 import org.semanticweb.owlapi.model.OWLPropertyAxiom;
049 import org.semanticweb.owlapi.model.OWLTransitiveObjectPropertyAxiom;
050
051 public class OntologyCloserOWLAPI {
052
053 OWLOntology onto;
054 OWLAPIReasoner rs;
055 // ReasonerComponent rs;
056 HashMap<Individual, Set<OWLObjectExactCardinality>> indToRestr;
057 OWLDataFactory factory;
058 OWLOntologyManager manager;
059 public int numberOfStatementsChanged = 0;
060
061 public OntologyCloserOWLAPI(OWLAPIReasoner reasoner) {
062 this.rs = reasoner;
063 this.indToRestr = new HashMap<Individual, Set<OWLObjectExactCardinality>>();
064 // this.rs = new ReasonerComponent(reasoner);
065 this.manager = OWLManager.createOWLOntologyManager();
066 this.factory = manager.getOWLDataFactory();
067 this.onto = reasoner.getOWLAPIOntologies().get(0);
068 }
069
070 /**
071 * counts the number of roles used by each individual and assigns
072 * ExactCardinalityRestriction to Individuals
073 */
074 public void applyNumberRestrictions() {
075 System.out.println("apply ExactCardinalityRestriction to Individuals");
076 Set<ObjectProperty> allRoles = this.rs.getObjectProperties();
077 System.out.println("found: " + allRoles.size() + " roles");
078 testForTransitiveProperties(true);
079
080 for (ObjectProperty oneRole : allRoles) {
081
082 Map<Individual, SortedSet<Individual>> allRoleMembers = this.rs
083 .getPropertyMembers(oneRole);
084 for (Individual oneInd : allRoleMembers.keySet()) {
085 SortedSet<Individual> fillers = allRoleMembers.get(oneInd);
086 // only where roles exist
087 if (fillers.size() > 0) {
088 OWLObjectExactCardinality oecr = factory
089 .getOWLObjectExactCardinality(fillers.size(), factory.getOWLObjectProperty(IRI
090 .create(oneRole.getName())), factory.getOWLThing());
091
092 OWLAxiom axiom = factory.getOWLClassAssertionAxiom(oecr, factory
093 .getOWLNamedIndividual(IRI.create(oneInd.getName())));
094 AddAxiom addAxiom = new AddAxiom(this.onto, axiom);
095 try {
096 // add change
097 manager.applyChange(addAxiom);
098 } catch (Exception e) {
099 e.printStackTrace();
100 }
101 }
102 }
103
104 }
105
106 }
107
108 /**
109 * counts the number of roles used by each individual and assigns
110 * ExactCardinalityRestriction, but uses only one Intersection: role1
111 * exactly 1 and role2 exactly 2 and ....
112 *
113 */
114 public void applyNumberRestrictionsConcise() {
115
116 Set<ObjectProperty> allRoles = this.rs.getObjectProperties();
117 testForTransitiveProperties(true);
118
119 // collect info for roles and individuals
120 for (ObjectProperty oneRole : allRoles) {
121 Map<Individual, SortedSet<Individual>> allRoleMembers = this.rs
122 .getPropertyMembers(oneRole);
123 for (Individual oneInd : allRoleMembers.keySet()) {
124 SortedSet<Individual> fillers = allRoleMembers.get(oneInd);
125 if (fillers.size() > 0) {
126 OWLObjectExactCardinality oecr = factory.getOWLObjectExactCardinality(fillers.size(), factory.getOWLObjectProperty(IRI
127 .create(oneRole.getName())),
128 factory.getOWLThing());
129 collectExObjRestrForInd(oneInd, oecr);
130 }
131 }
132 }// end for
133
134 Set<OWLClassExpression> target = new HashSet<OWLClassExpression>();
135 Set<OWLObjectExactCardinality> s = null;
136
137 for (Individual oneInd : indToRestr.keySet()) {
138 s = indToRestr.get(oneInd);
139 for (OWLObjectExactCardinality oecr : s) {
140 target.add(oecr);
141 }
142 // collect everything in an intersection
143 OWLObjectIntersectionOf intersection = factory.getOWLObjectIntersectionOf(target);
144 s = null;
145 target = new HashSet<OWLClassExpression>();
146
147 OWLAxiom axiom = factory.getOWLClassAssertionAxiom(intersection, factory
148 .getOWLNamedIndividual(IRI.create(oneInd.getName())));
149 AddAxiom addAxiom = new AddAxiom(this.onto, axiom);
150 try {
151 manager.applyChange(addAxiom);
152 numberOfStatementsChanged++;
153 } catch (Exception e) {
154 e.printStackTrace();
155 }
156
157 }// end for
158 }
159
160 /**
161 * @param printflag
162 * boolean for some output
163 * @return true if some roles are transitive
164 */
165 public boolean testForTransitiveProperties(boolean printflag) {
166
167 Set<OWLTransitiveObjectPropertyAxiom> ax = onto.getAxioms(AxiomType.TRANSITIVE_OBJECT_PROPERTY);
168 boolean retval = !ax.isEmpty();
169 for (OWLPropertyAxiom propertyAxiom : ax) {
170 if (printflag) {
171 System.out.println("WARNING transitive object property can't be used in cardinality restriction\n"
172 + propertyAxiom.toString() + "but I'm ignoring it");
173 }
174 }
175 if (printflag) {
176 System.out.println("No transitive Properties found");
177 }
178 return retval;
179 }
180
181 /*
182 * public static void closeKB(KB kb) { new
183 * OntologyCloserOWLAPI(kb).applyNumberRestrictions(); }
184 */
185
186 /**
187 * makes some retrieval queries
188 * @param conceptStr
189 */
190 public SortedSet<Individual> verifyConcept(String conceptStr) {
191
192 Description d;
193 SimpleClock sc = new SimpleClock();
194 StringBuffer sb = new StringBuffer();
195 sb.append(conceptStr);
196 conceptStr = sb.toString();
197 SortedSet<Individual> ind = new TreeSet<Individual>();
198 try {
199 d = KBParser.parseConcept(conceptStr);
200 System.out.println("\n*******************\nStarting retrieval");
201 System.out.println(d.toManchesterSyntaxString("",
202 new HashMap<String, String>()));
203 // System.out.println(d.toString());
204 sc.setTime();
205 this.rs.getIndividuals(d);
206
207 System.out.println("retrieved: " + ind.size() + " instances");
208 sc.printAndSet();
209 for (Individual individual : ind) {
210 System.out.print(individual + "|");
211 }
212
213 } catch (Exception e) {
214 e.printStackTrace();
215 }
216 return ind;
217 }
218
219 public void writeOWLFile(URI filename) {
220 try {
221 manager.saveOntology(this.onto, new RDFXMLOntologyFormat(),
222 IRI.create(filename));
223 } catch (Exception e) {
224 e.printStackTrace();
225 }
226 }
227
228 private boolean collectExObjRestrForInd(Individual ind,
229 OWLObjectExactCardinality oecr) {
230 Set<OWLObjectExactCardinality> s = indToRestr.get(ind);
231
232 if (s == null) {
233
234 indToRestr.put(ind,
235 new HashSet<OWLObjectExactCardinality>());
236 s = indToRestr.get(ind);
237 }
238 return s.add(oecr);
239 }
240
241 }