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}