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.schema; 020 021import com.google.common.collect.Sets; 022import org.apache.jena.ontology.OntModel; 023import org.apache.jena.ontology.OntModelSpec; 024import org.apache.jena.rdf.model.Model; 025import org.apache.jena.rdf.model.ModelFactory; 026import org.apache.jena.rdf.model.Statement; 027import org.aksw.jena_sparql_api.core.QueryExecutionFactory; 028import org.aksw.jena_sparql_api.model.QueryExecutionFactoryModel; 029import org.dllearner.algorithms.properties.AxiomAlgorithms; 030import org.dllearner.core.AbstractAxiomLearningAlgorithm; 031import org.dllearner.core.AxiomLearningProgressMonitor; 032import org.dllearner.core.SilentAxiomLearningProgressMonitor; 033import org.dllearner.kb.SparqlEndpointKS; 034import org.dllearner.reasoning.SPARQLReasoner; 035import org.dllearner.utilities.OwlApiJenaUtils; 036import org.semanticweb.owlapi.model.*; 037import org.semanticweb.owlapi.profiles.OWL2DLProfile; 038import org.semanticweb.owlapi.profiles.OWLProfile; 039import org.semanticweb.owlapi.profiles.Profiles; 040 041import java.util.*; 042import java.util.stream.Collectors; 043import java.util.stream.Stream; 044 045/** 046 * 047 * @author Lorenz Buehmann 048 * 049 */ 050public abstract class AbstractSchemaGenerator implements SchemaGenerator{ 051 052 protected QueryExecutionFactory qef; 053 protected OWLProfile owlProfile = new OWL2DLProfile(); 054 protected SPARQLReasoner reasoner; 055 056// protected AxiomLearningProgressMonitor progressMonitor = new ConsoleAxiomLearningProgressMonitor(); 057 protected AxiomLearningProgressMonitor progressMonitor = new SilentAxiomLearningProgressMonitor(); 058 059 // the types of axioms to be processed 060 protected Set<AxiomType<? extends OWLAxiom>> axiomTypes = AxiomAlgorithms.TBoxAndRBoxAxiomTypes; 061 062 // the types of entities to be processed 063 protected Set<EntityType<? extends OWLEntity>> entityTypes = Sets.<EntityType<? extends OWLEntity>>newHashSet( 064 EntityType.CLASS, EntityType.OBJECT_PROPERTY, EntityType.DATA_PROPERTY); 065 066 // the minimum accuracy threshold for generated axioms to be accepted 067 private double accuracyThreshold = 0.3; 068 069 // the entities which are processed 070 protected SortedSet<OWLEntity> entities; 071 072 // the knowledge base 073 private OntModel model; 074 075 // the profile used for rule based inferencing 076 private OntModelSpec reasoningProfile = OntModelSpec.RDFS_MEM_RDFS_INF; 077 078 public AbstractSchemaGenerator(QueryExecutionFactory qef) { 079 this.qef = qef; 080 this.reasoner = new SPARQLReasoner(qef); 081 this.model = ModelFactory.createOntologyModel(reasoningProfile); 082 } 083 084 public AbstractSchemaGenerator(Model model) { 085 // enable reasoning on model 086 this.model = ModelFactory.createOntologyModel(reasoningProfile, model); 087 this.qef = new QueryExecutionFactoryModel(this.model); 088 this.reasoner = new SPARQLReasoner(qef); 089 } 090 091 /** 092 * Set the types of axioms that are generated. 093 * @param axiomTypes the axiom types to set 094 */ 095 public void setAxiomTypes(Set<AxiomType<? extends OWLAxiom>> axiomTypes) { 096 this.axiomTypes = axiomTypes; 097 } 098 099 /** 100 * Set the types of axioms that are generated by giving an OWL profile. 101 * @param owlProfile the OWL profile 102 */ 103 public void setAxiomTypes(OWLProfile owlProfile) { 104 if(owlProfile.equals(Profiles.OWL2_EL.getOWLProfile())){ 105 106 } else if(owlProfile.equals(Profiles.OWL2_RL.getOWLProfile())){ 107 108 } else if(owlProfile.equals(Profiles.OWL2_QL.getOWLProfile())){ 109 110 } else if(owlProfile.equals(Profiles.OWL2_DL.getOWLProfile())){ 111 112 } else { 113 throw new IllegalArgumentException("OWL profile " + owlProfile.getName() + " not supported."); 114 } 115 } 116 117 public void setEntityTypes(Set<EntityType<? extends OWLEntity>> entityTypes) { 118 this.entityTypes = entityTypes; 119 } 120 121 /** 122 * @param entities the entities to set 123 */ 124 public void setEntities(SortedSet<OWLEntity> entities) { 125 this.entities = entities; 126 } 127 128 /** 129 * Return the entities contained in the current knowledge base. 130 */ 131 protected SortedSet<OWLEntity> getEntities(){ 132 if(entities == null){ 133 entities = new TreeSet<>(); 134 for (EntityType<? extends OWLEntity> entityType : entityTypes) { 135 if(entityType == EntityType.CLASS){ 136 entities.addAll(reasoner.getOWLClasses()); 137 } else if(entityType == EntityType.OBJECT_PROPERTY){ 138 entities.addAll(reasoner.getOWLObjectProperties()); 139 } else if(entityType == EntityType.DATA_PROPERTY){ 140 entities.addAll(reasoner.getOWLDataProperties()); 141 } else { 142 throw new IllegalArgumentException("Entity type " + entityType.getName() + " not supported."); 143 } 144 } 145 } 146 return entities; 147 } 148 149 /** 150 * Return the entities contained in the current knowledge base for the given entity type. 151 * 152 * @param entityType the entity type 153 */ 154 protected <T extends OWLEntity> SortedSet<T> getEntities(EntityType<T> entityType) { 155 SortedSet<T> entitiesForType = new TreeSet<>(); 156 for (OWLEntity entity : getEntities()) { 157 if (entity.isType(entityType)) { 158 entitiesForType.add((T) entity); 159 } 160 } 161 return entitiesForType; 162// Stream<T> s = entities.stream().filter(e -> e.isType(entityType)).map(e -> (T) e); 163// return s.collect(Collectors.toList()); 164 } 165 166 /** 167 * @param accuracyThreshold the accuracyThreshold to set 168 */ 169 public void setAccuracyThreshold(double accuracyThreshold) { 170 this.accuracyThreshold = accuracyThreshold; 171 } 172 173 protected Set<OWLAxiom> applyLearningAlgorithm(OWLEntity entity, AxiomType<? extends OWLAxiom> axiomType) throws Exception{ 174 // get the algorithm class 175 Class<? extends AbstractAxiomLearningAlgorithm<? extends OWLAxiom, ? extends OWLObject, ? extends OWLEntity>> algorithmClass = AxiomAlgorithms.getAlgorithmClass(axiomType); 176 177 // create learning algorithm object 178 AbstractAxiomLearningAlgorithm learner = null; 179 try { 180 learner = (AbstractAxiomLearningAlgorithm)algorithmClass.getConstructor( 181 SparqlEndpointKS.class).newInstance(new SparqlEndpointKS(qef)); 182 } catch (Exception e) { 183 e.printStackTrace(); 184 } 185 186 learner.setEntityToDescribe(entity); 187 learner.setUseSampling(false); 188 learner.setProgressMonitor(progressMonitor); 189 190 191 try { 192 // initialize the learning algorithm 193 learner.init(); 194 195 // run the learning algorithm 196 learner.start(); 197 198 // return the result 199 return new TreeSet<>(learner.getCurrentlyBestAxioms(accuracyThreshold)); 200 } catch (Exception e) { 201 throw new Exception("Generation of " + axiomType.getName() + " axioms failed.", e); 202 } 203 } 204 205 /** 206 * Add the axioms to the running knowledge base. 207 * @param axioms the axioms 208 */ 209 protected void addToKnowledgebase(Set<OWLAxiom> axioms) { 210 Set<Statement> statements = OwlApiJenaUtils.asStatements(axioms); 211 model.add(new ArrayList<>(statements)); 212 } 213 214}