Skip to content

Commit

Permalink
Enable usage of incoming triples.
Browse files Browse the repository at this point in the history
  • Loading branch information
LorenzBuehmann committed Jul 25, 2016
1 parent d2b39a1 commit c7d7761
Show file tree
Hide file tree
Showing 5 changed files with 438 additions and 80 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.apache.jena.vocabulary.OWL;
import org.apache.jena.vocabulary.RDF;
import org.apache.jena.vocabulary.RDFS;
import org.dllearner.algorithms.qtl.datastructures.NodeInv;
import org.dllearner.algorithms.qtl.datastructures.QueryTree;
import org.dllearner.algorithms.qtl.datastructures.impl.GenericTree;
import org.dllearner.algorithms.qtl.datastructures.impl.QueryTreeImpl.LiteralNodeConversionStrategy;
Expand Down Expand Up @@ -770,7 +771,15 @@ private static void buildSPARQLQueryString(RDFResourceTree tree,

// process object
String objectStr = FmtUtils.stringForNode(object, context);
sb.append(String.format(TRIPLE_PATTERN_TEMPLATE, subjectStr, predicateStr, objectStr)).append("\n");

// append triple pattern
String tpStr;
if(edge instanceof NodeInv) {
tpStr = String.format(TRIPLE_PATTERN_TEMPLATE, objectStr, predicateStr, subjectStr);
} else {
tpStr = String.format(TRIPLE_PATTERN_TEMPLATE, subjectStr, predicateStr, objectStr);
}
sb.append(tpStr).append("\n");

/*
* only if child is var node recursively process children if
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.dllearner.algorithms.qtl.datastructures;

import com.google.common.collect.ComparisonChain;
import org.apache.jena.graph.Node;
import org.apache.jena.graph.Node_URI;
import org.apache.jena.sparql.util.NodeComparator;

/**
* @author Lorenz Buehmann
*/
public class NodeInv extends Node_URI implements Comparable<NodeInv>{

private final Node node;

public NodeInv(Node node) {
super(node.getURI());
this.node = node;
}

public Node getNode() {
return node;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof NodeInv)) return false;
if (!super.equals(o)) return false;

NodeInv nodeInv = (NodeInv) o;

return node.equals(nodeInv.node);

}

@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + node.hashCode();
return result;
}

@Override
public int compareTo(NodeInv o) {
int match = this.getClass().equals(o.getClass()) ? 1 : 0;
if(match == 1) {
return new NodeComparator().compare(this, o);
} else {
return -1;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.util.TreeSet;

import org.dllearner.algorithms.qtl.QueryTreeUtils;
import org.dllearner.algorithms.qtl.datastructures.NodeInv;
import org.dllearner.algorithms.qtl.datastructures.impl.QueryTreeImpl.NodeType;
import org.dllearner.algorithms.qtl.util.PrefixCCPrefixMapping;

Expand Down Expand Up @@ -69,7 +70,18 @@ public enum Rendering {
private RDFDatatype datatype;

private Map<RDFResourceTree, Node> child2Edge = new HashMap<>();
private NavigableMap<Node, List<RDFResourceTree>> edge2Children = new TreeMap<>(new NodeComparator());
private NavigableMap<Node, List<RDFResourceTree>> edge2Children = new TreeMap<>(new NodeComparator() {
@Override
public int compare(Node o1, Node o2) {
int val1 = o1 instanceof NodeInv ? 1 : 0;
int val2 = o2 instanceof NodeInv ? 1 : 0;

if(val1 == val2) {
return super.compare(o1, o2);
}
return val1 - val2;
}
});
// private TreeMultimap<Node, RDFResourceTree> edge2Children = TreeMultimap.create(
// new NodeComparator(), Ordering.arbitrary());

Expand Down Expand Up @@ -384,7 +396,12 @@ private void buildTreeStringIndented(StringBuilder sb, boolean stopIfChildIsReso
if (edge != null) {
// sb.append(" ");
sb.append(FmtUtils.stringForNode(edge, context));
sb.append(" ---> ");
if(edge instanceof NodeInv) {
sb.append(" <--- ");
} else {
sb.append(" ---> ");
}

}
child.buildTreeStringIndented(sb, stopIfChildIsResourceNode, depth + 1, context);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,247 @@
/**
* Copyright (C) 2007 - 2016, Jens Lehmann
*
* This file is part of DL-Learner.
*
* DL-Learner is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* DL-Learner is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.dllearner.algorithms.qtl.impl;

import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Sets;
import org.apache.jena.graph.Node;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.RDFNode;
import org.apache.jena.rdf.model.Resource;
import org.apache.jena.rdf.model.Statement;
import org.apache.jena.sparql.util.NodeComparator;
import org.apache.jena.sparql.vocabulary.FOAF;
import org.apache.jena.util.iterator.ExtendedIterator;
import org.dllearner.algorithms.qtl.QueryTreeUtils;
import org.dllearner.algorithms.qtl.datastructures.NodeInv;
import org.dllearner.algorithms.qtl.datastructures.impl.RDFResourceTree;
import org.dllearner.algorithms.qtl.util.StopURIsDBpedia;
import org.dllearner.algorithms.qtl.util.StopURIsOWL;
import org.dllearner.algorithms.qtl.util.StopURIsRDFS;
import org.dllearner.algorithms.qtl.util.filters.NamespaceDropStatementFilter;
import org.dllearner.algorithms.qtl.util.filters.ObjectDropStatementFilter;
import org.dllearner.algorithms.qtl.util.filters.PredicateDropStatementFilter;
import org.dllearner.kb.sparql.ConciseBoundedDescriptionGenerator;
import org.dllearner.kb.sparql.ConciseBoundedDescriptionGeneratorImpl;
import org.dllearner.kb.sparql.SparqlEndpoint;
import org.dllearner.kb.sparql.SymmetricConciseBoundedDescriptionGeneratorImpl;

import java.util.*;
import java.util.function.Predicate;

/**
* A factory for query trees that also considers incoming triples.
*
* @author Lorenz Bühmann
*
*/
public class QueryTreeFactoryBaseInv implements QueryTreeFactory {

private int nodeId;
private final Comparator<Statement> comparator = new StatementComparator();

private int maxDepth = 3;

private Set<Predicate<Statement>> dropFilters = new HashSet<>();

/* (non-Javadoc)
* @see org.dllearner.algorithms.qtl.impl.QueryTreeFactory#setMaxDepth(int)
*/
@Override
public void setMaxDepth(int maxDepth) {
this.maxDepth = maxDepth;
}

@Override
public int maxDepth() {
return maxDepth;
}

/* (non-Javadoc)
* @see org.dllearner.algorithms.qtl.impl.QueryTreeFactory#getQueryTree(org.apache.jena.rdf.model.Resource, org.apache.jena.rdf.model.Model, int)
*/
@Override
public RDFResourceTree getQueryTree(Resource resource, Model model, int maxDepth) {
return createTree(resource, model, maxDepth);
}

/* (non-Javadoc)
* @see org.dllearner.algorithms.qtl.impl.QueryTreeFactory#addDropFilters(org.apache.jena.util.iterator.Filter)
*/
@Override
public void addDropFilters(Predicate<Statement>... dropFilters) {
this.dropFilters.addAll(Arrays.asList(dropFilters));
}

private RDFResourceTree createTree(Resource resource, Model model, int maxDepth) {
nodeId = 0;
Map<Resource, SortedSet<Statement>> resource2Statements = new HashMap<>();

RDFResourceTree tree = new RDFResourceTree(resource.asNode());

boolean inverse = false;

fillMap(resource, model, resource2Statements, inverse);
fillTree(resource, tree, resource2Statements, 0, maxDepth, inverse);

inverse = true;
resource2Statements = new HashMap<>();
fillMap(resource, model, resource2Statements, inverse);
fillTree(resource, tree, resource2Statements, 0, maxDepth, inverse);

return tree;
}

private void fillMap(Resource s, Model model, Map<Resource, SortedSet<Statement>> resource2Statements, boolean inverse) {

// get all statements
ExtendedIterator<Statement> it;
if (inverse) {
it = model.listStatements(null, null, s);// with object s
} else {
it = model.listStatements(s, null, (RDFNode) null);// with subject s
}


// filter statement if necessary
if (!dropFilters.isEmpty()) {
Iterator<Predicate<Statement>> iter = dropFilters.iterator();
Predicate<Statement> keepFilter = iter.next();
it = it.filterKeep(keepFilter);
while (iter.hasNext()) {it = it.filterKeep(iter.next());
// keepFilter = keepFilter.and(iter.next());
}
// it = it.filterKeep(keepFilter);
}

SortedSet<Statement> statements = resource2Statements.get(s);
if (statements == null) {
statements = new TreeSet<>(comparator);
resource2Statements.put(s, statements);
}

while (it.hasNext()) {
Statement st = it.next();
statements.add(st);
RDFNode nextNode = inverse ? st.getSubject() : st.getObject();
if (nextNode.isResource() && !resource2Statements.containsKey(nextNode)) {
fillMap(nextNode.asResource(), model, resource2Statements, inverse);
}
}
}

private void fillTree(Resource root, RDFResourceTree tree, Map<Resource, SortedSet<Statement>> resource2Statements,
int currentDepth, int maxDepth, boolean inverse) {
currentDepth++;
if (resource2Statements.containsKey(root)) {
RDFResourceTree subTree;

for (Statement st : resource2Statements.get(root)) {
Node predicate = inverse ? new NodeInv(st.getPredicate().asNode()): st.getPredicate().asNode();

RDFNode object = inverse ? st.getSubject() : st.getObject();

// create the subtree
subTree = new RDFResourceTree(nodeId++, object.asNode());
tree.addChild(subTree, predicate);

// if root of subtree is not a literal and current depth is < max depth recursive call
if (!object.isLiteral() && currentDepth < maxDepth) {
fillTree(object.asResource(), subTree, resource2Statements, currentDepth, maxDepth, inverse);
}
}
}
currentDepth--;
}

class StatementComparator implements Comparator<Statement> {

final NodeComparator nodeComparator = new NodeComparator();

@Override
public int compare(Statement s1, Statement s2) {
return ComparisonChain.start()
.compare(s1.getSubject().asNode(), s2.getSubject().asNode(), nodeComparator)
.compare(s1.getPredicate().asNode(), s2.getPredicate().asNode(), nodeComparator)
.compare(s1.getObject().asNode(), s2.getObject().asNode(), nodeComparator)
.result();
}
}

public static String encode(String s) {
char[] htmlChars = s.toCharArray();
StringBuilder encodedHtml = new StringBuilder();
for (char htmlChar : htmlChars) {
switch (htmlChar) {
case '<':
encodedHtml.append("&lt;");
break;
case '>':
encodedHtml.append("&gt;");
break;
case '&':
encodedHtml.append("&amp;");
break;
case '\'':
encodedHtml.append("&#39;");
break;
case '"':
encodedHtml.append("&quot;");
break;
case '\\':
encodedHtml.append("&#92;");
break;
case (char) 133:
encodedHtml.append("&#133;");
break;
default:
encodedHtml.append(htmlChar);
break;
}
}
return encodedHtml.toString();
}



public static void main(String[] args) throws Exception {
QueryTreeFactory factory = new QueryTreeFactoryBaseInv();
factory.setMaxDepth(2);
factory.addDropFilters(
new PredicateDropStatementFilter(Sets.union(Sets.union(StopURIsDBpedia.get(), StopURIsRDFS.get()), StopURIsOWL.get())),
new ObjectDropStatementFilter(StopURIsOWL.get()),
new NamespaceDropStatementFilter(
Sets.newHashSet(
"http://dbpedia.org/property/",
"http://purl.org/dc/terms/",
"http://dbpedia.org/class/yago/",
FOAF.getURI()
)
)
);
ConciseBoundedDescriptionGenerator cbdGen = new SymmetricConciseBoundedDescriptionGeneratorImpl(
SparqlEndpoint.getEndpointDBpedia());
String resourceURI = "http://dbpedia.org/resource/Athens";
Model cbd = cbdGen.getConciseBoundedDescription(resourceURI, 1);
RDFResourceTree queryTree = factory.getQueryTree(resourceURI, cbd);
System.out.println(queryTree.getStringRepresentation());
System.out.println(QueryTreeUtils.toSPARQLQuery(queryTree));
}

}
Loading

0 comments on commit c7d7761

Please sign in to comment.