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