ucbl / HyLAR-Reasoner

HyLAR reasoner
https://www.npmjs.com/package/hylar
MIT License
61 stars 13 forks source link

PropertyChainAxiom #7

Closed MadsHolten closed 6 years ago

MadsHolten commented 6 years ago

Hi,

I was trying to add an owl:propertyChainAxiom rule, but I can't get it to work.

The ontology is available here. It is loaded in and I have no problems inferring rules given by rdfs:subClassOf etc. I just can't get my own rule to work.

Triples: `@prefix bot: https://w3id.org/bot# .

bot:hasSpace . bot:containsElement .` Test query: `PREFIX bot: SELECT * WHERE { ?x bot:containsZone ?y . ?y bot:containsElement ?z . }` Hylar recognizes that bot:hasSpace is an rdfs:subPropertyOf bot:containsZone and returns a correct result: `[ { x: { token: 'uri', value: 'levelA' }, y: { token: 'uri', value: 'spaceA' }, z: { token: 'uri', value: 'elementA' } } ]` Before writing the general rule I wanted to test one for the specific case (which doesn't work): `(?z1 https://w3id.org/bot#containsZone ?z2) ^ (?z2 https://w3id.org/bot#containsElement ?el) -> (?z1 https://w3id.org/bot#containsElement ?el)` This general rule should work: `(?x ?p1 ?y) ^ (?p2 http://www.w3.org/2002/07/owl#propertyChainAxiom ?n) ^ (?n http://www.w3.org/1999/02/22-rdf-syntax-ns#first ?p1) ^ (?n http://www.w3.org/1999/02/22-rdf-syntax-ns#rest ?n2) ^ (?n2 http://www.w3.org/1999/02/22-rdf-syntax-ns#first ?p2) ^ (?y ?p2 ?z) -> (?x ?p2 ?z)` Thanks for sharing your work. From what I know this is the only OWL2 reasoner for JavaScript.
MadsHolten commented 6 years ago

To check the general rule I performed the following query: PREFIX bot: <https://w3id.org/bot#> PREFIX owl: <http://www.w3.org/2002/07/owl#> PREFIX rdfs: <http://www.w3.org/1999/02/22-rdf-syntax-ns> SELECT ?x ?p1 ?y ?p2 ?z WHERE { ?x ?p1 ?y . ?p2 owl:propertyChainAxiom ?n . ?n <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> ?p1 . ?n <http://www.w3.org/1999/02/22-rdf-syntax-ns#rest> ?n2 . ?n2 <http://www.w3.org/1999/02/22-rdf-syntax-ns#first> ?p2 . ?y ?p2 ?z . }

which gives me all the variables needed: [ { x: { token: 'uri', value: 'levelA' }, p1: { token: 'uri', value: 'https://w3id.org/bot#containsZone' }, y: { token: 'uri', value: 'spaceA' }, p2: { token: 'uri', value: 'https://w3id.org/bot#containsElement' }, z: { token: 'uri', value: 'elementA' } } ] ..still no luck with the rule though

mterdjimi commented 6 years ago

Hi,

Thanks for this issue. Indeed, PropertyChainAxiom are not natively supported by HyLAR, mainly because the blank node inference is not supported.

To be more specific, when rdfstore parses a list, it generates blank nodes, which can actually be queried (as shown below) image However, no inference is currently supported on statements with blank nodes, this is why is does not work as expected, even with the supplied rule.

I will work on it !

Regards,

MT.

MadsHolten commented 6 years ago

Okay, I see. Thanks for your swift response!

I see the problem with blank nodes, but the specific rule should still work, right? <A> bot:containsZone <B> ^ <B> bot:containsElement <C> -> <A> bot:containsElement <C>

If you are curious about what I am using it for, here is a demo of my implementation and the source code is here.

Again thanks for your effort!

mterdjimi commented 6 years ago

Hi, Can you try to replace <A> with an uri beginning with http://, such as <http://example.com/A> then retry with your specific rule, please ?

Thanks

mterdjimi commented 6 years ago

I pushed a new branch that may fix your issue with PropertyChainAxioms here. Can you try with this general rule please ?

Thanks

MadsHolten commented 6 years ago

Okay, so I can't really get any rule to work. Maybe I am doing something wrong.

Code:

h.load(triples, mimeType)
    .then(response => {
        // Add test rule
        return h.parseAndAddRule('(?a https://w3id.org/bot#containsElement ?b) -> (?a http://www.w3.org/1999/02/22-rdf-syntax-ns#label "test")', 'label-test');
    })
    .then(response => {
        console.log(h) // will show my new rule!
        return h.query(query);
    })
    .then(results => {
        console.log(results) // log results to console
    });

Query:

PREFIX bot: <https://w3id.org/bot#>
PREFIX rdfs: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT *
WHERE {
    ?x bot:containsElement ?el .
    ?x rdfs:label ?label .
}

Expected output:

[ { x:
     { token: 'uri',
       value: 'https://example.org/projectXX/space00aa' },
    el:
     { token: 'uri',
       value: 'https://example.org/projectXX/heater235' },
    label: { token: 'literal', value: 'test' } 
} ]

Actual output: Nothing

I also tried using the branch where you implemented the propertyChainAxiom. The following data:

@prefix bot:    <https://w3id.org/bot#> .
@prefix inst:    <https://example.org/projectXX/> .
@prefix rdfs:       <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:    <http://www.w3.org/2002/07/owl#> .

# TBOX
bot:containsZone a owl:ObjectProperty , owl:TransitiveProperty .

bot:hasStorey a owl:ObjectProperty ;
               rdfs:subPropertyOf bot:containsZone .

bot:hasSpace a owl:ObjectProperty ;
               rdfs:subPropertyOf bot:containsZone .

bot:containsElement a owl:ObjectProperty ;
               owl:propertyChainAxiom  ( bot:containsZone bot:containsElement ) .

# ABOX
inst:buildingA a bot:Building ;
               bot:hasStorey inst:storey00 .

inst:storey00 a bot:Storey ;
              bot:hasSpace inst:space00aa .

inst:space00aa a bot:Space ;
               bot:containsElement inst:heater235 .

inst:heater235 a bot:Element .

This query:

PREFIX bot: <https://w3id.org/bot#>
SELECT *
WHERE {
    ?s bot:containsElement ?el .
}

Should return:

[ { s:
     { token: 'uri',
       value: 'https://example.org/projectXX/buildingA' },
    el:
     { token: 'uri',
       value: 'https://example.org/projectXX/heater235' } 
}, { s:
     { token: 'uri',
       value: 'https://example.org/projectXX/space00aa' },
    el:
     { token: 'uri',
       value: 'https://example.org/projectXX/heater235' } 
} ]

But only returns:

[ { s:
     { token: 'uri',
       value: 'https://example.org/projectXX/space00aa' },
    el:
     { token: 'uri',
       value: 'https://example.org/projectXX/heater235' } 
} ]
mterdjimi commented 6 years ago

Hi,

Tested (on the branch recently pushed) with the ontology and your triples

@prefix bot:    <https://w3id.org/bot#> .
@prefix inst:    <https://example.org/projectXX/> .
@prefix rdfs:       <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl:    <http://www.w3.org/2002/07/owl#> .

# TBOX
bot:containsZone a owl:ObjectProperty , owl:TransitiveProperty .

bot:hasStorey a owl:ObjectProperty ;
               rdfs:subPropertyOf bot:containsZone .

bot:hasSpace a owl:ObjectProperty ;
               rdfs:subPropertyOf bot:containsZone .

bot:containsElement a owl:ObjectProperty ;
               owl:propertyChainAxiom  ( bot:containsZone bot:containsElement ) .

# ABOX
inst:buildingA a bot:Building ;
               bot:hasStorey inst:storey00 .

inst:storey00 a bot:Storey ;
              bot:hasSpace inst:space00aa .

inst:space00aa a bot:Space ;
               bot:containsElement inst:heater235 .

inst:heater235 a bot:Element .

querying with

PREFIX bot: <https://w3id.org/bot#>
SELECT *
WHERE {
    ?s bot:containsElement ?el .
}

I obtain

[ { s: 
     { token: 'uri',
       value: 'https://example.org/projectXX/storey00' },
    el: 
     { token: 'uri',
       value: 'https://example.org/projectXX/heater235' } },
  { s: 
     { token: 'uri',
       value: 'https://example.org/projectXX/space00aa' },
    el: 
     { token: 'uri',
       value: 'https://example.org/projectXX/heater235' } },
  { s: 
     { token: 'uri',
       value: 'https://example.org/projectXX/buildingA' },
    el: 
     { token: 'uri',
       value: 'https://example.org/projectXX/heater235' } } ]

With these steps, I did not reproduce your error. My test code is shown below

return h.load(onto, 'text/turtle')
            .then(results => {
                return h.load(triples, 'text/turtle', true);
            }).then(results => {
                return h.parseAndAddRule('(?a https://w3id.org/bot#containsElement ?b) -> (?a http://www.w3.org/1999/02/22-rdf-syntax-ns#label "test")', 'label-test');
            })
            .then(results => {// will show my new rule!
                return h.query(query);
            })
            .then(results => {
                console.log(results) // log results to console
            });
MadsHolten commented 6 years ago

@mterdjimi - just wanted you to know that it also works for me now. I have implemented a Heroku hosted endpoint for Hylar reasoning which I am using here. The example shows our dataset + a construct query performed on it. Feel free to use the tool whenever you discuss an RDF problem with someone :)

mterdjimi commented 6 years ago

I just checked it, well done ! I am glad the fix solved your problem. I will include it in the next HyLAR release (asap ;-) )