You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@rya.apache.org by "Jesse Hatfield (JIRA)" <ji...@apache.org> on 2017/07/20 21:01:00 UTC

[jira] [Comment Edited] (RYA-296) Implement owl:hasSelf inference

    [ https://issues.apache.org/jira/browse/RYA-296?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16092250#comment-16092250 ] 

Jesse Hatfield edited comment on RYA-296 at 7/20/17 9:00 PM:
-------------------------------------------------------------

Note: [The object of the hasSelf triple is irrelevant|https://www.w3.org/TR/owl2-rdf-based-semantics/#Semantic_Conditions_for_the_Vocabulary_Properties], though {{"true"^^xsd:boolean}} is recommended.

An owl:hasSelf restriction takes the form {{:A owl:onProperty \:p ; owl:hasSelf _ .}}, and means{quote}(1) *If* (x p x) *then* x is an A.
(2) *If* x is an A *then* (x p x) .{quote}
We can use both implications. If a query asks for instances of A, then we rewrite to ask for individuals connected to themselves via p and/or individuals otherwise known to be instances of A. If a query asks for triples involving predicate p, then we know to include (x p x) for every x of type A. That is,
{code}SELECT ?x WHERE { ?x rdf:type :A }{code} becomes {code}SELECT ?x WHERE {
    { ?x :p ?x }
    UNION
    { ?x rdf:type :A }
}{code}
And{code}SELECT ?s ?o WHERE { ?s :p ?o }{code} becomes {code}SELECT ?s ?o WHERE {
    {
        ?s rdf:type :A .
        BIND(?s AS ?o) .
    } UNION {
        ?s :p ?o .
    }
}{code}Or in the query algebra:{code}Union(
    Extension(
        StatementPattern(?s rdf:type :A),
        ExtensionElem(?s, "o")
    ),
    StatementPattern(?s :p ?o)
){code}
(Note: One of s or o could be defined, and if it is o, it should be used in the join instead, and "?s" bound to its value.)
h4. Proposed Approach
Since the inference can be made in either direction, the inference engine needs to provide methods to look up the hasSelf information given either the type or the property. At refresh time, we have:
{code}hasSelfByProperty <- Map<property, Set<type>>
hasSelfByType <- Map<type, Set<property>>
for (restrictionType, property) in propertyRestrictions:
    if exists(query(restrictionType owl:hasSelf ?any)):
        hasSelfByProperty[property].add(restrictionType)
        hasSelfByType[restrictionType].add(property){code}
The inference engine needs two methods:
{code}getHasSelfImplyingType(type): // return properties that imply this type if reflexive
    properties <- Set<property>
    for sufficientType in ( { type } UNION getAllSubClasses(type) ):
        properties.addAll(hasSelfByType[type])
        return properties{code}
{code}getHasSelfImplyingProperty(property): // return types that imply this property to be reflexive
    return hasSelfByProperty[property] if exists{code}
At query time, apply the visitor:
{code}meet(StatementPattern originalSP):
    if originalSP like (?s rdf:type :C1):  // require that C1 is defined, i.e. not a variable
        node <- originalSP
        for property in getHasSelfImplyingType(C1):
            node <- InferUnion(node, StatementPattern(?s, property, ?s)).
        originalSP.replaceWith(node)
    else if originalSP like (s :p o):  // where p is not a variable and at least one of s and o are variables
        node <- originalSP
        for type in getHasSelfImplyingProperty(p):
            newNode <- if o is defined:  // meaning s is the variable
                Extension(StatementPattern(o, rdf:type, type), ExtensionElem(o, "s"))
            else: // o is a variable and s may either be defined or a variable
                Extension(StatementPattern(s, rdf:type, type), ExtensionElem(s, "o"))
            node <- InferUnion(node, newNode)
        originalSP.replaceWith(node){code}


was (Author: jhatfiel):
Note: [The object of the hasSelf triple is irrelevant|https://www.w3.org/TR/owl2-rdf-based-semantics/#Semantic_Conditions_for_the_Vocabulary_Properties], though {{"true"^^xsd:boolean}} is recommended.

An owl:hasSelf restriction takes the form {{:A owl:onProperty \:p ; owl:hasSelf _ .}}, and means{quote}(1) *If* (x p x) *then* x is an A.
(2) *If* x is an A *then* (x p x) .{quote}
We can use both implications. If a query asks for instances of A, then we rewrite to ask for individuals connected to themselves via p and/or individuals otherwise known to be instances of A. If a query asks for triples involving predicate p, then we know to include (x p x) for every x of type A. That is,
{code}SELECT ?x WHERE { ?x rdf:type :A }{code} becomes {code}SELECT ?x WHERE {
    { ?x :p ?x }
    UNION
    { ?x rdf:type :A }
}{code}
And{code}SELECT ?s ?o WHERE { ?s :p ?o }{code} becomes {code}SELECT ?s ?o WHERE {
    {
        ?s rdf:type :A .
        BIND(?s AS ?o) .
    } UNION {
        ?s :p ?o .
    }
}{code}Or in the query algebra:{code}Union(
    Extension(
        StatementPattern(?s rdf:type :A),
        ExtensionElem(?s, "o")
    ),
    StatementPattern(?s :p ?o)
){code}
(Note: One of s or o could be defined, and if it is o, it should be used in the join instead, and "?s" bound to its value.)
h4. Proposed Approach
Since the inference can be made in either direction, the inference engine needs to provide methods to look up the hasSelf information given either the type or the property. At refresh time, we have:
{code}oneOfByProperty <- Map<property, Set<type>>
oneOfByType <- Map<type, Set<property>>
for (restrictionType, property) in propertyRestrictions:
    if exists(query(property owl:oneOf ?any)):
        oneOfByProperty[property].add(restrictionType }
        oneOfByType[restrictionType].add(property){code}
The inference engine needs two methods:
{code}getOneOfImplyingType(type): // return properties that imply this type if reflexive
    properties <- Set<property>
    for sufficientType in ( { type } UNION getAllSubClasses(type) ):
        properties.addAll(oneOfByType[type])
        return properties{code}
{code}getOneOfImplyingProperty(property): // return types that imply this property to be reflexive
    return oneOfByProperty[property] if exists{code}
At query time, apply the visitor:
{code}meet(StatementPattern originalSP):
    if originalSP like (?s rdf:type :C1):  // require that C1 is defined, i.e. not a variable
        node <- originalSP
        for property in getOneOfImplyingType(C1):
            node <- InferUnion(node, StatementPattern(?s, property, ?s)).
        originalSP.replaceWith(node)
    else if originalSP like (s :p o):  // where p is not a variable and at least one of s and o are variables
        node <- originalSP
        for type in getOneOfImplyingProperty(p):
            newNode <- if o is defined:  // meaning s is the variable
                Extension(StatementPattern(o, rdf:type, type), ExtensionElem(o, "s"))
            else: // o is a variable and s may either be defined or a variable
                Extension(StatementPattern(s, rdf:type, type), ExtensionElem(s, "o"))
            node <- InferUnion(node, newNode)
        originalSP.replaceWith(node){code}

> Implement owl:hasSelf inference
> -------------------------------
>
>                 Key: RYA-296
>                 URL: https://issues.apache.org/jira/browse/RYA-296
>             Project: Rya
>          Issue Type: Sub-task
>          Components: sail
>            Reporter: Jesse Hatfield
>
> An *{{owl:hasSelf}}* restriction defines the set of resources that are connected to themselves by a specific property.
> If the ontology states that a {{:Narcissist}} is a resource that {{:loves}} itself, then the inference engine should:
> 1. Rewrite queries of the form {{?x rdf:type :Narcissist}} to find all resources matching {{?x :loves ?x}} (as well as anything explicitly stated to be a :Narcissist) .
> 2. Rewrite queries of either form {{:A :loves ?y}} or {{?z :loves :A}} to match {{:A}} if {{:A}} is known to have the type {{:Narcissist}} .



--
This message was sent by Atlassian JIRA
(v6.4.14#64029)