[ https://issues.apache.org/jira/browse/RYA-292?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16128085#comment-16128085 ]
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_r133321220 --- Diff: sail/src/main/java/org/apache/rya/rdftriplestore/inference/InferenceEngine.java --- @@ -416,22 +425,131 @@ 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 RyaDaoStatementIterHandler() { + @Override + public void handleStatementIter(final Statement st1) throws Exception { + final Resource type = st1.getSubject(); + // head will point to a type that is part of the intersection. + URI head = (URI) st1.getObject(); + if (!intersectionsProp.containsKey(type)) { + intersectionsProp.put(type, new ArrayList<Set<Resource>>()); + } + final Set<Resource> intersection = new HashSet<>(); + // Go through and find all bnodes that are part of the defined + // intersection. + while (!RDF.NIL.equals(head)) { + // rdf.first will point to a type item that is in the + // intersection. + ryaDaoQueryWrapper.queryFirst(head, RDF.FIRST, null, new RyaDaoStatementIterHandler() { + @Override + public void handleStatementIter(final Statement st2) throws Exception{ + // The object found in the query represents a type + // that should be included in the intersection. + final URI obj2 = (URI) st2.getObject(); + intersection.add(obj2); + } + }); + final List<URI> headHolder = new ArrayList<>(1); + // rdf.rest will point to the next bnode that's part of the + // intersection. + ryaDaoQueryWrapper.queryFirst(head, RDF.REST, null, new RyaDaoStatementIterHandler() { + @Override + public void handleStatementIter(final Statement st3) throws Exception { + // This object is the next bnode head to look for. + final URI obj3 = (URI) st3.getObject(); + headHolder.add(obj3); + } + }); + // As long as we get a new head there are more bnodes that + // are part of the intersection. Keep going until we reach + // rdf.nil. + if (!headHolder.isEmpty()) { + head = headHolder.get(0); + } else { + head = RDF.NIL; + } + } + // 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); + } + }); + + for (final Map.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); + } + } + } + for (final Set<Resource> intersection : intersectionList) { + addIntersection(intersection, type); + } + } + intersections.clear(); --- End diff -- Won't this throw out the information that was just added in the preceding loop via addIntersection? > 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)