001/**
002 * Copyright (C) 2007 - 2016, Jens Lehmann
003 * <p>
004 * This file is part of DL-Learner.
005 * <p>
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 * <p>
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 * <p>
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.kb.sparql;
020
021import java.io.StringReader;
022import java.util.Set;
023
024import org.aksw.jena_sparql_api.model.QueryExecutionFactoryModel;
025import org.apache.jena.query.ParameterizedSparqlString;
026import org.apache.jena.query.QueryExecution;
027import org.apache.jena.rdf.model.Model;
028import org.apache.jena.rdf.model.ModelFactory;
029import org.slf4j.Logger;
030import org.slf4j.LoggerFactory;
031
032/**
033 * A CBD generator that resolves blank nodes.
034 *
035 * @author Lorenz Buehmann
036 */
037public class BlanknodeResolvingCBDGenerator implements ConciseBoundedDescriptionGenerator {
038
039    private static final Logger log = LoggerFactory.getLogger(BlanknodeResolvingCBDGenerator.class);
040
041    private QueryExecutionFactoryModel qef;
042
043    public BlanknodeResolvingCBDGenerator(Model model) {
044        String query = "prefix : <http://dl-learner.org/ontology/> "
045                + "construct { ?s ?p ?o ; ?type ?s .} "
046                + "where {  ?s ?p ?o .  bind( if(isIRI(?s),:sameIri,:sameBlank) as ?type )}";
047        qef = new QueryExecutionFactoryModel(model);
048        QueryExecution qe = qef.createQueryExecution(query);
049        Model extendedModel = qe.execConstruct();
050        qe.close();
051
052        qef = new QueryExecutionFactoryModel(extendedModel);
053    }
054
055    /* (non-Javadoc)
056     * @see org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator#getConciseBoundedDescription(java.lang.String)
057     */
058    @Override
059    public Model getConciseBoundedDescription(String resourceURI) {
060        return getConciseBoundedDescription(resourceURI, 0);
061    }
062
063    /* (non-Javadoc)
064     * @see org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator#getConciseBoundedDescription(java.lang.String, int)
065     */
066    @Override
067    public Model getConciseBoundedDescription(String resource, int depth) {
068        return getConciseBoundedDescription(resource, depth, false);
069    }
070
071    /* (non-Javadoc)
072     * @see org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator#getConciseBoundedDescription(java.lang.String, int, boolean)
073     */
074    @Override
075    public Model getConciseBoundedDescription(String resource, int depth, boolean withTypesForLeafs) {
076        StringBuilder constructTemplate = new StringBuilder("?s0 ?p0 ?o0 .\n");
077        for (int i = 1; i < depth; i++) {
078            constructTemplate.append("?s").append(i).append(" ?p").append(i).append(" ?o").append(i).append(" .\n");
079        }
080
081        StringBuilder triplesTemplate = new StringBuilder("?x ((!<x>|!<y>)/:sameBlank)* ?s0 . ?s0 ?p0 ?o0 . filter(!(?p0 in (:sameIri, :sameBlank)))\n");
082        for (int i = 1; i < depth; i++) {
083            triplesTemplate.append("OPTIONAL {").append("?o").append(i - 1).append(" ((!<x>|!<y>)/:sameBlank)* ?s").append(i).append(" .")
084                    .append("?s").append(i).append(" ?p").append(i).append(" ?o").append(i).append(" filter(!(?p").append(i).append(" in (:sameIri, :sameBlank)))");
085        }
086
087
088        for (int i = 1; i < depth; i++) {
089            triplesTemplate.append("}");
090        }
091
092        ParameterizedSparqlString query = new ParameterizedSparqlString("prefix : <http://dl-learner.org/ontology/> " +
093                "\nCONSTRUCT {\n" + constructTemplate + "} WHERE {\n" + triplesTemplate + "\n}");
094        query.setIri("x", resource);
095
096        log.debug("CBD query:\n" + query.toString());
097
098        try (QueryExecution qe = qef.createQueryExecution(query.toString())) {
099            return qe.execConstruct();
100        }
101    }
102
103    @Override
104    public void setIgnoredProperties(Set<String> properties) {
105        throw new UnsupportedOperationException("not supported yet!");
106    }
107
108    /* (non-Javadoc)
109     * @see org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator#setRestrictToNamespaces(java.util.List)
110     */
111    @Override
112    public void setAllowedPropertyNamespaces(Set<String> namespaces) {
113        throw new UnsupportedOperationException("not supported yet!");
114    }
115
116    /* (non-Javadoc)
117     * @see org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator#setAllowedObjectNamespaces(java.util.Set)
118     */
119    @Override
120    public void setAllowedObjectNamespaces(Set<String> namespaces) {
121        throw new UnsupportedOperationException("not supported yet!");
122    }
123
124    public static void main(String[] args) {
125        String data = "@prefix : <http://dl-learner.org/test/> .\n" +
126                "\n" +
127                ":A :p :B ;\n" +
128                "   :q [ :r :C , :D ] .\n" +
129                ":B :q :D, :E .\n" +
130                ":C :r :F .\n" +
131                ":D :r :F , :G ;\n" +
132                "   :s :A , :B .";
133
134        printCBD(data, 1);
135
136        data = "@prefix : <http://dl-learner.org/test/> .\n" +
137                "\n" +
138                ":A :p :B . :B :q [ :r :C , :D ] . \n" +
139                ":B :q :D, :E .\n" +
140                ":C :r :F .\n" +
141                ":D :r :F , :G ;\n" +
142                "   :s :A , :B .";
143
144        printCBD(data, 2);
145    }
146
147    private static void printCBD(String data, int depth) {
148        Model m = ModelFactory.createDefaultModel();
149        m.read(new StringReader(data), null, "Turtle");
150
151        BlanknodeResolvingCBDGenerator cbdGen = new BlanknodeResolvingCBDGenerator(m);
152
153        Model cbd = cbdGen.getConciseBoundedDescription("http://dl-learner.org/test/A", 2);
154        cbd.setNsPrefix("", "http://dl-learner.org/test/");
155        cbd.write(System.out, "Turtle");
156    }
157}