How to write Jena rule to query class and get indi

2019-08-29 04:46发布

问题:

How to extract all actuators that are switched off when there are no users at home. I tried to write Jena rule but am unable to get proper output. I have added desired result that I want. Need help with writing rule.

[rule1: noValue(:users :hasLocation :home) -> 
(:actuators :hasLocation :home) 
(:actuators :state "OFF"^^xsd:boolean)]  

[rule2: noValue(:users :hasLocation :home) -> 
(?x rdf:type :actuators)  
(?x :hasLocation :home) 
(?x :state "OFF"^^xsd:boolean)]

{ rulex: [noValue(:subject1 :hasPropertyP2 :Object1) -> 
  (:subject2 :hasProperty1 :Object2) 
  (:subject2 :hasPropertyP3 Object3)] }

Ontology: 

class:user
Individual user_1 -> user
Individual user_2 -> user
.
.
class: actuators
subclass: ac -> actuators
subclass: light -> actuators
subclass: other -> actuators

Individual central_ac -> ac
Individual room_lighting -> light
Individual tv -> other
Individual refridgration -> other
Individual heater -> other

result for rule1 [:actuators :state "OFF"^^xsd:boolean]
result for rule2 [:4e62503a:14b01762f42:-7eea :state "OFF"^^xsd:boolean]

desired result:
[central_ac :state "OFF"^^xsd:boolean]
[room_lighting :state "OFF"^^xsd:boolean]
[tv :state "OFF"^^xsd:boolean]
.
.  

回答1:

The rule

[rule1: noValue(:users :hasLocation :home) -> 
        (:actuators :hasLocation :home) 
        (:actuators :state "OFF"^^xsd:boolean)] 

doesn't do what you expect it to, and there may very well be some typos, too. In your ontology (in the future, please provide code that we can actually copy and paste, e.g.,the TTL serialization, or the OWL/FSS), you have a class called user, not users, but in your rule you talk about users. But even if that were corrected, you're not going to get the results you want, because you're using IRIs where you need to be using variables. Your rule says that

  • if the triple :users :hasLocation :home does not appear in the graph,
  • then the triples :actuators :hasLocation :home and :actuators :state "OFF"^^xsd:boolean should be added to the graph.

I think that you want a rule that says:

  • if ?x is an actuator and has a location of home, and there are not users that have the same home as a location,
  • then the state of the actuator should be set to off.

That would look more like:

[(?actuator rdf:type :actuator)
 (?actuator :hasLocation ?home)
 noValue(?user,:hasLocation,?home)
 ->
 (?actuator :state "OFF")]

This will start getting you results in your graph like

[:central_ac :state "OFF"]
[:room_lighting :state "OFF"]
[:tv :state "OFF"]

Note that I removed the ^^xsd:boolean datatype from "OFF", because "OFF" isn't a valid lexical form for the boolean datatype. You could use "true" or "false" instead.