1

Let's start from the begin. There are some persons stored in graph database with predicates like birthDate, name, etc. I'm currently trying to write custom rule which add some new fact for persons older than e.g. 50 years. So to achieve that two steps are needed: calculate age and filter age.

SPARQL query could look like below:

PREFIX  rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX drl:  <http://...>
SELECT DISTINCT ?person ?age
WHERE { 
  ?person rdf:type drl:Person.
  ?person drl:Person.birthDate/drl:value ?birthDate;       
  BIND(year(now()) - year(?birthDate) as ?age)
  FILTER (?age > 50)
} 

But how to write such rule? According to https://graphdb.ontotext.com/documentation/standard/reasoning.html#entailment-rules

The syntax of a rule definition is as follows:

Id: <rule_name>
    <premises> <optional_constraints>
    -------------------------------
    <consequences> <optional_constraints>

So is it possible to use BIND and FILTER keywords inside <premises> or <optional_constraints>? As I suppose the answear is: NOT :(

Maybe there is anoter way to have such rule?

Seems that SPARQL SPIN functions and magic predicates are not an option for GraphDB?

1 Answers1

0

When you say, "which add some new fact for persons older than e.g. 50 years." I interpret that to mean

  1. You want to construct new triples and add them to the triplestore
  2. You want to detect the new triples with a query like the one you show

Let's say you wish to add a concept of "Retirement Pension Account" to any Person over 60 ( I would say 50 like you, but I am 57 and not ready to retire so I'll make it 60 ;-).

If you have Person data that matches, you can construct triples with SPARQL:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX drl: <http://example.org/drl/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>

CONSTRUCT
{   
    ?person drl:beneficiaryOf ?acct .

    ?acct a drl:RetirementAccount ;
        drl:hasId ?acctId ;
        drl:hasBalance ?balance .
        
}
WHERE {

  ?person rdf:type drl:Person ;
      drl:birthDate/drl:value ?birthDate;       
  BIND(year(now()) - year(?birthDate) as ?age)
  FILTER (?age > 50)
  
BIND(IRI(CONCAT(STR(drl:),"_Account_",STRUUID())) AS ?acct)
BIND(IRI(CONCAT(STR(drl:),"_AccountID_",STRUUID())) AS ?acctId)
BIND(STRDT("10.0",xsd:double) AS ?balance)
} 

Is this the kind of thing you want to do?