001    /**
002     * Copyright (C) 2007-2009, 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.protege;
022    
023    import java.util.HashSet;
024    import java.util.List;
025    import java.util.Set;
026    
027    import javax.swing.DefaultListModel;
028    
029    import org.dllearner.algorithms.celoe.CELOE;
030    import org.dllearner.core.ComponentInitException;
031    import org.dllearner.core.ComponentManager;
032    import org.dllearner.core.EvaluatedDescription;
033    import org.dllearner.core.KnowledgeSource;
034    import org.dllearner.core.LearningAlgorithm;
035    import org.dllearner.core.LearningProblem;
036    import org.dllearner.core.LearningProblemUnsupportedException;
037    import org.dllearner.core.owl.Description;
038    import org.dllearner.core.owl.Individual;
039    import org.dllearner.core.owl.NamedClass;
040    import org.dllearner.kb.OWLAPIOntology;
041    import org.dllearner.learningproblems.ClassLearningProblem;
042    import org.dllearner.learningproblems.EvaluatedDescriptionClass;
043    import org.dllearner.reasoning.FastInstanceChecker;
044    import org.dllearner.utilities.owl.OWLAPIDescriptionConvertVisitor;
045    import org.mindswap.pellet.exceptions.InconsistentOntologyException;
046    import org.protege.editor.owl.OWLEditorKit;
047    import org.semanticweb.owl.apibinding.OWLManager;
048    import org.semanticweb.owl.model.AddAxiom;
049    import org.semanticweb.owl.model.OWLAxiom;
050    import org.semanticweb.owl.model.OWLDataFactory;
051    import org.semanticweb.owl.model.OWLDescription;
052    import org.semanticweb.owl.model.OWLOntology;
053    import org.semanticweb.owl.model.OWLOntologyChangeException;
054    import org.semanticweb.owl.model.OWLOntologyManager;
055    
056    /**
057     * This Class provides the necessary methods to learn Concepts from the
058     * DL-Learner.
059     * 
060     * @author Christian Koetteritzsch
061     * 
062     */
063    public class DLLearnerModel implements Runnable{
064    
065            // The Sting is for components that are available in the DL-Learner
066    
067            private final String[] componenten = { "org.dllearner.kb.OWLFile",
068                            "org.dllearner.reasoning.OWLAPIReasoner",
069                            "org.dllearner.reasoning.FastInstanceChecker",
070                            "org.dllearner.reasoning.FastRetrievalReasoner",
071                            "org.dllearner.algorithms.RandomGuesser",
072                            "org.dllearner.algorithms.refinement.ROLearner",
073                            "org.dllearner.algorithms.celoe.CELOE",
074                            "org.dllearner.algorithms.gp.GP", "org.dllearner.learningproblems.PosOnlyLP",
075                            "org.dllearner.learningproblems.PosNegLPStandard", "org.dllearner.learningproblems.ClassLearningProblem"};
076    
077            // Component Manager that manages the components of the DL-Learner
078    
079            private final ComponentManager cm;
080    
081            private static final String EQUIVALENT_CLASS_AXIOM_STRING = "equivalent class";
082            private static final String SUPER_CLASS_AXIOM_STRING = "Suggest super class";
083            private static final String EQUIVALENT_CLASS_LEARNING = "equivalence";
084            private static final String SUPER_CLASS_LEARNING = "superClass";
085    
086            // The View of the DL-Learner Plugin
087    
088    
089            // The Learning problem that is used to learn new concepts
090    
091            private LearningProblem lp;
092    
093            // This boolean is for clearing the suggest Panel
094    
095            private boolean alreadyLearned = false;
096    
097            // This is the learning algorithm
098    
099            private LearningAlgorithm la = null;
100    
101            // Necessary to get the currently loaded Ontology
102    
103            private final OWLEditorKit editor;
104    
105            // The Reasoner which is used to learn
106    
107            private FastInstanceChecker reasoner;
108    
109            // A Set of Descriptions in OWL Syntax which the DL-Learner suggested
110    
111            private final Set<OWLDescription> owlDescription;
112    
113            // The most fitting Description in OWL Syntax which the DL-Learner suggested
114    
115            private OWLDescription desc;
116    
117            // String to distinguish between Equivalent classes and sub classes
118    
119            private String id;
120    
121            // The new Concept which is learned by the DL-Learner
122    
123            private OWLDescription newConceptOWLAPI;
124    
125            // The old concept that is chosen in Protege
126    
127            private OWLDescription oldConceptOWLAPI;
128    
129            // A Set of Descriptions in OWL Syntax which the DL-Learner suggested
130    
131            private final Set<OWLDescription> ds;
132    
133            // The model for the suggested Descriptions
134    
135            private final DefaultListModel suggestModel;
136    
137            // The Individuals of the Ontology
138    
139            private Set<Individual> individual;
140            private int instancesCount;
141    
142            // The error message which is rendered when an error occured
143    
144    
145            // This is the new axiom which will be added to the Ontology
146    
147            private OWLAxiom axiomOWLAPI;
148    
149            // This is necessary to get the details of the suggested concept
150    
151            private final Set<KnowledgeSource> sources;
152            private boolean hasIndividuals;
153            private NamedClass currentConcept;
154            private Set<String> ontologieURI;
155            private final boolean ontologyConsistent;
156            private final DLLearnerView view;
157    
158            // This is a List of evaluated descriptions to get more information of the
159            // suggested concept
160            private List<? extends EvaluatedDescription> evalDescriptions;
161    
162            /**
163             * This is the constructor for DL-Learner model.
164             * 
165             * @param editorKit
166             *            Editor Kit to get the currently loaded Ontology
167             * @param id
168             *            String if it learns a subclass or a superclass.
169             * @param view
170             *            current view of the DL-Learner tab
171             */
172            public DLLearnerModel(OWLEditorKit editorKit, DLLearnerView view) {
173                    editor = editorKit;
174                    
175                    this.view = view;
176                    ontologyConsistent = true;
177                    instancesCount = 0;
178                    owlDescription = new HashSet<OWLDescription>();
179                    ComponentManager.setComponentClasses(componenten);
180                    cm = ComponentManager.getInstance();
181                    ds = new HashSet<OWLDescription>();
182                    suggestModel = new DefaultListModel();
183                    ontologieURI = new HashSet<String>();
184                    sources = new HashSet<KnowledgeSource>();
185            }
186            
187            public void setID(String d) {
188                    this.id = d;
189            }
190            /**
191             * This method initializes the SimpleSuggestionLearningAlgorithm and adds
192             * the suggestions to the suggest panel model.
193             */
194            public void initReasoner() {
195                    alreadyLearned = false;
196                    setKnowledgeSource();
197                    setReasoner();
198    
199            }
200    
201            /**
202             * This Method returns a List of evaluated descriptions suggested by the
203             * DL-Learner.
204             * 
205             * @return list of evaluated descriptions
206             */
207            public List<? extends EvaluatedDescription> getEvaluatedDescriptionList() {
208                    return evalDescriptions;
209            }
210    
211            /**
212             * This method sets the knowledge source for the learning process. Only
213             * OWLAPIOntology will be available.
214             */
215            public void setKnowledgeSource() {
216                    Set<OWLOntology> ontologieSet = editor.getModelManager().getActiveOntologies();
217                    for(OWLOntology onto : ontologieSet) {
218                            sources.add(new OWLAPIOntology(onto));
219                    }
220            }
221    
222            /**
223             * This method sets the reasoner. Only
224             * FastInstanceChecker is available.
225             */
226            public void setReasoner() {
227                    this.reasoner = cm.reasoner(FastInstanceChecker.class, sources);
228                    try {
229                            reasoner.init();
230                            reasoner.isSatisfiable();
231                            view.setIsInconsistent(false);
232                    } catch (ComponentInitException e) {
233                            // TODO Auto-generated catch block
234                            System.out.println("fehler!!!!!!!!!");  
235                            e.printStackTrace();
236                    } catch (InconsistentOntologyException incon) {
237                            view.setIsInconsistent(true);
238                    }
239            }
240            
241            /**
242             * This method returns the fast instance checker reasoner.
243             * @return fast instance checker reasoner
244             */
245            public FastInstanceChecker getReasoner() {
246                    return reasoner;
247            }
248            
249            /**
250             * This method returns the current concept.
251             * @return current concept
252             */
253            public NamedClass getCurrentConcept() {
254                    return currentConcept;
255            }
256            /**
257             * This method sets the Learning problem for the learning process.
258             * PosNegDefinitonLp for equivalent classes and PosNegInclusionLP for super
259             * classes.
260             */
261            public void setLearningProblem() {
262                    lp = cm.learningProblem(ClassLearningProblem.class, reasoner);
263                    cm.applyConfigEntry(lp, "classToDescribe", currentConcept.toString());
264                    if (id.equals(EQUIVALENT_CLASS_AXIOM_STRING)) {
265                            // sets the learning problem to PosNegDefinitionLP when the
266                            // dllearner should suggest an equivalent class
267                            cm.applyConfigEntry(lp, "type", EQUIVALENT_CLASS_LEARNING);
268                    }
269                    if (id.equals(SUPER_CLASS_AXIOM_STRING)) {
270                            // sets the learning problem to PosNegInclusionLP when the dllearner
271                            // should suggest a subclass
272                            cm.applyConfigEntry(lp, "type", SUPER_CLASS_LEARNING);
273                    }
274                    try {
275                            lp.init();
276                    } catch (ComponentInitException e) {
277                            e.printStackTrace();
278                    }
279            }
280    
281            /**
282             * This method sets the learning algorithm for the learning process.
283             */
284            public void setLearningAlgorithm() {
285                    try {
286                            this.la = cm.learningAlgorithm(CELOE.class, lp,
287                                            reasoner);
288                    } catch (LearningProblemUnsupportedException e) {
289                            // TODO Auto-generated catch block
290                            e.printStackTrace();
291                    }
292                    cm.applyConfigEntry(la, "useNegation", false);
293                    cm.applyConfigEntry(la, "noisePercentage", view.getPosAndNegSelectPanel().getOptionPanel().getMinAccuracy());
294                    cm.applyConfigEntry(la, "maxExecutionTimeInSeconds", view
295                                    .getPosAndNegSelectPanel().getOptionPanel()
296                                    .getMaxExecutionTime());
297                    try {
298                            // initializes the learning algorithm
299                            la.init();
300                    } catch (ComponentInitException e) {
301                            e.printStackTrace();
302                    }
303                    alreadyLearned = true;
304            }
305            
306            /**
307             * Starts the learning algorithm.
308             */
309            public void run() {
310                    la.start();
311            }
312    
313            /**
314             * This method sets the positive examples for learning. 
315             * @param ind Set of Individuals
316             */
317            public void setIndividuals(Set<Individual> ind) {
318                    individual = ind;
319            }
320            
321            /**
322             * This method sets the uri sting for the currently used
323             * for learning. 
324             * @param uri Set of uris
325             */
326            public void setOntologyURIString(Set<String> uri) {
327                    this.ontologieURI = uri;
328            }
329            /**
330             * This Method checks if the selected class has any individuals.
331             * 
332             * @return boolean hasIndividuals
333             */
334            public boolean hasIndividuals() {
335                    return hasIndividuals;
336            }
337            
338            /**
339             * Sets if the ontology has individuals.
340             * @param has boolean if concept has Individuals
341             */
342            public void setHasIndividuals(boolean has) {
343                    this.hasIndividuals = has;
344            }
345    
346            /**
347             * This method returns the current learning algorithm that is used to learn
348             * new concepts.
349             * 
350             * @return Learning algorithm that is used for learning concepts.
351             */
352            public LearningAlgorithm getLearningAlgorithm() {
353                    return la;
354            }
355    
356            /**
357             * This method returns a set of concepts that are learned by the DL-Learner.
358             * They are already converted into the OWLDescription format.
359             * 
360             * @return Set of learned concepts in OWLDescription format
361             */
362            public Set<OWLDescription> getNewOWLDescription() {
363                    return owlDescription;
364            }
365    
366            /**
367             * This method returns the old concept which is chosen in protege in
368             * OWLDescription format.
369             * 
370             * @return Old Concept in OWLDescription format.
371             */
372            public OWLDescription getOldConceptOWLAPI() {
373                    oldConceptOWLAPI = OWLAPIDescriptionConvertVisitor
374                    .getOWLDescription(currentConcept);
375                    return oldConceptOWLAPI;
376            }
377            
378            /**
379             * This method returns the currently learned description in OWLDescription
380             * format.
381             * 
382             * @return currently used description in OWLDescription format
383             */
384            public OWLDescription getSolution() {
385                    return desc;
386            }
387    
388            /**
389             * This method gets a description learned by the DL-Learner an converts it
390             * to the OWLDescription format.
391             * 
392             * @param desc
393             *            Description learned by the DL-Learner
394             */
395            private void setNewConceptOWLAPI(Description des) {
396                    // converts DL-Learner description into an OWL API Description
397                    newConceptOWLAPI = OWLAPIDescriptionConvertVisitor
398                                    .getOWLDescription(des);
399                    ds.add(newConceptOWLAPI);
400                    owlDescription.add(newConceptOWLAPI);
401                    this.desc = newConceptOWLAPI;
402            }
403            
404            /**
405             * This methode returns the Model for the suggested Concepts.
406             * 
407             * @return DefaultListModel
408             */
409            public DefaultListModel getSuggestModel() {
410                    return suggestModel;
411            }
412    
413            /**
414             * This method stores the new concept learned by the DL-Learner in the
415             * Ontology.
416             * 
417             * @param descript
418             *            Description learn by the DL-Learner
419             */
420            public void changeDLLearnerDescriptionsToOWLDescriptions(
421                            Description descript) {
422                    setNewConceptOWLAPI(descript);
423                    oldConceptOWLAPI = OWLAPIDescriptionConvertVisitor
424                                    .getOWLDescription(currentConcept);
425                    ds.add(oldConceptOWLAPI);
426                    OWLOntologyManager manager = OWLManager.createOWLOntologyManager();
427    
428                    OWLDataFactory factory = manager.getOWLDataFactory();
429                    if (id.equals(EQUIVALENT_CLASS_AXIOM_STRING)) {
430                            axiomOWLAPI = factory.getOWLEquivalentClassesAxiom(ds);
431                    } else {
432                            axiomOWLAPI = factory.getOWLSubClassAxiom(oldConceptOWLAPI,
433                                            newConceptOWLAPI);
434                    }
435                    OWLOntology onto = editor.getModelManager().getActiveOntology();
436                    AddAxiom axiom = new AddAxiom(onto, axiomOWLAPI);
437                    try {
438                            // adds the new concept to the ontology
439                            manager.applyChange(axiom);
440                    } catch (OWLOntologyChangeException e) {
441                            // TODO Auto-generated catch block
442                            e.printStackTrace();
443                    }
444            }
445    
446            /**
447             * This method gets the status if the DL-Learner has already learned. It is
448             * only for reseting the suggest panel.
449             * 
450             * @return boolean if the learner has already learned
451             */
452            public boolean getAlreadyLearned() {
453                    return alreadyLearned;
454            }
455    
456            /**
457             * This Method checks if after inserting of this concept the ontology is
458             * still consistent.
459             * 
460             * @param eDescription
461             *            EvauatedDescription
462             * @return isConsistent boolean
463             */
464            public boolean isConsistent(EvaluatedDescription eDescription) {
465                    boolean isConsistent = false;
466                    if (((EvaluatedDescriptionClass) eDescription).getCoveredInstances().size() < instancesCount) {
467                            isConsistent = false;
468                    } else {
469                            isConsistent = true;
470                    }
471                    return isConsistent;
472            }
473    
474            /**
475             * This method sets the suggestion list.
476             * 
477             * @param list
478             *            List(EvaluatedDescription)
479             */
480            public void setSuggestList(List<? extends EvaluatedDescription> list) {
481                    evalDescriptions = list;
482            }
483            
484            /**
485             * This method returns the Strings of the Ontology uri's that are currently used.
486             * @return ontologieURI
487             */
488            public Set<String> getOntologyURIString() {
489                    return ontologieURI;
490            }
491            /**
492             * This method returns a boolean if an ontology is inconsistent.
493             * @return ontologyInconsistent
494             */
495            public boolean getOntologyConsistent() {
496                    return ontologyConsistent;
497            }
498            
499            /**
500             * This sets the current concept.
501             * @param current currently selected class
502             */
503            public void setCurrentConcept(NamedClass current) {
504                    this.currentConcept = current;
505            }
506    
507            /**
508             * This method returns a set of individuals belonging to the
509             * currently selected class. 
510             * @return the individual
511             */
512            public Set<Individual> getIndividual() {
513                    return individual;
514            }
515            
516            /**
517             * This method sets the number of instances.
518             * @param i number of instances
519             */
520            public void setInstancesCount(int i) {
521                    instancesCount = i;
522            }
523            
524            public String getID() {
525                    return id;
526            }
527    }
528    
529