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.properties;
020
021import java.util.Set;
022
023import org.dllearner.core.ComponentAnn;
024import org.dllearner.core.EvaluatedAxiom;
025import org.dllearner.kb.SparqlEndpointKS;
026import org.dllearner.learningproblems.AxiomScore;
027import org.dllearner.learningproblems.Heuristics;
028import org.semanticweb.owlapi.model.AxiomType;
029import org.semanticweb.owlapi.model.IRI;
030import org.semanticweb.owlapi.model.OWLDataProperty;
031import org.semanticweb.owlapi.model.OWLDataPropertyAssertionAxiom;
032import org.semanticweb.owlapi.model.OWLDataPropertyRangeAxiom;
033import org.semanticweb.owlapi.model.OWLDataRange;
034
035import org.apache.jena.query.ParameterizedSparqlString;
036import org.apache.jena.query.QuerySolution;
037import org.apache.jena.query.ResultSet;
038
039@ComponentAnn(name="data property range learner", shortName="dblrange", version=0.1, description="A learning algorithm for reflexive data property range axioms.")
040public class DataPropertyRangeAxiomLearner extends DataPropertyAxiomLearner<OWLDataPropertyRangeAxiom> {
041        
042        private static final ParameterizedSparqlString DATATYPE_FREQUENCY_QUERY = new ParameterizedSparqlString(
043                        "SELECT  ?dt (count(distinct ?o) AS ?cnt)\n" + 
044                        "WHERE\n" + 
045                        "  { ?s ?p ?o }\n" + 
046                        "GROUP BY (datatype(?o) AS ?dt)");
047        
048        public DataPropertyRangeAxiomLearner(SparqlEndpointKS ks){
049                this.ks = ks;
050                super.posExamplesQueryTemplate = new ParameterizedSparqlString("SELECT ?s WHERE {?o ?p ?s. FILTER (DATATYPE(?s) = ?dt)}");
051                super.negExamplesQueryTemplate = new ParameterizedSparqlString("SELECT ?s WHERE {?o ?p ?s. FILTER (DATATYPE(?s) != ?dt)}");
052                
053                COUNT_QUERY = DISTINCT_OBJECTS_COUNT_QUERY;
054                
055                axiomType = AxiomType.DATA_PROPERTY_RANGE;
056        }
057        
058        /* (non-Javadoc)
059         * @see org.dllearner.core.AbstractAxiomLearningAlgorithm#getExistingAxioms()
060         */
061        @Override
062        protected void getExistingAxioms() {
063                OWLDataRange existingRange = reasoner.getRange(entityToDescribe);
064                if(existingRange != null){
065                        existingAxioms.add(df.getOWLDataPropertyRangeAxiom(entityToDescribe, existingRange));
066                }
067        }
068        
069        /* (non-Javadoc)
070         * @see org.dllearner.core.AbstractAxiomLearningAlgorithm#setEntityToDescribe(org.semanticweb.owlapi.model.OWLEntity)
071         */
072        @Override
073        public void setEntityToDescribe(OWLDataProperty entityToDescribe) {
074                super.setEntityToDescribe(entityToDescribe);
075                
076                DATATYPE_FREQUENCY_QUERY.setIri("p", entityToDescribe.toStringID());
077        }
078        
079        /* (non-Javadoc)
080         * @see org.dllearner.algorithms.properties.PropertyAxiomLearner#run()
081         */
082        @Override
083        protected void run() {
084                // get the frequency for each datatype
085                ResultSet rs = executeSelectQuery(DATATYPE_FREQUENCY_QUERY.toString());
086                while (rs.hasNext()) {
087                        QuerySolution qs = rs.next();
088
089                        // datatype
090                        String datatypeURI = qs.getResource("dt").getURI();
091
092                        // frequency of datatype
093                        int frequency = qs.getLiteral("cnt").getInt();
094
095                        // precision (A AND B)/B
096                        double precision = Heuristics.getConfidenceInterval95WaldAverage(popularity, frequency);
097
098                        // score
099                        /* TODO: currently the score is rather simple, but it's not clear whether it makes sense to take
100                         also the total number of literals with given datatype into account
101                         */
102                        double score = precision;
103                        
104                        int nrOfPosExamples = frequency;
105                        
106                        int nrOfNegExamples = popularity - nrOfPosExamples;
107                        
108                        currentlyBestAxioms.add(new EvaluatedAxiom<>(
109                                        df.getOWLDataPropertyRangeAxiom(entityToDescribe, df.getOWLDatatype(IRI.create(datatypeURI))),
110                                        new AxiomScore(score, score, nrOfPosExamples, nrOfNegExamples, useSampling)));
111
112                }
113
114        }
115        
116        @Override
117        public Set<OWLDataPropertyAssertionAxiom> getPositiveExamples(EvaluatedAxiom<OWLDataPropertyRangeAxiom> evAxiom) {
118                OWLDataPropertyRangeAxiom axiom = evAxiom.getAxiom();
119                posExamplesQueryTemplate.setIri("dt", axiom.getRange().toString());
120                return super.getPositiveExamples(evAxiom);
121        }
122        
123        @Override
124        public Set<OWLDataPropertyAssertionAxiom> getNegativeExamples(EvaluatedAxiom<OWLDataPropertyRangeAxiom> evAxiom) {
125                OWLDataPropertyRangeAxiom axiom = evAxiom.getAxiom();
126                negExamplesQueryTemplate.setIri("dt", axiom.getRange().toString());
127                return super.getNegativeExamples(evAxiom);
128        }
129
130        
131}