Skip to content

Commit

Permalink
rdf:type materialization for trees.
Browse files Browse the repository at this point in the history
  • Loading branch information
LorenzBuehmann committed Sep 23, 2016
1 parent fa776a1 commit 8b47514
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 12 deletions.
Expand Up @@ -534,7 +534,7 @@ public static <N> boolean sameTrees(RDFResourceTree tree1, RDFResourceTree tree2

public static Model toModel(RDFResourceTree tree) {
Model model = ModelFactory.createDefaultModel();
buildModel(model, tree, model.asRDFNode(NodeFactory.createAnon()).asResource());
buildModel(model, tree, model.asRDFNode(NodeFactory.createBlankNode()).asResource());
return model;
}

Expand All @@ -549,7 +549,7 @@ private static void buildModel(Model model, RDFResourceTree tree, Resource subje
for (Node edge : tree.getEdges()) {
Property p = model.getProperty(edge.getURI());
for (RDFResourceTree child : tree.getChildren(edge)) {
RDFNode object = child.isVarNode() ? model.asRDFNode(NodeFactory.createAnon()) : model.asRDFNode(child.getData());
RDFNode object = child.isVarNode() ? model.asRDFNode(NodeFactory.createBlankNode()) : model.asRDFNode(child.getData());
model.add(subject, p, object);
// if (child.isVarNode()) {
buildModel(model, child, object.asResource());
Expand Down Expand Up @@ -828,6 +828,69 @@ public static RDFResourceTree materializePropertyDomains(RDFResourceTree tree, A

return newTree;
}

/**
* Adds all rdf:type statements to each node based on the domain and range of the edges as well as the subClassOf
* relations between all existing types.
*
* @param tree the query tree
* @param reasoner the reasoner
* @return a new rdf:type materialized tree
*/
public static RDFResourceTree materializeTypes(RDFResourceTree tree, AbstractReasonerComponent reasoner) {
RDFResourceTree newTree = new RDFResourceTree(tree.getData());

Consumer<OWLClass> addTypeChild = (cls) -> newTree.addChild(new RDFResourceTree(OwlApiJenaUtils.asNode(cls)), RDF.type.asNode());

Set<OWLClassExpression> types = new HashSet<>();

// process the outgoing non-rdf:type edges
tree.getEdges().stream().filter(edge -> !edge.equals(RDF.type.asNode())).forEach(edge -> {
List<RDFResourceTree> children = tree.getChildren(edge);

// add existing children
children.forEach(child -> {
RDFResourceTree newChild = materializeTypes(child, reasoner);
newTree.addChild(newChild, edge);
});

// collect the rdfs:domain information if exist
OWLClassExpression dom = reasoner.getDomain(OwlApiJenaUtils.asOWLEntity(edge, EntityType.OBJECT_PROPERTY));
types.add(dom);
});

// process the incoming edge(s), i.e. collect the rdfs:range information if exist
if(!tree.isRoot()) {
Node inEdge = tree.getEdgeToParent();
OWLClassExpression range = reasoner.getRange(
OwlApiJenaUtils.asOWLEntity(inEdge, EntityType.OBJECT_PROPERTY));
types.add(range);
}

// collect the existing rdf:type nodes
List<RDFResourceTree> children = tree.getChildren(RDF.type.asNode());
if(children != null) {
children.forEach(child -> {
types.add(OwlApiJenaUtils.asOWLEntity(child.getData(), EntityType.CLASS));
});
}

// process the collected (complex) types, i.e. add an rdf:type edge for each named class
types.forEach(type -> {
if(!type.isAnonymous()) {
addTypeChild.accept(type.asOWLClass());
} else {
if(type.getClassExpressionType() == ClassExpressionType.OBJECT_INTERSECTION_OF) {
type.getNestedClassExpressions().stream()
.filter(ce -> !ce.isAnonymous())
.map(OWLClassExpression::asOWLClass)
.forEach(addTypeChild);
}
}
});

return newTree;
}

/**
* Remove trivial statements according to the given entailment semantics:
Expand Down Expand Up @@ -953,7 +1016,7 @@ public static void prune(RDFResourceTree tree, AbstractReasonerComponent reasone
// }
// }
// if(typeChildren != null) {
// // remove type children which are already covered implicitely
// // remove type children which are already covered implicitly
// for (RDFResourceTree child : new ArrayList<RDFResourceTree>(tree.getChildren(RDF.type.asNode()))) {
// if(child.isResourceNode() && implicitTypes.contains(new OWLClassImpl(IRI.create(child.getData().getURI())))) {
// tree.removeChild(child, RDF.type.asNode());
Expand Down Expand Up @@ -1252,14 +1315,14 @@ private static Multimap<Node, Node> getRelatedEdges(RDFResourceTree tree1, RDFRe
*/
public static <T, V extends GenericTree<T, V>> List<List<V>> getPathsToLeafs(GenericTree<T, V> tree) {
List<List<V>> paths = new ArrayList<>();
getPathsToLeafs(paths, new ArrayList<V>(), tree);
getPathsToLeafs(paths, new ArrayList<>(), tree);
return paths;
}

private static <T, V extends GenericTree<T, V>> void getPathsToLeafs(List<List<V>> paths, List<V> path, GenericTree<T, V> tree) {
List<V> children = tree.getChildren();
for (V child : children) {
List<V> newPath = new ArrayList<V>(path);
List<V> newPath = new ArrayList<>(path);
newPath.add(child);
if(child.isLeaf()) {
paths.add(newPath);
Expand Down
Expand Up @@ -81,7 +81,7 @@ protected boolean isSubTreeOf(RDFResourceTree tree1, RDFResourceTree tree2) {
protected RDFResourceTree preProcess(RDFResourceTree tree) {
QueryTreeUtils.keepMostSpecificTypes(tree, reasoner);

return QueryTreeUtils.materializePropertyDomains(tree, reasoner);
return QueryTreeUtils.materializeTypes(tree, reasoner);
}

@Override
Expand Down Expand Up @@ -211,6 +211,7 @@ public static void main(String[] args) throws Exception {
StringRenderer.setRenderer(Rendering.DL_SYNTAX);
// knowledge base
SparqlEndpoint endpoint = SparqlEndpoint.getEndpointDBpedia();
endpoint = SparqlEndpoint.create("http://sake.informatik.uni-leipzig.de:8890/sparql", "http://dbpedia.org");
QueryExecutionFactory qef = FluentQueryExecutionFactory
.http(endpoint.getURL().toString(), endpoint.getDefaultGraphURIs()).config()
.withCache(CacheUtilsH2.createCacheFrontend("/tmp/cache", false, TimeUnit.DAYS.toMillis(60)))
Expand Down Expand Up @@ -254,6 +255,7 @@ public static void main(String[] args) throws Exception {
reasoner.setPrecomputeDataPropertyHierarchy(true);
reasoner.init();
reasoner.precomputePropertyDomains();
reasoner.precomputeObjectPropertyRanges();
LGGGenerator lggGen = new LGGGeneratorRDFS(reasoner);
RDFResourceTree lgg = lggGen.getLGG(trees);

Expand Down
Expand Up @@ -533,7 +533,7 @@ public final ClassHierarchy prepareSubsumptionHierarchyFast() {
);

String query = "SELECT * WHERE {"
// + "?sub a <http://www.w3.org/2002/07/owl#Class> . "
+ "?sub a <http://www.w3.org/2002/07/owl#Class> . "
// + "?sup a <http://www.w3.org/2002/07/owl#Class> . "
+ "?sub (<http://www.w3.org/2000/01/rdf-schema#subClassOf>|<http://www.w3.org/2002/07/owl#equivalentClass>) ?sup ."
+ "FILTER(?sub != ?sup)"
Expand Down
Expand Up @@ -56,6 +56,7 @@ public static <E extends OWLEntity> Node getLeastCommonSubsumer(AbstractReasoner
* @param <E> the entity type
* @return the LCS if exists
*/
@SuppressWarnings("unchecked")
public static <E extends OWLEntity> E getLeastCommonSubsumer(AbstractReasonerComponent reasoner, E e1, E e2) {
// check if both entities are of the same type
if(e1.getEntityType() != e2.getEntityType()) {
Expand All @@ -73,7 +74,7 @@ public static <E extends OWLEntity> E getLeastCommonSubsumer(AbstractReasonerCom
if(entityType == EntityType.CLASS) {
f = e -> (SortedSet<E>) reasoner.getSuperClasses((OWLClass) e).stream()
.filter(ce -> !ce.isAnonymous())
.map(ce -> ce.asOWLClass())
.map(OWLClassExpression::asOWLClass)
.collect(Collectors.toCollection(TreeSet::new));
} else if(entityType == EntityType.OBJECT_PROPERTY) {
f = e -> (SortedSet<E>) reasoner.getSuperProperties((OWLObjectProperty) e);
Expand All @@ -84,9 +85,7 @@ public static <E extends OWLEntity> E getLeastCommonSubsumer(AbstractReasonerCom
}

// compute the LCS
E lcs = getLeastCommonSubsumer(e1, e2, f);

return lcs;
return getLeastCommonSubsumer(e1, e2, f);
}

private static <E extends OWLEntity> E getLeastCommonSubsumer(E e1, E e2, Function<E, SortedSet<E>> f) {
Expand Down
Expand Up @@ -30,6 +30,7 @@ public class LGGGeneratorRDFSTest {
LGGGeneratorRDFS lggGen;

String NS = "http://dl-learner.org/test/";
private int maxDepth = 2;

@Before
public void setUp() throws Exception {
Expand All @@ -44,6 +45,12 @@ public void setUp() throws Exception {
":x3 :s :y2 ." +
":x4 rdf:type :B ." +
":s rdfs:domain :C ." +
":B rdfs:subClassOf :C ." +

":x5 :t :y3 ." +
":y3 rdf:type :B ." +
":x6 :t :y4 ." +
":t rdfs:range :C ." +
":B rdfs:subClassOf :C .";

Model model = ModelFactory.createDefaultModel();
Expand All @@ -65,13 +72,14 @@ public void setUp() throws Exception {
}

private RDFResourceTree getTree(String uri) {
return treeFactory.getQueryTree(uri, cbdGenerator.getConciseBoundedDescription(uri));
return treeFactory.getQueryTree(uri, cbdGenerator.getConciseBoundedDescription(uri, maxDepth), maxDepth);
}

@Test
public void getLGG() throws Exception {
compute(NS + "x1", NS + "x2");
compute(NS + "x3", NS + "x4");
compute(NS + "x5", NS + "x6");
}

private void compute(String tree1URI, String tree2URI) {
Expand Down

0 comments on commit 8b47514

Please sign in to comment.