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}