I created an A-box that describes a person named Yves going to a healthcare appointment (or 'encounter') and having his blood pressure measured. I also added SWRL rules to my model, which should conclude that his blood pressure was elevated, because he was over 18 years old at the time of the appointment and because the value of his systolic blood pressure was > 120.
I have omitted the T-box in the interest of simplicity, but at the expense of uninformative OBO Foundry terms. Let me know if that's a problem.
Why doesn't Stardog like my rules and assertions? I can provide a simpler integer arithmetic SWRL rule that did work for me in Stardog is that's helpful.
Sorry, I'm pretty new to SWRL. I thought I was using swrlb:date to extract the components like encounter year ?ey, month ?em, day ?ed and zone ?ez from a (previously bound) date like ?encStartDateVal, not to construct a date.
?ey and ?by are bound in a subtract operation, whose result is used in the consequent portion. But the other extracted date components don't appear anywhere else in the rule.
Do you have a sense of why it works in Protege, with Pellet? Is Stardog rewriting the rules as a SELECT statement?
@mamillerpaswrlb:date is a built-in predicate that needs all arguments to be bound.
From the docs:
swrlb:date
Satisfied iff the first argument is the xsd:date representation consisting of the year the second argument, month the third argument, day the fourth argument, and timezone the fifth argument.
Not sure if this also means to bind parts if only the date argument was bound. From the specs it does not sound like this.
You could also try your rule or a smaller part in the SQWRL Tab of Protege:
thanks @lorenz_b. you're right, SQWRL doesn't like my date parsing operation either. I started typing a simplified case into a StackOverflow post before I saw your response here. Do you think I should post it, or should I just accept the fact that there is no way to parse the year out of dates with Pellet and SWRL at this point in time?
This SO post from five years ago raises a similar question, and one response suggests importing a temporal ontology in order to get more functions. Do you think that's still relevant? Do you know where to find the temporal ontology they're talking about?
I guess the post refers to the SWRL API built by Martin O'Connor. He created some temporal extension for SWRL, and also piblished a paper about it
O'Connor, M.J. and Das, A. "A Method for Representing and Querying Temporal Information in OWL" Biomedical Engineering Systems and Technologies (Selected Papers), Springer-Verlag, CCIS 127, pp. 97-110, 2011.
but this only works with SWRL API in Protege and isn't in the standard in any sense. Indeed, you could use the temporal ontology, but the custom built-ins wouldn't be considered outside of the SWRL Tab, i.e. neither with Pellet, HermiT nor Stardog.
Seome more stuff about the SWRL API time apporach is spread in the Github Wiki, e.g. 1, 2 or of course in the paper.
That said, I'm still wondering why - as you stated - with standard Pellet your rule works. Had no time to test it. But the Pellet people are basically here
Before getting into SWRL semantics let me mention that with Stardog you can use subtraction with dates directly and compare two durations. In SPARQL (and Stardog rule syntax) this would look like this (or with a BIND if you want the actual difference value):
As you and Lorenz noted with standalone Pellet your rule would work as-is because the SWRL specification allows to bind arbitrary variables in the function arguments. However, functions in Stardog are based on SPARQL specification where there is a fixed return value. Therefore in a SWRL rule only the first variable will be bound to a value.
The other alternative here is to use the date component extraction functions from SPARQL (which were originally defined in XPath). In SPARQL these functions look like as follows:
SELECT * {
BIND("2019-09-07T07:43:56.540"^^xsd:dateTime as ?date)
BIND(year(?date) AS ?year)
BIND(month(?date) AS ?month)
BIND(day(?date) AS ?day)
BIND(hours(?date) AS ?hours)
BIND(minutes(?date) AS ?minutes)
BIND(seconds(?date) AS ?seconds)
}
In SWRL you can use these functions with the http://www.w3.org/ns/sparql# namespace or use the original IRIs from the XPath namespace, e.g. http://www.w3.org/2005/xpath-functions#year-from-dateTime. See the documentation for a complete list of functions Stardog supports and the namespaces recognized by Stardog.
@lorenz_b and @evren, these recent posts are very helpful. Thanks.
I was hoping to write SWRL rules in Protege and then 'use' them at scale in Stardog. I understand that I may not be able to do that now, but that there are good alternatives.
Can you recommend a good tool or strategy for editing SWRL rules with something IDE-like [using the (,) ^ (,) -> (,)] notation and then getting them into RDF, for loading into Stardog?
PS, yes I have seen the documentation regarding Stardog Rule Syntax being strongly encouraged. I can see myself going that direction at some point in the future.
You can still write the rules in Protege and might even test them there if the reasoner you are using supports date arithmetic or the xpath functions I mentioned. If the reasoner does not support those functions then you'd be able to edit them but not run in Protege.
Stardog Studio provides native editing support for Stardog rule syntax [1] which can be written inline in Turtle files. There is no support for SWRL presentation syntax (,) ^ (,) -> (,) but it is possible to translate Stardog rule syntax to SWRL RDF syntax for interoperability.