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.analyse; 020 021import java.util.ArrayList; 022import java.util.HashSet; 023import java.util.List; 024import java.util.Set; 025 026import org.dllearner.kb.sparql.simple.QueryExecutor; 027import org.slf4j.Logger; 028import org.slf4j.LoggerFactory; 029 030import org.apache.jena.graph.Triple; 031import org.apache.jena.ontology.DatatypeProperty; 032import org.apache.jena.ontology.Individual; 033import org.apache.jena.ontology.ObjectProperty; 034import org.apache.jena.ontology.OntClass; 035import org.apache.jena.ontology.OntModel; 036import org.apache.jena.rdf.model.ModelFactory; 037import org.apache.jena.util.iterator.ExtendedIterator; 038import org.apache.jena.vocabulary.OWL; 039import org.apache.jena.vocabulary.RDF; 040import org.apache.jena.vocabulary.RDFS; 041 042public class TypeOntology { 043 044 private static Logger log = LoggerFactory.getLogger(TypeOntology.class); 045 046 private int addTypes(OntModel model) { 047 int changes=0; 048 Set<String> dataProperties = new HashSet<>(); 049 Set<String> objectProperties = new HashSet<>(); 050 Set<String> classes = new HashSet<>(); 051 Set<String> individuals = new HashSet<>(); 052 Set<Triple> triples = model.getGraph().find(Triple.ANY).toSet(); 053 054 ExtendedIterator<OntClass> itClass = model.listNamedClasses(); 055 while (itClass.hasNext()) { 056 classes.add(itClass.next().getURI()); 057 } 058 059 ExtendedIterator<Individual> itIndividuals = model.listIndividuals(); 060 while (itIndividuals.hasNext()) { 061 individuals.add(itIndividuals.next().getURI()); 062 } 063 064 ExtendedIterator<DatatypeProperty> itDataProperties = model 065 .listDatatypeProperties(); 066 while (itDataProperties.hasNext()) { 067 dataProperties.add(itDataProperties.next().getURI()); 068 } 069 070 ExtendedIterator<ObjectProperty> itObjectProperties = model 071 .listObjectProperties(); 072 while (itObjectProperties.hasNext()) { 073 objectProperties.add(itObjectProperties.next().getURI()); 074 } 075 076 String sUri; 077 String pUri; 078 String oUri; 079 //System.out.println(individuals); 080 081 // foreach triple in the model 082 for (Triple triple : triples) { 083 if(!triple.getSubject().isURI() || !triple.getPredicate().isURI() || !triple.getObject().isURI()){ 084 continue; 085 } 086 sUri = triple.getSubject().getURI(); 087 pUri = triple.getPredicate().getURI(); 088 oUri = triple.getObject().getURI(); 089 090 // if subject is an Individual 091 if (individuals.contains(sUri)) { 092 log.trace("Subject is an individual {}",triple); 093 094 // if predicate is rdf:type 095 if (pUri.equals(RDF.type.getURI())) { 096 097 // if object is not in the list of class and not equals 098 // owl:thing 099 if (!classes.contains(oUri) 100 && !oUri.equals(OWL.Thing.getURI())) { 101 model.getResource(oUri).addProperty(RDF.type,OWL.Class); 102 classes.add(oUri); 103 changes++; 104 log.debug("{} is a class",oUri); 105 } 106 107 // object is not a class, so it can only be a literal or an 108 // object 109 // if object is a literal 110 } else if (model.getResource(oUri).isLiteral()) { 111 112 // if predicate is not in the list of objectproperties 113 if (!objectProperties.contains(pUri)) { 114 model.createDatatypeProperty(pUri); 115 dataProperties.add(pUri); 116 117 log.debug("{} is a dataproperty",pUri); 118 119 // if predicate is in the list of objectproperties it 120 // must be an rdf:property 121 } else { 122 model.createOntProperty(pUri); 123 log.info("{} is a rdf:property", pUri); 124 } 125 changes++; 126 127 // object is not a literal or a class so it must be an 128 // instance 129 // if object is not in the list of individuals 130 } else if (!individuals.contains(oUri)) { 131 model.getResource(oUri).addProperty(RDF.type, OWL.Thing); 132 individuals.add(oUri); 133 134 // subject and object are individuals so is predicate an 135 // objectproperty 136 // if predicate ist not in the list of dataproperties 137 if (!dataProperties.contains(pUri)) { 138 model.createObjectProperty(pUri); 139 objectProperties.add(pUri); 140 log.debug("{} is an objectproperty", pUri); 141 142 // if predicate is in the list of dataproperties it must 143 // be a rdf:property 144 } else { 145 model.createOntProperty(pUri); 146 log.info("{} is a rdf:property", pUri); 147 } 148 log.debug("{} is an individual",oUri); 149 changes++; 150 } 151 // if subject is an owl:class 152 } else if (classes.contains(sUri)) { 153 log.trace("Subject is a class {}",triple); 154 155 //TODO check this assumption 156 //if s is owl:class, then o is owl:class too ???? 157 if(!classes.contains(oUri) ){ 158 model.getResource(oUri).addProperty(RDF.type, OWL.Class); 159 classes.add(oUri); 160 log.debug("{} is a class",oUri); 161 changes++; 162 } 163 } 164 } 165 return changes; 166 } 167 168 public OntModel addTypetoJena(OntModel model, List<String> individuals, 169 List<String> classes) { 170 if (individuals != null) { 171 for (String individual : individuals) { 172 if (individual.startsWith("<")) { 173 int strlen = individual.length(); 174 // assuming that there is also a closing angle bracket 175 individual = individual.substring(1, strlen-1); 176 } 177 model.getResource(individual).addProperty(RDF.type, OWL.Thing); 178 } 179 } 180 if (classes != null) { 181 for (String ontClass : classes) { 182 if (!ontClass.equals(OWL.Thing.getURI())) { 183 model.getResource(ontClass).addProperty(RDFS.subClassOf, OWL.Thing); 184 } 185 } 186 } 187// model.write(System.out); 188 while(this.addTypes(model)!=0); 189 190 return model; 191 } 192 193 public static void main(String... args) { 194 String sparql = "CONSTRUCT {?s ?p ?o}" 195 + "{ ?s ?p ?o " 196 + "FILTER (?s IN( <http://dbpedia.org/resource/Philolaus>," 197 + " <http://dbpedia.org/resource/Zeno_of_Elea>," 198 + " <http://dbpedia.org/resource/Socrates>," 199 + " <http://dbpedia.org/resource/Pythagoras>," 200 + " <http://dbpedia.org/resource/Archytas>," 201 + " <http://dbpedia.org/resource/Plato>," 202 + " <http://dbpedia.org/resource/Democritus> )) ." 203 + " FILTER ( !isLiteral(?o) && regex(str(?o), '^http://dbpedia.org/resource/') &&" 204 + " ! regex(str(?o), '^http://dbpedia.org/resource/Category') &&" 205 + " ! regex(str(?o), '^http://dbpedia.org/resource/Template') ) . }"; 206 OntModel model = ModelFactory.createOntologyModel(); 207 List<String> individuals = new ArrayList<>(7); 208 individuals.add("http://dbpedia.org/resource/Philolaus"); 209 individuals.add("http://dbpedia.org/resource/Zeno_of_Elea"); 210 individuals.add("http://dbpedia.org/resource/Socrates"); 211 individuals.add("http://dbpedia.org/resource/Pytagoras"); 212 individuals.add("http://dbpedia.org/resource/Archytas"); 213 individuals.add("http://dbpedia.org/resource/Plato"); 214 individuals.add("http://dbpedia.org/resource/Democritus"); 215 QueryExecutor exec = new QueryExecutor(); 216 exec.executeQuery(sparql, "http://live.dbpedia.org/sparql", model, 217 "http://dbpedia.org"); 218 System.out.println(model.listIndividuals().toSet()); 219 System.out.println(model.listObjectProperties().toSet()); 220 TypeOntology type = new TypeOntology(); 221 model=type.addTypetoJena(model, individuals, null); 222 System.out.println(model.listIndividuals().toSet()); 223 System.out.println(model.listObjectProperties().toSet()); 224 System.out.println(model.listDatatypeProperties().toSet()); 225 } 226}