[ 
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)

Reply via email to