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.utilities.split;
020
021import java.util.ArrayList;
022import java.util.List;
023import java.util.Map;
024import java.util.Map.Entry;
025import java.util.Set;
026import java.util.SortedSet;
027import java.util.TreeSet;
028
029import org.dllearner.core.AbstractReasonerComponent;
030import org.semanticweb.owlapi.model.OWLDataFactory;
031import org.semanticweb.owlapi.model.OWLDataProperty;
032import org.semanticweb.owlapi.model.OWLIndividual;
033import org.semanticweb.owlapi.model.OWLLiteral;
034
035/**
036 * A splitter for numeric values which simply returns a fixed number of split
037 * values.
038 * Given k is the maximal number of values
039 * used for the refinement of a data property, the assertion
040 * values of the data property are split into k equal parts and
041 * the middle values of split parts are used for refinement (they
042 * are rounded for the integer datatype).
043 * Supposed we have a set of integer values
044 * {1, 2, 3, 4, 5, 6, 10, 12, 16, 20, 28, 30} and use 4 splits, then
045 * we would get 5 split values [1, 3, 8, 18, 30].
046 * 
047 * @author Lorenz Buehmann
048 *
049 */
050public class DefaultNumericValuesSplitter extends AbstractNumericValuesSplitter {
051
052        private int maxNrOfSplits = 10;
053
054        public DefaultNumericValuesSplitter(AbstractReasonerComponent reasoner, OWLDataFactory dataFactory, int maxNrOfSplits) {
055                super(reasoner, dataFactory);
056                this.maxNrOfSplits = maxNrOfSplits;
057        }
058
059        public DefaultNumericValuesSplitter(AbstractReasonerComponent reasoner,
060                        OWLDataFactory dataFactory) {
061                super(reasoner, dataFactory);
062        }
063
064        /**
065         * @param maxNrOfSplits the maximal number of splits
066         */
067        public void setMaxNrOfSplits(int maxNrOfSplits) {
068                this.maxNrOfSplits = maxNrOfSplits;
069        }
070        
071        /* (non-Javadoc)
072         * @see org.dllearner.utilities.split.AbstractValuesSplitter#computeSplits(org.semanticweb.owlapi.model.OWLDataProperty)
073         */
074        @Override
075        public List<OWLLiteral> computeSplits(OWLDataProperty dp) {
076                List<OWLLiteral> splitLiterals = new ArrayList<>();
077                
078                List<? extends Number> splitValues = computeSplitValues(dp);
079                for (Number value : splitValues) {
080                        OWLLiteral literal = dataFactory.getOWLLiteral(value.toString(), reasoner.getDatatype(dp));
081                        splitLiterals.add(literal);
082                }
083                
084                return splitLiterals;
085        }
086        
087        private <T extends Number & Comparable<T>> List<T> computeSplitValues(OWLDataProperty dp) {
088                Set<T> valuesSet = new TreeSet<>();
089
090                Map<OWLIndividual, SortedSet<T>> ind2Values = reasoner.getNumericDatatypeMembers(dp);
091                // add all values to the set
092                for(Entry<OWLIndividual, SortedSet<T>> e : ind2Values.entrySet()){
093                        try {
094                                valuesSet.addAll(e.getValue());
095                        } catch(ClassCastException ce) {
096                                System.err.println("Mixed datatypes in "+dp.toStringID());
097                                throw ce;
098                        }
099                }
100
101                return simpleListSplitter(valuesSet, maxNrOfSplits);
102        }
103}