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.algorithms.decisiontrees.refinementoperators;
020
021import org.dllearner.core.AbstractReasonerComponent;
022import org.dllearner.core.ComponentAnn;
023import org.dllearner.core.ComponentInitException;
024import org.dllearner.core.Reasoner;
025import org.dllearner.core.annotations.NoConfigOption;
026import org.dllearner.core.config.ConfigOption;
027import org.dllearner.core.owl.ClassHierarchy;
028import org.dllearner.learningproblems.PosNegLP;
029import org.dllearner.refinementoperators.PsiDown;
030import org.dllearner.refinementoperators.RhoDRDown;
031import org.dllearner.utilities.owl.OWLClassExpressionUtils;
032import org.semanticweb.owlapi.model.*;
033import org.semanticweb.owlapi.reasoner.Node;
034import org.slf4j.Logger;
035import org.slf4j.LoggerFactory;
036import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl;
037
038import java.util.*;
039//import evaluation.Parameters;
040//import knowledgeBasesHandler.KnowledgeBase;
041
042/**
043 * The original refinement Operator proposed for inducing Terminological Decision Trees
044 * @author Giuseppe Rizzo
045 *
046 */
047@ComponentAnn(name="Refinement Operator TDT", shortName="tdtop", version=1.0)
048public class DLTreesRefinementOperator implements InstanceBasedRefinementOperator{
049
050        private static Logger logger= LoggerFactory.getLogger(DLTreesRefinementOperator.class);
051
052        //KnowledgeBase kb;
053        private static final double d = 0.5;
054        @NoConfigOption
055        private ArrayList<OWLClass> allConcepts;
056        @NoConfigOption
057        private ArrayList<OWLObjectProperty> allRoles;
058        @ConfigOption(description = "the learning problem instance to use")
059        private PosNegLP lp;
060        private Random generator;
061        public static final int ORIGINAL=3; //predefined constants
062        public static final int RHO=1;
063        public static final int PSI=2;
064
065        //private OWLDataFactory dataFactory;
066        @ConfigOption(description = "the reasoner instance to use")
067        private Reasoner reasoner;
068        protected OWLDataFactory dataFactory = new OWLDataFactoryImpl();
069
070        @ConfigOption(defaultValue = "5")
071        private int beam;
072
073        @ConfigOption(defaultValue = "1")
074        private int ro; // the name of a refinement operator
075        //
076        //
077        //
078        public int getRo() {
079                return ro;
080        }
081
082        public void setRo(int ro) {
083                this.ro = ro;
084        }
085
086        public DLTreesRefinementOperator() {
087                super();
088
089                generator= new Random(2);
090        }
091
092        public DLTreesRefinementOperator(PosNegLP lp, AbstractReasonerComponent reasoner, int beam) {
093                super();
094                // TODO Auto-generated constructor stub
095                this.reasoner=reasoner;
096                //System.out.println("is Reasoner null? "+reasoner==null);
097                allConcepts= new ArrayList<>(reasoner.getClasses());
098                //System.out.println("all+ Concepts: "+allConcepts.size());
099                allRoles= new ArrayList<>(reasoner.getObjectProperties());
100                //this.beam=beam; // set the maximum number of candidates that can be generated
101                this.lp=lp;
102                generator= new Random(2);
103
104        }
105
106        public PosNegLP getLp() {
107                return lp;
108        }
109
110        public void setLp(PosNegLP lp) {
111                this.lp = lp;
112        }
113
114        public ArrayList<OWLClass> getAllConcepts() {
115                return allConcepts;
116        }
117
118        public void setAllConcepts(ArrayList<OWLClass> allConcepts) {
119                this.allConcepts = allConcepts;
120        }
121
122        public ArrayList<OWLObjectProperty> getAllRoles() {
123                return allRoles;
124        }
125
126        public void setAllRoles(ArrayList<OWLObjectProperty> allRoles) {
127                this.allRoles = allRoles;
128        }
129
130        /**
131         * Random concept generation
132         * @return
133         */
134        public OWLClassExpression getRandomConcept() {
135
136                OWLClassExpression newConcept = null;
137                boolean binaryclassification= false; //TODO eliminare
138                //System.out.println("*********"+ generator);
139                if (!binaryclassification){
140                        // case A:  ALC and more expressive ontologies
141                        do {
142
143                                //System.out.println("No of classes: "+allConcepts.isEmpty());
144                                newConcept = allConcepts.get(generator.nextInt(allConcepts.size()));
145                                if (generator.nextDouble() < d) {
146                                        OWLClassExpression newConceptBase =     getRandomConcept();
147                                        if (generator.nextDouble() < d) {
148
149                                                if (generator.nextDouble() <d) { // new role restriction
150                                                        OWLObjectProperty role = allRoles.get(generator.nextInt(allRoles.size()));
151                                                        //                                      OWLDescription roleRange = (OWLDescription) role.getRange
152                                                        if (generator.nextDouble() < d)
153                                                                newConcept = dataFactory.getOWLObjectAllValuesFrom(role, newConceptBase);
154                                                        else
155                                                                newConcept = dataFactory.getOWLObjectSomeValuesFrom(role, newConceptBase);
156                                                }
157                                                else
158                                                        newConcept = dataFactory.getOWLObjectComplementOf(newConceptBase);
159                                        }
160                                }
161
162                        } while (!(reasoner.getIndividuals(newConcept).size()>0) );
163
164                }
165                else{
166                        // for less expressive ontologies, e.g ALE
167                        do {
168                                newConcept = allConcepts.get(generator.nextInt(allConcepts.size()));
169                                if (generator.nextDouble() < d) {
170                                        OWLClassExpression newConceptBase =  getRandomConcept(); //dataFactory.getOWLThing(); //
171                                        if (generator.nextDouble() < d)
172                                                if (generator.nextDouble() < d) { // new role restriction
173                                                        OWLObjectProperty role = allRoles.get(generator.nextInt(allRoles.size()));
174                                                        //                                      OWLDescription roleRange = (OWLDescription) role.getRange;
175
176                                                        if (generator.nextDouble() < d)
177                                                                newConcept = dataFactory.getOWLObjectAllValuesFrom(role, newConceptBase);
178                                                        else
179                                                                newConcept = dataFactory.getOWLObjectSomeValuesFrom(role, newConceptBase);
180                                                }
181                                } // else ext
182                                else //if (KnowledgeBase.generator.nextDouble() > 0.8) {
183                                        newConcept = dataFactory.getOWLObjectComplementOf(newConcept);
184
185                        } while (!(reasoner.getIndividuals(newConcept).size()>0));
186                }
187                //System.out.println("*********");
188                return newConcept;
189        }
190
191        public SortedSet<OWLClassExpression>generateNewConcepts(SortedSet<OWLIndividual> posExs, SortedSet<OWLIndividual> negExs, boolean seed) {
192
193                logger.info("Generating node concepts ");
194                TreeSet<OWLClassExpression> rConcepts = new TreeSet<>();
195
196                OWLClassExpression newConcept=null;
197                boolean emptyIntersection;
198                for (int c=0; c<beam; c++) {
199
200                        do {
201                                emptyIntersection =  false;
202                                //System.out.println("Before the try");
203                                //                                      try{
204                                //System.out.println("---------->");
205                                newConcept = getRandomConcept();
206                                logger.info(c+"-  New Concept: "+newConcept);
207                                SortedSet<OWLIndividual> individuals;
208
209                                individuals = (reasoner.getIndividuals(newConcept));
210                                Iterator<OWLIndividual> instIterator = individuals.iterator();
211                                while (emptyIntersection && instIterator.hasNext()) {
212                                        Node<OWLNamedIndividual> nextInd = (Node<OWLNamedIndividual>) instIterator.next();
213                                        int index = -1;
214                                        ArrayList<OWLIndividual> individuals2 = new ArrayList<>(reasoner.getIndividuals());
215                                        for (int i=0; index<0 && i<individuals2.size(); ++i)
216                                                if (nextInd.equals(individuals2)) index = i;
217                                        if (posExs.contains(index))
218                                                emptyIntersection = false;
219                                        else if (negExs.contains(index))
220                                                emptyIntersection = false;
221                                }
222
223                        } while (emptyIntersection);
224                        //if (newConcept !=null){
225                        System.out.println(newConcept==null);
226                        rConcepts.add(newConcept);
227                        //}
228
229                }
230                System.out.println();
231
232                logger.debug(""+rConcepts.size());
233                return rConcepts;
234        }
235
236        private OWLClassExpression setSeed() {
237
238                //for (OWLClassExpression cl: allConcepts){
239                //if (cl.toString().compareToIgnoreCase(conceptSeed)==0){
240                //return cl;
241                //}
242
243                //}
244                return null;
245        }
246
247        @Override
248        public Set<OWLClassExpression> refine(OWLClassExpression description) {
249                // this method calls the naive refinement operator for DLTree
250                return null;
251        }
252
253        @Override
254        public void init() throws ComponentInitException {
255                // TODO Auto-generated method stub
256
257                //              allConcepts=new ArrayList<OWLClass>(reasoner.getClasses());
258                //              //System.out.println("all Concepts: "+allConcepts.size());
259                //              allRoles= new ArrayList<OWLObjectProperty>(reasoner.getObjectProperties());
260                //this.beam=beam; // set the maximum number of candidates that can be generated
261                generator= new Random(2);
262
263                //              if (beam==0)
264                //                      setBeam(4); // a default value
265
266        }
267
268     //
269        public void setReasoner(AbstractReasonerComponent reasoner) {
270                // TODO Auto-generated method stub
271                this.reasoner= reasoner;
272                if (allConcepts==null)
273                        allConcepts= new ArrayList<>(reasoner.getClasses());
274                //System.out.println("all+ Concepts: "+allConcepts.size());
275                if (allRoles==null)
276                        allRoles= new ArrayList<>(reasoner.getObjectProperties());
277
278        }
279
280        
281        @Override
282        public void setReasoner(Reasoner reasoner) {
283                // TODO Auto-generated method stub
284                this.reasoner= reasoner;
285                if (allConcepts==null)
286                        allConcepts= new ArrayList<>(reasoner.getClasses());
287                //System.out.println("all+ Concepts: "+allConcepts.size());
288                if (allRoles==null)
289                        allRoles= new ArrayList<>(reasoner.getObjectProperties());
290
291        }
292
293        @Override
294        public Set<OWLClassExpression> refine(OWLClassExpression definition, SortedSet<OWLIndividual> posExs,
295                        SortedSet<OWLIndividual> negExs) {
296
297                Set<OWLClassExpression> children;
298                int n=-1; // initialization
299                ArrayList<OWLClassExpression> childrenList= new ArrayList<>();
300                OWLClassExpression def= definition;
301                
302                if ((!definition.isOWLThing())&&(!definition.isOWLNothing())){
303                        children = OWLClassExpressionUtils.getChildren(def);
304                        
305                        Random rg= new Random();
306
307                        if (children.size()>0){
308                                n= rg.nextInt(children.size());
309                                childrenList= new ArrayList<>(children);
310
311                        }
312                }
313
314                if (ro==RHO){
315                        RhoDRDown rho = new RhoDRDown();
316
317                        rho.setReasoner((AbstractReasonerComponent)reasoner);
318                        ClassHierarchy classHierarchy = (ClassHierarchy) reasoner.getClassHierarchy();
319                        rho.setClassHierarchy(classHierarchy);
320                        rho.setObjectPropertyHierarchy(reasoner.getObjectPropertyHierarchy());
321                        rho.setDataPropertyHierarchy(reasoner.getDatatypePropertyHierarchy());
322
323                        rho.setApplyAllFilter(false);
324                        rho.setUseAllConstructor(true);
325                        rho.setUseExistsConstructor(true);
326                        rho.setUseHasValueConstructor(false);
327                        rho.setUseCardinalityRestrictions(false);
328                        rho.setUseNegation(true);
329                        rho.setUseBooleanDatatypes(false);
330                        rho.setUseNumericDatatypes(false);
331                        rho.setUseStringDatatypes(false);
332
333                        try {
334                                rho.init();
335                        } catch (ComponentInitException e) {
336                                // TODO Auto-generated catch block
337                                e.printStackTrace();
338                        }
339                        //              System.out.println("Definition: "+definition);
340                        
341                        OWLClassExpression toRefine= (n!=-1)?childrenList.get(n):def;
342                        Set<OWLClassExpression> refine = rho.refine(toRefine,3);
343
344                        //System.out.println("Refine size: "+ refine);
345                        return refine;
346
347                }else if (ro==PSI){
348                        PsiDown psiDown=null;
349                        
350                        if (reasoner instanceof AbstractReasonerComponent){
351                          psiDown= new PsiDown(lp,(AbstractReasonerComponent)reasoner);
352
353                        }else
354                                throw new RuntimeException("Psi Down cannot be instantiated");
355                        
356//                      ClassHierarchy classHierarchy = (ClassHierarchy) r.getClassHierarchy();
357                        
358                Set<OWLClassExpression> refine = psiDown.refine(definition);
359                return refine;
360
361                }
362                else
363                        return (generateNewConcepts(posExs, negExs, false));
364                
365                
366        }
367
368        public void setBeam(int i) {
369                // TODO Auto-generated method stub
370                beam=i;
371
372        }
373
374        public int getBeam() {
375                return beam;
376        }
377
378        
379
380}