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; 020 021import com.google.common.base.StandardSystemProperty; 022import com.google.common.collect.Sets; 023import org.apache.jena.query.ParameterizedSparqlString; 024import org.apache.jena.query.QueryExecution; 025import org.apache.jena.rdf.model.Model; 026import org.apache.jena.rdf.model.Statement; 027import org.apache.jena.rdf.model.StmtIterator; 028import org.aksw.jena_sparql_api.pagination.core.QueryExecutionFactoryPaginated; 029import org.dllearner.algorithms.celoe.CELOE; 030import org.dllearner.core.AbstractAxiomLearningAlgorithm; 031import org.dllearner.core.AbstractClassExpressionLearningProblem; 032import org.dllearner.core.AbstractReasonerComponent; 033import org.dllearner.core.ComponentInitException; 034import org.dllearner.kb.OWLAPIOntology; 035import org.dllearner.kb.SparqlEndpointKS; 036import org.dllearner.kb.sparql.SparqlEndpoint; 037import org.dllearner.learningproblems.PosNegLPStandard; 038import org.dllearner.reasoning.ClosedWorldReasoner; 039import org.dllearner.utilities.OwlApiJenaUtils; 040import org.dllearner.utilities.owl.OWLEntityTypeAdder; 041import org.semanticweb.owlapi.formats.RDFXMLDocumentFormat; 042import org.semanticweb.owlapi.model.*; 043import uk.ac.manchester.cs.owl.owlapi.OWLClassImpl; 044 045import java.io.File; 046import java.io.FileNotFoundException; 047import java.io.FileOutputStream; 048import java.util.Set; 049import java.util.SortedSet; 050 051//import org.dllearner.utilities.OwlApiJenaUtils; 052 053/** 054 * A wrapper class for CELOE that allows for returning the result in forms of OWL axioms. 055 * @author Lorenz Buehmann 056 * 057 */ 058// not for conf 059public class CELOEWrapper extends AbstractAxiomLearningAlgorithm<OWLClassAxiom, OWLIndividual, OWLClass> { 060 061 private boolean equivalence = true; 062 063 private int maxClassExpressionDepth = 2; 064 065 private int maxNrOfPosExamples = 10; 066 private int maxNrOfNegExamples = 20; 067 068 private static final ParameterizedSparqlString SAMPLE_QUERY = new ParameterizedSparqlString( 069 "CONSTRUCT {?s a ?entity . ?s a ?cls . ?cls a <http://www.w3.org/2002/07/owl#Class> .} " 070 + "WHERE {?s a ?entity . OPTIONAL {?s a ?cls . ?cls a <http://www.w3.org/2002/07/owl#Class> . FILTER(!sameTerm(?cls, ?entity))}}"); 071 072 public CELOEWrapper(SparqlEndpointKS ks) { 073 super.ks = ks; 074 useSampling = false; 075 076 } 077 078 /* (non-Javadoc) 079 * @see org.dllearner.core.AbstractAxiomLearningAlgorithm#getExistingAxioms() 080 */ 081 @Override 082 protected void getExistingAxioms() { 083 if(equivalence){ 084 SortedSet<OWLClassExpression> equivalentClasses = reasoner.getEquivalentClasses(entityToDescribe); 085 for (OWLClassExpression equivCls : equivalentClasses) { 086 existingAxioms.add(df.getOWLEquivalentClassesAxiom(entityToDescribe, equivCls)); 087 } 088 } else { 089 SortedSet<OWLClassExpression> superClasses = reasoner.getSuperClasses(entityToDescribe); 090 for (OWLClassExpression supCls : superClasses) { 091 existingAxioms.add(df.getOWLSubClassOfAxiom(entityToDescribe, supCls)); 092 } 093 } 094 } 095 096 /* (non-Javadoc) 097 * @see org.dllearner.core.AbstractAxiomLearningAlgorithm#learnAxioms() 098 */ 099 @Override 100 protected void learnAxioms() { 101 // get the popularity of the class 102 int popularity = reasoner.getPopularity(entityToDescribe); 103 104 // we have to skip here if there are not instances for the given class 105 if (popularity == 0) { 106 logger.warn("Cannot compute statements for empty class " + entityToDescribe); 107 return; 108 } 109 110 // get positive examples 111 SortedSet<OWLIndividual> posExamples = reasoner.getIndividuals(entityToDescribe, maxNrOfPosExamples ); 112 113 // get negative examples 114 SortedSet<OWLIndividual> negExamples = Sets.newTreeSet(); 115 116 OWLOntology fragment = buildFragment(posExamples, negExamples); 117 try { 118 fragment.getOWLOntologyManager().saveOntology(fragment, new RDFXMLDocumentFormat(), new FileOutputStream(System.getProperty("java.io.tmpdir") + File.separator + "ont.owl")); 119 } catch (OWLOntologyStorageException | FileNotFoundException e1) { 120 // TODO Auto-generated catch block 121 e1.printStackTrace(); 122 } 123 try { 124 AbstractReasonerComponent rc = new ClosedWorldReasoner(new OWLAPIOntology(fragment)); 125 rc.init(); 126 127 AbstractClassExpressionLearningProblem lp = new PosNegLPStandard(rc, posExamples, negExamples); 128 lp.init(); 129 130 CELOE la = new CELOE(lp, rc); 131 la.init(); 132 133 la.start(); 134 } catch (ComponentInitException e) { 135 logger.error("CELOE execution failed.", e); 136 } 137 } 138 139 private OWLOntology buildFragment(Set<OWLIndividual> posExamples, Set<OWLIndividual> negExamples){ 140 StringBuilder filter = new StringBuilder("VALUES ?s0 {"); 141 for (OWLIndividual ind : Sets.union(posExamples, negExamples)) { 142 filter.append(ind).append(" "); 143 } 144 filter.append("}"); 145 146 StringBuilder sb = new StringBuilder("CONSTRUCT {"); 147 sb.append("?s0 ?p0 ?o0 . ?p0 a ?p_type0 ."); 148 for (int i = 1; i < maxClassExpressionDepth; i++) { 149 sb.append("?o").append(i-1).append(" ?p").append(i).append(" ?o").append(i).append(" ."); 150 sb.append("?p").append(i).append(" a ").append(" ?p_type").append(i).append(" ."); 151 } 152 sb.append("} WHERE {"); 153 sb.append("?s0 ?p0 ?o0 . OPTIONAL{?p0 a ?p_type0 .}"); 154 155 for (int i = 1; i < maxClassExpressionDepth; i++) { 156 sb.append("OPTIONAL {"); 157 sb.append("?o").append(i-1).append(" ?p").append(i).append(" ?o").append(i).append(" ."); 158 sb.append("OPTIONAL{").append("?p").append(i).append(" a ").append(" ?p_type").append(i).append(" .}"); 159 } 160 for (int i = 1; i < maxClassExpressionDepth; i++) { 161 sb.append("}"); 162 } 163 sb.append(filter); 164 sb.append("}"); 165 166 QueryExecutionFactoryPaginated qef = new QueryExecutionFactoryPaginated(super.qef, 10000); 167 QueryExecution qe = qef.createQueryExecution(sb.toString()); 168 Model sample = qe.execConstruct(); 169 qe.close(); 170 171 StmtIterator iter = sample.listStatements(); 172 while(iter.hasNext()){ 173 Statement st = iter.next(); 174 if(st.getObject().isLiteral() && st.getObject().asLiteral().getDatatype() != null){ 175 try { 176 st.getObject().asLiteral().getValue(); 177 } catch (Exception e) { 178 iter.remove(); 179 } 180 } 181 } 182 183// org.dllearner.utilities.owl. 184 OWLEntityTypeAdder.addEntityTypes(sample); 185 return OwlApiJenaUtils.getOWLOntology(sample); 186 } 187 188 189 /* (non-Javadoc) 190 * @see org.dllearner.core.AbstractAxiomLearningAlgorithm#getSampleQuery() 191 */ 192 @Override 193 protected ParameterizedSparqlString getSampleQuery() { 194 return SAMPLE_QUERY; 195 } 196 197 public static void main(String[] args) throws Exception{ 198 CELOEWrapper la = new CELOEWrapper(new SparqlEndpointKS(SparqlEndpoint.getEndpointDBpediaLiveAKSW())); 199 la.setEntityToDescribe(new OWLClassImpl(IRI.create("http://dbpedia.org/ontology/Book"))); 200 la.init(); 201 la.start(); 202// new CELOEWrapper(new SparqlEndpointKS(SPARqlend)) 203 } 204 205}