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.dsttdt.models;
020
021import org.dllearner.algorithms.decisiontrees.dsttdt.dst.MassFunction;
022import org.dllearner.algorithms.decisiontrees.tdt.model.AbstractTree;
023import org.semanticweb.owlapi.model.OWLClass;
024import org.semanticweb.owlapi.model.OWLClassExpression;
025import org.semanticweb.owlapi.model.OWLDataFactory;
026import uk.ac.manchester.cs.owl.owlapi.OWLDataFactoryImpl;
027
028import java.util.ArrayList;
029import java.util.HashSet;
030import java.util.Set;
031public class DSTDLTree extends AbstractTree implements EvidentialModel{
032
033        private class DLNode {
034                OWLClassExpression concept;     // node concept
035                
036                DSTDLTree pos;                  // positive decision subtree
037                DSTDLTree neg;  // negative decision subtree
038                @SuppressWarnings("rawtypes")
039                MassFunction m;
040                @SuppressWarnings("rawtypes")
041                public DLNode(OWLClassExpression c, MassFunction m) {
042                        concept = c;
043                        this.pos = this.neg = null; // node has no children
044                        this.m= m; // Dempster-Shafer extension
045                }
046
047//              public DLNode() {
048//                      concept = null;
049////                    this.pos = this.neg = null; // node has no children
050//              }
051                
052
053                public String toString() {
054                        return this.concept.toString();
055                }
056                
057                @Override
058                public Object clone(){
059                        return new DLNode(concept,m);
060                }
061                
062        }
063        
064
065        private DLNode root; // Tree root
066        
067        
068        public DSTDLTree () {
069                this.root = null;
070                
071        
072        }
073        
074        @SuppressWarnings("rawtypes")
075        public DSTDLTree (OWLClassExpression c, MassFunction m) {               
076                this.root = new DLNode(c,m);
077        
078        }
079
080        /**
081         * @param concept the root concept to set
082         */
083        @SuppressWarnings("rawtypes")
084        public void setRoot(OWLClassExpression concept, MassFunction m) {
085                this.root = new DLNode(concept, m);
086//              this.root.concept = concept;
087        }
088
089        /**
090         * @return the root
091         */
092        public OWLClassExpression getRoot() {
093                return root.concept;
094        }
095        
096        @SuppressWarnings("rawtypes")
097        public MassFunction getRootBBA() {
098                return root.m;
099        }
100
101        public void setPosTree(DSTDLTree subTree) {
102                //System.out.println("--->"+(this.root==null));
103                this.root.pos = subTree;
104                
105        }
106
107        public void setNegTree(DSTDLTree subTree) {
108                
109                this.root.neg = subTree;
110                
111        }
112        
113        public String toString() {
114                if (root.pos == null && root.neg == null)
115                        return root.toString();
116                else
117                        return root.concept.toString() + " ["+root.pos.toString()+"  "+root.neg.toString()+"]";
118        }
119
120        public DSTDLTree getPosSubTree() {
121                // TODO Auto-generated method stub
122                return root.pos;
123        }
124
125        public DSTDLTree getNegSubTree() {
126                // TODO Auto-generated method stub
127                return root.neg;
128        }
129        
130        @Override
131        public Object clone(){
132                DSTDLTree elem= new DSTDLTree();
133                DLNode cloned= (DLNode)root.clone(); 
134                elem.setRoot(cloned.concept, cloned.m);
135                if (root.pos != null){ // copy the positive tree
136                
137                        elem.root.pos= (DSTDLTree)(root.pos).clone();
138                        
139                }
140                if (root.neg!=null){ // copy the negative tree
141                        elem.root.neg=  (DSTDLTree)(root.neg).clone();
142                        
143                }
144                
145                return elem;
146        }
147        
148        
149        
150        
151        private double getNodes(){
152        
153                
154                ArrayList<DLNode> list = new ArrayList<>();
155                double  num=0;
156                if(root!=null){
157                        list.add(root);
158                        while(!list.isEmpty()){
159                                DLNode node= list.get(0);
160                                list.remove(0);
161                                num++;
162                                DLNode sx=null;
163                                if(node.pos!=null){
164                                        sx= node.pos.root;
165                                        if(sx!=null)
166                                         list.add(sx);
167                                }
168                                if(node.neg!=null){
169                                 sx= node.neg.root;
170                                 if(sx!=null)
171                                         list.add(sx);
172                                }
173                                         
174                        }
175                        
176                }
177                
178                return num;
179                
180        }
181
182        @Override
183        public double getComplexityMeasure() {
184                
185                return getNodes();
186        }
187        
188
189        private static void associate(DSTDLTree tree, OWLDataFactory df, OWLClass leaf, OWLClassExpression currentConceptDescription,  Set<OWLClassExpression> set){
190                
191                if ((tree.root.pos==null)&&(tree.root.neg==null)){
192                        if (tree.root.concept.compareTo(leaf)==0){
193                                
194                                set.add(currentConceptDescription);
195                        }
196                }
197                else{
198                        //OWLDataFactory dataFactory = new OWLDataFactoryImpl();
199                        // tail recursive calls
200                        associate(tree.getPosSubTree(),df,leaf, df.getOWLObjectIntersectionOf(currentConceptDescription, tree.root.concept),set);
201                        associate(tree.getNegSubTree(),df, leaf, df.getOWLObjectIntersectionOf(currentConceptDescription, tree.root.concept),set);
202                }
203        
204        }
205        
206        /**
207         * Return a concept definition from a DSTDLTree (both the positive and the negative instances) A theoretical problems concerns the way in which BBAs must be considered. 
208         * In this case, may there exists a DL-based representation language for representing intensionally the concept and the BBAs?
209         * @param tree
210         * @param conceptFromPositiveIstances
211         * @return
212         */
213        public static OWLClassExpression deriveDefinition(DSTDLTree tree, boolean conceptFromPositiveIstances){
214        
215    HashSet<OWLClassExpression> exp= new HashSet<>();
216
217    OWLDataFactory dataFactory = new OWLDataFactoryImpl();
218    if (conceptFromPositiveIstances)
219        associate(tree, dataFactory, dataFactory.getOWLThing(), dataFactory.getOWLThing(), exp);
220    else
221        associate(tree, dataFactory, dataFactory.getOWLNothing(), dataFactory.getOWLThing(), exp);
222    if(exp.isEmpty())
223                return dataFactory.getOWLThing();
224        else 
225                return dataFactory.getOWLObjectUnionOf(exp);
226        
227        }
228
229        
230}