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}