Invalid Rule error with property path

I have the following rule:

RULE :has_Entering_Water_Temperature_Sensor_Rule
IF {
    ?class a brick:Chiller ; brick:hasPoint ?point .
    ?point rdf:type/rdfs:subClassOf* brick:Entering_Water_Temperature_Sensor .
}
THEN {
    ?class :has_Entering_Water_Temperature_Sensor ?point
}

The IF works file when I run as a query, but the rule doesn't work - the error message seems to indicate a failure to parse the 2nd line (the property path). Am I doing this wrong?

WARN  2020-11-26 11:10:43,550 [stardog-user-2] com.complexible.stardog.reasoning.rule.RuleExtractor:parseRule(156): Ignoring invalid rule:
 IF {
   ?class a <https://brickschema.org/schema/1.1/Brick#Chiller> ;
          <https://brickschema.org/schema/1.1/Brick#hasPoint> ?point .
   ?point a/<http://www.w3.org/2000/01/rdf-schema#subClassOf>* <https://brickschema.org/schema/1.1/Brick#Entering_Water_Temperature_Sensor> .
}
THEN {
   ?class <http://example.com/ontology#has_Entering_Water_Temperature_Sensor> ?point .
}

Parse error was: Invalid rule, a variable is used as the predicate of a triple pattern: (?point rdf:type ?gsnztxqt)

I'd also be interested to know if I can use reasoning to define this directly, i.e. I've defined has_Leaving_Water_Temperature_Sensor as below - is there a way I can avoid defining rules for the reasoner to infer this property?

:has_Leaving_Water_Temperature_Sensor a owl:ObjectProperty ;
  rdfs:subPropertyOf brick:hasPoint;
  rdfs:domain brick:Chiller;
  rdfs:range brick:Leaving_Water_Temperature_Sensor .

Hi David,

The query for points is:

?point rdf:type/rdfs:subClassOf* brick:Entering_Water_Temperature_Sensor .

This is unnecessary. You can simply specify ?point rdf:type brick:Entering_Water_Temperature_Sensor. When reasoning is enabled, any instance of a class which is a subclass of Entering_Water_Temperature_Sensor will be inferred to be an instance of Entering_Water_Temperature_Sensor. Does that help?

Additionally, your subPropertyOf assertion will also make it unnecessary to write a rule which infers triples with predicate has_Entering_Water_Temperature_Sensor when a similar triple with predicate hasPoint exists. Let me know if this makes sense and if it's working for you. We'll be glad to explain more or help debug the reasoning definitions.

Thanks Jess

Yes that works. I guess what I'm unsure of is my original query also "worked" - even though it was unnecessarily complex - but only when I ran it startdog studio (with and without reasoning on). So it seems that the SPARQL the rules engine accepts is a subset of the SPARQL I can run in the workspace?

Also I'm not following the last paragraph "your subPropertyOf assertion will also make it unnecessary to write a rule which infers triples with predicate has_Entering_Water_Temperature_Sensor when a similar triple with predicate hasPoint exists"

If you're saying that the predicate

:has_Leaving_Water_Temperature_Sensor a owl:ObjectProperty ;
  rdfs:subPropertyOf brick:hasPoint;
  rdfs:domain brick:Chiller;
  rdfs:range brick:Leaving_Water_Temperature_Sensor .

Should be enough for

SELECT * WHERE {?s :has_Leaving_Water_Temperature_Sensor ?o}

to work (with reasoning on) then that's what I originally assumed but it's not working.

It sounds like you have the hasPoint/has_Leaving_Water_Temperature_Sensor relationship backwards. You have this axiom:
:has_Leaving_Water_Temperature_Sensor rdfs:subPropertyOf brick:hasPoint;. This means that every asserted triple of ?x :has_Leaving_Water_Temperature_Sensor ?y will return a result when querying ?x brick:hasPoint ?y. Does that make sense?

This is the Brick.ttl definition of hasPoint

brick:hasPoint a owl:AsymmetricProperty,
        owl:IrreflexiveProperty,
        owl:ObjectProperty ;
    rdfs:range brick:Point ;
    owl:inverseOf brick:isPointOf ;
    skos:definition "The subject has a digital/analog input/output point given by the object"@en .

The domain is anything and the range a brick:Point

I'm trying to say that a :has_Entering_Water_Temperature_Sensor is a subset, i.e. a

:CH1 brick:hasPoint :CH1_Entering_Water_Temperature_Sensor

should match since :CH1 a brick:Chller and :CH1_Entering_Water_Temperature_Sensor a brick:Entering_Water_Temperature_Sensor a brick:Point

So yes every ?x :has_Leaving_Water_Temperature_Sensor ?y is a member of ?x brick:hasPoint ?y

This is the triples for hasPoint and isPoint

?x brick:hasPoint ?y

and

?x ?y brick:Point

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.