[ https://issues.apache.org/jira/browse/RYA-292?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16133903#comment-16133903 ]
ASF GitHub Bot commented on RYA-292: ------------------------------------ Github user jessehatfield commented on a diff in the pull request: https://github.com/apache/incubator-rya/pull/206#discussion_r134081075 --- Diff: sail/src/main/java/org/apache/rya/rdftriplestore/inference/InferenceEngine.java --- @@ -621,22 +631,189 @@ private void refreshHasValueRestrictions(Map<Resource, URI> restrictions) throws } } - private static Vertex getVertex(Graph graph, Object id) { - Iterator<Vertex> it = graph.vertices(id.toString()); + private void refreshIntersectionOf() throws QueryEvaluationException { + final Map<Resource, List<Set<Resource>>> intersectionsProp = new HashMap<>(); + + // First query for all the owl:intersectionOf's. + // If we have the following intersectionOf: + // :A owl:intersectionOf[:B, :C] + // It will be represented by triples following a pattern similar to: + // <:A> owl:intersectionOf _:bnode1 . + // _:bnode1 rdf:first <:B> . + // _:bnode1 rdf:rest _:bnode2 . + // _:bnode2 rdf:first <:C> . + // _:bnode2 rdf:rest rdf:nil . + ryaDaoQueryWrapper.queryAll(null, OWL.INTERSECTIONOF, null, new RDFHandlerBase() { + @Override + public void handleStatement(final Statement statement) throws RDFHandlerException { + final Resource type = statement.getSubject(); + // head will point to a type that is part of the intersection. + final URI head = (URI) statement.getObject(); + if (!intersectionsProp.containsKey(type)) { + intersectionsProp.put(type, new ArrayList<Set<Resource>>()); + } + + // head should point to a list of items that forms the + // intersection. + try { + final Set<Resource> intersection = new LinkedHashSet<>(getList(head)); + if (!intersection.isEmpty()) { + // Add this intersection for this type. There may be more + // intersections for this type so each type has a list of + // intersection sets. + intersectionsProp.get(type).add(intersection); + } + } catch (final QueryEvaluationException e) { + throw new RDFHandlerException("Error getting intersection list.", e); + } + } + }); + + intersections.clear(); + for (final Entry<Resource, List<Set<Resource>>> entry : intersectionsProp.entrySet()) { + final Resource type = entry.getKey(); + final List<Set<Resource>> intersectionList = entry.getValue(); + final Set<Resource> otherTypes = new HashSet<>(); + // Combine all of a type's intersections together. + for (final Set<Resource> intersection : intersectionList) { + otherTypes.addAll(intersection); + } + for (final Resource other : otherTypes) { + // :A intersectionOf[:B, :C] implies that + // :A subclassOf :B + // :A subclassOf :C + // So add each type that's part of the intersection to the + // subClassOf graph. + addSubClassOf(type, other); + for (final Set<Resource> intersection : intersectionList) { + if (!intersection.contains(other)) { + addIntersection(intersection, other); + } + } + } + + final List<Statement> typeStatements = new ArrayList<>(); + ryaDaoQueryWrapper.queryAll(type, OWL.INTERSECTIONOF, null, new RDFHandlerBase() { + @Override + public void handleStatement(final Statement statement) throws RDFHandlerException { + typeStatements.add(statement); + } + }); + + final Set<URI> superClasses = getSuperClasses((URI) type); + for (final Set<Resource> intersection : intersectionList) { + addIntersection(intersection, type); + for (final URI superClass : superClasses) { + // Add intersections to super classes if applicable. + // IF: + // :A intersectionOf[:B, :C] + // AND + // :A subclassOf :D + // Then we can infer: + // intersectionOf[:B, :C] subclassOf :D + for (final Statement statement : typeStatements) { + final Resource intersectionOfBnode = (Resource) statement.getObject(); + addSubClassOf(intersectionOfBnode, superClass); --- End diff -- I don't think this is quite correct: this bnode (the object of <subject, owl:intersectionOf, object>) is going to be the head of a list, right? I don't think it represents a type of its own. Is the goal here to let us answer queries for instances of D based on the subclass (A) and in turn the intersection (B and C)? We could do that by directly adding (B and C) to the list of intersections for D, instead of adding to the subclass graph. But if you take that approach, note that you'd want to get transitive superclasses of A (therefore superclasses of D, and so on), so 1) I think you'd want findChildren(subClassOfGraph, URI) instead of getSuperClasses; and 2) since we're still actively modifying the subclass graph a little earlier in this outer loop, I think you'd need to move the propagate-to-superclasses logic out to a second pass over the intersectionsProp entries. Alternatively, if the getIntersectionsImplying method iterated through the (transitive) subclasses of the queried class, and added their intersections as well, we would get this behavior by doing the processing at query time. All the other changes look good to me. > Implement owl:intersectionOf inference > -------------------------------------- > > Key: RYA-292 > URL: https://issues.apache.org/jira/browse/RYA-292 > Project: Rya > Issue Type: Sub-task > Components: sail > Reporter: Jesse Hatfield > Assignee: Eric White > > An *{{owl:intersectionOf}}* expression defines the set of resources who > belong to all of a particular set of classes. > A basic implementation, if the ontology states that {{:Mother}} is the > intersection of {{:Parent}} and {{:Woman}}, should cause the inference engine > to: > 1. Rewrite query patterns {{?x rdf:type :Mother}} (the intersection type) to > check for resources that have both types {{:Parent}} and {{:Woman}} (as well > as check for resources that are explicitly stated to be {{:Mother}} s) > 2. Rewrite query patterns {{?y rdf:type :Parent}} (one of the intersecting > sets) to check for resources that are stated to be either {{:Mother}} or > {{:Parent}} , since belonging to the intersection type implies membership in > the component types. (Equivalent logic applies to {{Woman}} ) -- This message was sent by Atlassian JIRA (v6.4.14#64029)