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.tdt.model;
020
021import java.util.ArrayList;
022import java.util.HashSet;
023import java.util.List;
024import java.util.Set;
025import java.util.Stack;
026
027//import knowledgeBasesHandler.KnowledgeBase;
028
029import org.semanticweb.owlapi.model.OWLClass;
030import org.semanticweb.owlapi.model.OWLClassExpression;
031import org.semanticweb.owlapi.model.OWLDataFactory;
032
033import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl;
034
035public class DLTree extends AbstractTree {
036
037        private int match, omission, commission, induction;
038
039        /* (non-Javadoc)
040         * @see algorithms.trees.models.AbstractTree#getMatch()
041         */
042        @Override
043        public int getMatch() {
044                return match;
045        }
046
047        /* (non-Javadoc)
048         * @see algorithms.trees.models.AbstractTree#setMatch(int)
049         */
050        @Override
051        public void setMatch(int match) {
052                this.match++;
053        }
054
055        /* (non-Javadoc)
056         * @see algorithms.trees.models.AbstractTree#getOmission()
057         */
058        @Override
059        public int getOmission() {
060                return omission;
061        }
062
063        /* (non-Javadoc)
064         * @see algorithms.trees.models.AbstractTree#setOmission(int)
065         */
066        @Override
067        public void setOmission(int omission) {
068                this.omission++;
069        }
070
071        /* (non-Javadoc)
072         * @see algorithms.trees.models.AbstractTree#getCommission()
073         */
074        @Override
075        public int getCommission() {
076                return commission;
077        }
078
079        /* (non-Javadoc)
080         * @see algorithms.trees.models.AbstractTree#setCommission(int)
081         */
082        @Override
083        public void setCommission(int commission) {
084                this.commission++;
085        }
086
087        /* (non-Javadoc)
088         * @see algorithms.trees.models.AbstractTree#getInduction()
089         */
090        @Override
091        public int getInduction() {
092                return induction;
093        }
094
095        /* (non-Javadoc)
096         * @see algorithms.trees.models.AbstractTree#setInduction(int)
097         */
098        @Override
099        public void setInduction(int induction) {
100                this.induction++;
101        }
102        int nFoglie;
103        private class DLNode {
104
105                OWLClassExpression concept;             // node concept
106                DLTree pos;                     // positive decision subtree
107                DLTree neg;                     // negative decision subtree
108
109                public DLNode(OWLClassExpression c) {
110                        concept = c;
111                        this.pos = this.neg = null; // node has no children
112                }
113
114                //              public DLNode() {
115                //                      concept = null;
116                ////                    this.pos = this.neg = null; // node has no children
117                //              }
118
119                public String toString() {
120                        return this.concept.toString();
121                }
122
123        }
124
125        private DLNode root; // Tree root
126
127        public DLTree () {
128                this.root = null;
129        }
130
131        public DLTree (OWLClassExpression c) {          
132                this.root = new DLNode(c);
133        }
134
135        /**
136         * @param concept the root concept to set
137         */
138        public void setRoot(OWLClassExpression concept) {
139                this.root = new DLNode(concept);
140                //              this.root.concept = concept;
141        }
142
143        /**
144         * @return the root
145         */
146        public OWLClassExpression getRoot() {
147                return root.concept;
148        }
149
150        public void setPosTree(DLTree subTree) {
151                this.root.pos = subTree;
152
153        }
154
155        public void setNegTree(DLTree subTree) {
156
157                this.root.neg = subTree;
158
159        }
160
161        public String toString() {
162//              if (root==null)
163//                      return null;
164//              if (root.pos == null && root.neg == null)
165//                      return root.toString();
166//              else
167//                      return root.concept.toString() + " ["+root.pos.toString()+" "+root.neg.toString()+"]";
168                
169                String string="";
170                Stack<DLTree> stack= new Stack<>();
171                stack.push(this);
172                DLTree currenttree=null;
173                while(!stack.isEmpty()){
174                        currenttree=stack.pop();
175                        string+= this.root.concept.toString(); // current node
176                        if (root.pos != null)  {
177                                stack.push(root.pos);
178                                string+="[";
179                        }
180                        if(root.neg != null){
181                                stack.push(root.neg);
182                                string+="]";
183                        }
184
185                        
186                }
187                return string;
188                
189        }
190
191        public DLTree getPosSubTree() {
192                return root.pos;
193        }
194
195        public DLTree getNegSubTree() {
196
197                return root.neg;
198        }
199
200        private double getNodes(){
201
202                ArrayList<DLNode> list = new ArrayList<>();
203                double  num=0;
204                if(root!=null){
205                        list.add(root);
206                        while(!list.isEmpty()){
207                                DLNode node= list.get(0);
208                                list.remove(0);
209                                num++;
210                                DLNode sx=null;
211                                if(node.pos!=null){
212                                        sx= node.pos.root;
213                                        if(sx!=null)
214                                                list.add(sx);
215                                }
216                                if(node.neg!=null){
217                                        sx= node.neg.root;
218                                        if(sx!=null)
219                                                list.add(sx);
220                                }
221
222                        }
223
224                }
225
226                return num;
227
228        }
229
230        @Override
231        public double getComplexityMeasure() {
232                // TODO Auto-generated method stub
233                return getNodes();
234        }
235
236        public List<DLTree> getLeaves(){
237                ArrayList<DLTree> leaves= new ArrayList<>();
238
239                ArrayList<DLTree> list = new ArrayList<>();
240
241                if(root!=null){
242                        list.add(this);
243                        while(!list.isEmpty()){
244                                DLTree current= list.get(0);
245                                list.remove(0);
246                                if ((current.getPosSubTree()==null)&&(current.getNegSubTree()==null))
247                                        leaves.add(current);
248
249                                else{
250                                        if(current.getPosSubTree()!=null)
251                                                list.add(current.getPosSubTree());
252
253                                        if (current.getNegSubTree()!=null)
254                                                list.add(current.getNegSubTree());
255                                }
256                        }
257
258                }
259
260                return leaves;
261
262        }
263
264        private static void associate(DLTree tree, OWLDataFactory df, OWLClass leaf, OWLClassExpression currentConceptDescription,  Set<OWLClassExpression> set){
265        
266                if ((tree.root.pos==null)&&(tree.root.neg==null)){
267                        if (tree.root.concept.compareTo(leaf)==0){
268                                
269                                set.add(currentConceptDescription);
270                        }
271                }
272                else{
273                        //OWLDataFactory dataFactory = new OWLDataFactoryImpl();
274                        // tail recursive calls
275                        associate(tree.getPosSubTree(),df,leaf, df.getOWLObjectIntersectionOf(currentConceptDescription, tree.root.concept),set);
276                        associate(tree.getNegSubTree(),df, leaf, df.getOWLObjectIntersectionOf(currentConceptDescription, tree.root.concept),set);
277                }
278        
279        }
280        
281        /**
282         * Return a concept definition from a DLTree (both the positive and the negative instances)
283         * @param tree
284         * @param conceptFromPositiveIstances
285         * @return
286         */
287        public static OWLClassExpression deriveDefinition(DLTree tree, boolean conceptFromPositiveIstances){
288        
289    HashSet<OWLClassExpression> exp= new HashSet<>();
290
291    OWLDataFactory dataFactory = new OWLDataFactoryImpl();
292    if (conceptFromPositiveIstances)
293        associate(tree, dataFactory, dataFactory.getOWLThing(), dataFactory.getOWLThing(), exp);
294    else
295        associate(tree, dataFactory, dataFactory.getOWLNothing(), dataFactory.getOWLThing(), exp);
296    if(exp.isEmpty())
297                return dataFactory.getOWLThing();
298        else 
299                return dataFactory.getOWLObjectUnionOf(exp);
300        
301        }
302
303}