001 /**
002 * Copyright (C) 2007-2008, 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
021 package org.dllearner.tools.ore;
022
023 import java.io.File;
024 import java.net.MalformedURLException;
025 import java.util.Collection;
026 import java.util.HashSet;
027 import java.util.List;
028 import java.util.Map;
029 import java.util.Set;
030 import java.util.SortedSet;
031 import java.util.TreeSet;
032 import java.util.Vector;
033
034 import javax.swing.JLabel;
035
036 import org.dllearner.algorithms.refinement2.ROLComponent2;
037 import org.dllearner.core.ComponentInitException;
038 import org.dllearner.core.ComponentManager;
039 import org.dllearner.core.KnowledgeSource;
040 import org.dllearner.core.LearningAlgorithm;
041 import org.dllearner.core.LearningProblemUnsupportedException;
042 import org.dllearner.core.ReasonerComponent;
043 import org.dllearner.core.owl.Description;
044 import org.dllearner.core.owl.Individual;
045 import org.dllearner.core.owl.Intersection;
046 import org.dllearner.core.owl.NamedClass;
047 import org.dllearner.core.owl.ObjectQuantorRestriction;
048 import org.dllearner.core.owl.Union;
049 import org.dllearner.kb.OWLAPIOntology;
050 import org.dllearner.kb.OWLFile;
051 import org.dllearner.learningproblems.EvaluatedDescriptionPosNeg;
052 import org.dllearner.learningproblems.PosNegLPStandard;
053 import org.dllearner.reasoning.FastInstanceChecker;
054 import org.dllearner.reasoning.OWLAPIReasoner;
055
056 /**
057 * This class contains init methods, and is used as broker between wizard and OWL-API.
058 * @author Lorenz Buehmann
059 *
060 */
061 public class ORE {
062
063 private LearningAlgorithm la;
064 private ReasonerComponent rs;
065 private KnowledgeSource ks;
066 private PosNegLPStandard lp;
067 private ComponentManager cm;
068
069 private ReasonerComponent fastReasoner;
070 private ReasonerComponent owlReasoner;
071
072 private SortedSet<Individual> posExamples;
073 private SortedSet<Individual> negExamples;
074
075 private NamedClass classToLearn;
076 private EvaluatedDescriptionPosNeg newClassDescription;
077
078
079 private OntologyModifier modifier;
080
081 private String baseURI;
082 private Map<String, String> prefixes;
083
084 private double noise = 0.0;
085
086
087 public ORE() {
088
089 cm = ComponentManager.getInstance();
090
091 }
092
093 // step 1: detect knowledge sources
094
095 /**
096 * Applying knowledge source.
097 */
098 public void setKnowledgeSource(File f) {
099
100 ks = cm.knowledgeSource(OWLFile.class);
101
102 try {
103 cm.applyConfigEntry(ks, "url", f.toURI().toURL());
104 } catch (MalformedURLException e1) {
105 // TODO Auto-generated catch block
106 e1.printStackTrace();
107 }
108
109 try {
110 ks.init();
111 } catch (ComponentInitException e) {
112 // TODO Auto-generated catch block
113 e.printStackTrace();
114 }
115
116 }
117
118
119 /**
120 * Initialize the reasoners.
121 */
122 public void initReasoners(){
123
124 fastReasoner = cm.reasoner(FastInstanceChecker.class, ks);
125 try {
126 fastReasoner.init();
127 } catch (ComponentInitException e) {
128 // TODO Auto-generated catch block
129 e.printStackTrace();
130 }
131
132
133
134 owlReasoner = cm.reasoner(OWLAPIReasoner.class, ks);
135 try {
136 owlReasoner.init();
137 } catch (ComponentInitException e) {
138 // TODO Auto-generated catch block
139 e.printStackTrace();
140 }
141 modifier = new OntologyModifier(owlReasoner, rs);
142 baseURI = fastReasoner.getBaseURI();
143 prefixes = fastReasoner.getPrefixes();
144
145 }
146
147 /**
148 * Returns the reasoningservice.
149 * @return reasoning service
150 */
151 public ReasonerComponent getReasonerComponent(){
152 return rs;
153 }
154
155
156
157 public void setPosNegExamples(){
158 posExamples = owlReasoner.getIndividuals(classToLearn);
159 negExamples = owlReasoner.getIndividuals();
160
161
162 for (Individual pos : posExamples){
163 negExamples.remove(pos);
164 }
165 }
166
167
168 public OntologyModifier getModifier() {
169 return modifier;
170 }
171
172
173 public EvaluatedDescriptionPosNeg getNewClassDescription() {
174 return newClassDescription;
175 }
176
177
178 public String getBaseURI() {
179 return baseURI;
180 }
181
182 public Map<String, String> getPrefixes() {
183 return prefixes;
184 }
185
186 public ReasonerComponent getOwlReasoner() {
187 return owlReasoner;
188 }
189
190 public ReasonerComponent getFastReasoner() {
191 return fastReasoner;
192 }
193
194 public void setLearningProblem(){
195 lp = new PosNegLPStandard(owlReasoner, posExamples, negExamples);
196 lp.init();
197 }
198
199 public void setNoise(double noise){
200 this.noise = noise;
201 }
202
203 public void setLearningAlgorithm(){
204 try {
205 la = cm.learningAlgorithm(ROLComponent2.class, lp, owlReasoner);
206 } catch (LearningProblemUnsupportedException e1) {
207 // TODO Auto-generated catch block
208 e1.printStackTrace();
209 }
210
211 Set<String> t = new TreeSet<String>();
212
213
214 t.add(classToLearn.getName());
215 cm.applyConfigEntry(la, "ignoredConcepts", t);
216 cm.applyConfigEntry(la, "guaranteeXgoodDescriptions", 10);
217 try {
218 la.init();
219 } catch (ComponentInitException e) {
220 // TODO Auto-generated catch block
221 e.printStackTrace();
222 }
223
224 }
225
226 /**
227 * Sets the class that has to be learned.
228 * @param oldClass class that is choosen to be (re)learned
229 */
230 public void setClassToLearn(NamedClass oldClass){
231 this.classToLearn = oldClass;
232 }
233
234 public void init(){
235 try {
236 owlReasoner.init();
237 fastReasoner.init();
238 } catch (ComponentInitException e) {
239 // TODO Auto-generated catch block
240 e.printStackTrace();
241 }
242 this.setPosNegExamples();
243 this.setLearningProblem();
244 this.setLearningAlgorithm();
245
246 }
247
248 /**
249 * Starts the learning algorithm, setting noise value and ignored concepts.
250 *
251 */
252 public void start(){
253 Set<String> t = new TreeSet<String>();
254 t.add(classToLearn.getName());
255 cm.applyConfigEntry(la, "ignoredConcepts", t);
256 cm.applyConfigEntry(la, "noisePercentage", noise);
257 try {
258 la.init();
259 } catch (ComponentInitException e) {
260 // TODO Auto-generated catch block
261 e.printStackTrace();
262 }
263
264 la.start();
265
266 }
267
268 public void setNewClassDescription(EvaluatedDescriptionPosNeg newClassDescription) {
269 this.newClassDescription = newClassDescription;
270 }
271
272 public LearningAlgorithm getLa() {
273 return la;
274 }
275
276 public NamedClass getIgnoredConcept() {
277 return classToLearn;
278 }
279
280
281
282 /**
283 * Retrieves description parts that might cause inconsistency - for negative examples only.
284 * @param ind
285 * @param desc
286 */
287 public Set<Description> getNegCriticalDescriptions(Individual ind, Description desc){
288
289 Set<Description> criticals = new HashSet<Description>();
290 List<Description> children = desc.getChildren();
291
292 if(owlReasoner.hasType(desc, ind)){
293
294 if(children.size() >= 2){
295
296 if(desc instanceof Intersection){
297 for(Description d: children){
298 criticals.addAll(getNegCriticalDescriptions(ind, d));
299 }
300 } else if(desc instanceof Union){
301 for(Description d: children){
302 if(owlReasoner.hasType(d, ind)){
303 criticals.addAll(getNegCriticalDescriptions(ind, d));
304 }
305 }
306 }
307 } else{
308 criticals.add(desc);
309 }
310 }
311
312 return criticals;
313 }
314 /**
315 * Retrieves the description parts, that might cause inconsistency - for negative examples.
316 * @param ind
317 * @param desc
318 * @return vector of JLabel
319 */
320 public Collection<JLabel> descriptionToJLabelNeg(Individual ind, Description desc){
321
322 Collection<JLabel> criticals = new Vector<JLabel>();
323 List<Description> children = desc.getChildren();
324
325 // try {
326 if(fastReasoner.hasType(desc, ind)){
327
328 if(children.size() >= 2){
329
330 if(desc instanceof Intersection){
331 criticals.add(new JLabel("("));
332 for(int i = 0; i<children.size()-1; i++){
333 criticals.addAll(descriptionToJLabelNeg(ind, desc.getChild(i)));
334 criticals.add(new JLabel("and"));
335
336 }
337 criticals.addAll(descriptionToJLabelNeg(ind, desc.getChild(children.size()-1)));
338 criticals.add(new JLabel(")"));
339 } else if(desc instanceof Union){
340 criticals.add(new JLabel("("));
341 for(int i = 0; i<children.size()-1; i++){
342 if(fastReasoner.hasType(desc.getChild(i), ind)){
343 criticals.addAll(descriptionToJLabelNeg(ind, desc.getChild(i)));
344 } else{
345 criticals.add(new JLabel(desc.getChild(i).toManchesterSyntaxString(baseURI, prefixes)));
346 }
347 criticals.add(new JLabel("or"));
348 }
349 if(fastReasoner.hasType(desc.getChild(children.size()-1), ind)){
350 criticals.addAll(descriptionToJLabelNeg(ind, desc.getChild(children.size()-1)));
351 } else{
352 criticals.add(new JLabel(desc.getChild(children.size()-1).toManchesterSyntaxString(baseURI, prefixes)));
353 }
354 criticals.add(new JLabel(")"));
355
356
357 }
358 } else{
359
360 criticals.add(new DescriptionLabel(desc, "neg"));
361 }
362 } else{
363 criticals.add(new JLabel(desc.toManchesterSyntaxString(baseURI, prefixes)));
364 }
365 // } catch (ReasoningMethodUnsupportedException e) {
366 // // TODO Auto-generated catch block
367 // e.printStackTrace();
368 // }
369
370 return criticals;
371 }
372
373 /**
374 * Retrieves the description parts that might cause inconsistency - for positive examples.
375 * @param ind
376 * @param desc
377 * @return vector of JLabel
378 */
379 public Collection<JLabel> descriptionToJLabelPos(Individual ind, Description desc){
380
381 Collection<JLabel> criticals = new Vector<JLabel>();
382 List<Description> children = desc.getChildren();
383
384 // try {
385 if(!fastReasoner.hasType(desc, ind)){
386
387 if(children.size() >= 2){
388
389 if(desc instanceof Union){
390 criticals.add(new JLabel("("));
391 for(int i = 0; i<children.size()-1; i++){
392 criticals.addAll(descriptionToJLabelPos(ind, desc.getChild(i)));
393 criticals.add(new JLabel("or"));
394 }
395 criticals.addAll(descriptionToJLabelPos(ind, desc.getChild(children.size()-1)));
396 criticals.add(new JLabel(")"));
397 } else if(desc instanceof Intersection){
398 criticals.add(new JLabel("("));
399 for(int i = 0; i<children.size()-1; i++){
400 if(!fastReasoner.hasType(desc.getChild(i), ind)){
401 criticals.addAll(descriptionToJLabelPos(ind, desc.getChild(i)));
402 } else{
403 criticals.add(new JLabel(desc.getChild(i).toManchesterSyntaxString(baseURI, prefixes)));
404 }
405 criticals.add(new JLabel("and"));
406 }
407 if(!fastReasoner.hasType(desc.getChild(children.size()-1), ind)){
408 criticals.addAll(descriptionToJLabelPos(ind, desc.getChild(children.size()-1)));
409 } else{
410 criticals.add(new JLabel(desc.getChild(children.size()-1).toManchesterSyntaxString(baseURI, prefixes)));
411 }
412 criticals.add(new JLabel(")"));
413 }
414 } else{
415 criticals.add(new DescriptionLabel(desc, "pos"));
416 }
417 } else{
418 criticals.add(new JLabel(desc.toManchesterSyntaxString(baseURI, prefixes)));
419 }
420 // } catch (ReasoningMethodUnsupportedException e) {
421 // // TODO Auto-generated catch block
422 // e.printStackTrace();
423 // }
424
425 return criticals;
426 }
427
428 /**
429 * Returns individuals that are in range of property.
430 * @param objRestr
431 * @param ind
432 */
433 public Set<Individual> getIndividualsInPropertyRange(ObjectQuantorRestriction objRestr, Individual ind){
434
435 Set<Individual> individuals = owlReasoner.getIndividuals(objRestr.getChild(0));
436 individuals.remove(ind);
437
438 return individuals;
439 }
440
441 /**
442 * Returns individuals that are not in range of property.
443 * @param objRestr
444 * @param ind
445 */
446 public Set<Individual> getIndividualsNotInPropertyRange(ObjectQuantorRestriction objRestr, Individual ind){
447
448
449 Set<Individual> allIndividuals = new HashSet<Individual>();
450
451 for(Individual i : owlReasoner.getIndividuals()){
452
453 // try {
454 if(!fastReasoner.hasType(objRestr.getChild(0), i)){
455 allIndividuals.add(i);
456 }
457 // } catch (ReasoningMethodUnsupportedException e) {
458 // // TODO Auto-generated catch block
459 // e.printStackTrace();
460 // }
461 }
462
463
464 return allIndividuals;
465 }
466
467 /**
468 * Returns classes where individual might moved to.
469 * @param ind the individual
470 * @return set of classes
471 */
472 public Set<NamedClass> getpossibleClassesMoveTo(Individual ind){
473 Set<NamedClass> moveClasses = new HashSet<NamedClass>();
474 for(NamedClass nc : owlReasoner.getNamedClasses()){
475 if(!owlReasoner.hasType(nc, ind)){
476 moveClasses.add(nc);
477 }
478 }
479 moveClasses.remove(classToLearn);
480
481 return moveClasses;
482 }
483
484 /**
485 * Returns classes where individual might moved from.
486 * @param ind the individual
487 * @return set of classes
488 */
489 public Set<NamedClass> getpossibleClassesMoveFrom(Individual ind){
490 Set<NamedClass> moveClasses = new HashSet<NamedClass>();
491 for(NamedClass nc : owlReasoner.getNamedClasses()){
492 if(owlReasoner.hasType(nc, ind)){
493 moveClasses.add(nc);
494 }
495 }
496 moveClasses.remove(classToLearn);
497
498 return moveClasses;
499 }
500
501 /**
502 * Update reasoners ontology.
503 */
504 public void updateReasoner(){
505 fastReasoner = cm.reasoner(FastInstanceChecker.class, new OWLAPIOntology(modifier.getOntology()));
506 try {
507 fastReasoner.init();
508 } catch (ComponentInitException e) {
509 // TODO Auto-generated catch block
510 e.printStackTrace();
511 }
512 owlReasoner = cm.reasoner(OWLAPIReasoner.class, new OWLAPIOntology(modifier.getOntology()));
513
514 try {
515 owlReasoner.init();
516 } catch (ComponentInitException e) {
517 // TODO Auto-generated catch block
518 e.printStackTrace();
519 }
520 // rs = cm.reasoningService(owlReasoner);
521 setLearningAlgorithm();
522 }
523
524 /**
525 * Get the complement classes where individual is asserted to.
526 * @param desc
527 * @param ind
528 */
529 public Set<NamedClass> getComplements(Description desc, Individual ind){
530 // System.out.println("----------------" + desc + "---------------");
531 Set<NamedClass> complements = new HashSet<NamedClass>();
532 for(NamedClass nc : owlReasoner.getNamedClasses()){
533 if(!(nc.toString().endsWith("Thing"))){
534 if(owlReasoner.hasType(nc, ind)){
535 if(modifier.isComplement(desc, nc)){
536 complements.add(nc);
537 }
538 }
539 }
540 }
541 // System.out.println("Disjunkt sind: " + complements);
542
543 return complements;
544 }
545
546
547
548 public static void main(String[] args){
549 final ORE test = new ORE();
550
551 File owlFile1 = new File("examples/ore/people+pets.owl");
552 File owlFile2 = new File("examples/ore/inconsistent.owl");
553 File owlFile3 = new File("examples/ore/incohaerent.owl");
554
555 test.setKnowledgeSource(owlFile1);
556 test.initReasoners();
557 System.out.println(test.owlReasoner.isSatisfiable());
558
559 test.setKnowledgeSource(owlFile2);
560 test.initReasoners();
561 System.out.println(test.owlReasoner.isSatisfiable());
562
563 test.setKnowledgeSource(owlFile3);
564 test.initReasoners();
565 System.out.println(test.owlReasoner.isSatisfiable());
566
567
568
569
570 }
571 }
572
573 // public static void main(String[] args){
574 //
575 // final ORE test = new ORE();
576 //
577 // File owlFile = new File("src/dl-learner/org/dllearner/tools/ore/neg_has_all.owl");
578 //
579 // test.setKnowledgeSource(owlFile);
580 // test.initReasoners();
581 //
582 // Individual subject = new Individual("http://example.com/father#patrick");
583 // Description newClass = new Intersection(new NamedClass("http://example.com/father#female"),
584 // new Negation(new NamedClass("http://example.com/father#bird")));
585 // Description desc = new NamedClass("http://example.com/father#bird");
586 //
587 // Description range = new ObjectAllRestriction(new ObjectProperty("http://example.com/father#hasChild"),
588 // new NamedClass("http://example.com/father#female"));
589 // ObjectAllRestriction role = new ObjectAllRestriction(new ObjectProperty("http://example.com/father#hasChild"),
590 // range);
591 // System.out.println(role.toManchesterSyntaxString(test.getBaseURI(), test.getPrefixes()));
592 // try {
593 // System.out.println(test.fastReasoner.instanceCheck(role, subject));
594 // } catch (ReasoningMethodUnsupportedException e) {
595 // // TODO Auto-generated catch block
596 // e.printStackTrace();
597 // }
598 // test.modifier.addObjectProperty(subject, role, new Individual("http://example.com/father#anna"));
599 // test.updateReasoner();
600 // try {
601 // System.out.println(test.fastReasoner.instanceCheck(role, subject));
602 // } catch (ReasoningMethodUnsupportedException e) {
603 // // TODO Auto-generated catch block
604 // e.printStackTrace();
605 // }
606 // test.modifier.saveOntology();
607 //
608 //
609 //
610 //
611
612 // System.out.println(test.owlReasoner.getInconsistentClasses());
613 // test.getModi().reason();
614
615 //
616 // Individual subject = new Individual("http://example.com/father#anton");
617 //
618 // Description range = new ObjectAllRestriction(new ObjectProperty("http://example.com/father#hasChild"),
619 // new NamedClass("http://example.com/father#female"));
620 // ObjectAllRestriction role = new ObjectAllRestriction(new ObjectProperty("http://example.com/father#hasChild"),
621 // range);
622 // Description d = new Intersection(new NamedClass("http://example.com/father#male"), role);
623 // try {
624 // System.out.println(test.fastReasoner.instanceCheck(d, subject));
625 // } catch (ReasoningMethodUnsupportedException e) {
626 // // TODO Auto-generated catch block
627 // e.printStackTrace();
628 // }
629 // System.out.println("vorher" + test.modi.ontology.getAxioms());
630 // Individual object = new Individual("http://example.com/father#markus");
631 // test.modi.addObjectProperty(subject, role, object);
632 // test.updateReasoner();
633 // try {
634 // System.out.println(test.fastReasoner.instanceCheck(d, subject));
635 // } catch (ReasoningMethodUnsupportedException e) {
636 // // TODO Auto-generated catch block
637 // e.printStackTrace();
638 // }
639
640
641 // test.modi.reason();
642
643 // Individual ind = new Individual("http://example.com/father#heinz");
644 // Description d1 = new Intersection(new NamedClass("http://example.com/father#male"), new ObjectAllRestriction(new ObjectProperty("http://example.com/father#hasChild"), new NamedClass("http://example.com/father#male")));
645 // System.out.println(test.reasoner2.instanceCheck(d, ind));
646
647
648 // test.setConcept(new NamedClass("http://example.com/father#father"));
649 // test.setPosNegExamples();
650 // System.out.println(test.posExamples);
651 // System.out.println(test.negExamples);
652 // test.start();
653 // Individual ind = new Individual("http://www.test.owl#lorenz");
654
655 // test.modi.addClassAssertion(ind, new NamedClass("http://www.test.owl#B"));
656 // System.out.println(test.reasoner2.getInconsistentClasses());
657 // Description d = new Intersection(new NamedClass("http://www.test.owl#A"), new Union(new NamedClass("http://www.test.owl#B"),
658 // new NamedClass("http://www.test.owl#C")));
659 // System.out.println(d);
660 // System.out.println(test.getCriticalDescriptions(ind, d));
661 // JFrame testFrame = new JFrame();
662 // JPanel j = new JPanel();
663 // testFrame.add(j);
664 // testFrame.setSize(new Dimension(400, 400));
665 // for(JLabel jLab : test.DescriptionToJLabel(ind, d))
666 // j.add(jLab);
667 // testFrame.setVisible(true);
668 //}
669
670
671
672
673
674
675
676
677
678