It should be perfectly possible to develop a rule built-in function that
executes a SPARQL query over the underlying base graph.
If you need the SPARQL to also see the results of earlier forward
deductions then that would be possible (create a dynamic union of the
base and deductions graphs) but more dangerous. Dangerous in the sense
that your builtin is then exposing the state of the rule processing so
you would need to careful that the rules which use it have suitable
guard clauses to ensure that they are only fired when it makes sense to
issue the query.
Dave
On 06/12/13 00:20, Miguel Bento Alves wrote:
Is it possible call a Sparql command in a rule? Can we do that with a custom
built-in function?
An example:
let's consider that I have the classes Student, Course and Lesson. Lesson is
related with Course. I have an ObjectProperty wasFailedBy that defines that
a given student fails to a given lesson (I list my schema and my data
example below). I want to define an ObjectProperty isDiligent that defines
that a given student is diligent to a given course. I consider that a given
student is diligent to a given course if he didn't fails more than a given
number of lessons (let's consider 1). I can't get this information with OWL
or OWL2 inference, I only can get with a Sparql command.
I'm thinking to define my rule in this way:
(?Student ex:isDiligent ?Course) <-
(?Student rdf:type ex:Student),
(?Course rdf:type ex:Course),
execSparql('
prefix exa: <http://www.example.org/example#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT (COUNT(1) AS ?nCount)
WHERE {
?V1_Student ex:failsTo ?Lesson .
?Lesson exa:isLessonOf ?V2_Course .
}', ?Student, ?Course, ?NCount),
le(?NCount, 1).
In my idea, the custom built-in function execSparql receives as parameters a
string with a Sparql command, a list of instanced variables to be replaced
inside the function and will return the result in the last variable passed
as parameter. I didn't implemented yet because I have doubts if this is the
better approach. My main doubts is:
Can I execute a Sparql command inside a custom built-in function using de
RuleContext?
Can I use a custom built-in function only to be an external access from the
rule and call the Sparql command, for instance via Web Service, to my
inference engine? Any better ideas?
<?xml version="1.0"?>
<!DOCTYPE rdf:RDF [
<!ENTITY owl "http://www.w3.org/2002/07/owl#" >
<!ENTITY exa "http://www.example.org/example#" >
<!ENTITY xsd "http://www.w3.org/2001/XMLSchema#" >
<!ENTITY rdfs "http://www.w3.org/2000/01/rdf-schema#" >
<!ENTITY rdf "http://www.w3.org/1999/02/22-rdf-syntax-ns#" >
]>
<rdf:RDF xmlns="http://www.example.org/example#"
xml:base="http://www.example.org/example#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:exa="http://www.example.org/example#">
<!--
////////////////////////////////////////////////////////////////////////////
///////////
//
// Object Properties
//
////////////////////////////////////////////////////////////////////////////
///////////
-->
<owl:ObjectProperty rdf:about="&exa;isLessonOf">
<rdfs:label>wasFailedBy</rdfs:label>
<rdfs:domain rdf:resource="&exa;Lesson"/>
<rdfs:range rdf:resource="&exa;Course"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:about="&exa;wasFailedBy">
<rdfs:label>wasFailedBy</rdfs:label>
<rdfs:domain rdf:resource="&exa;Lesson"/>
<rdfs:range rdf:resource="&exa;Student"/>
</owl:ObjectProperty>
<owl:ObjectProperty rdf:about="&exa;failsTo">
<rdfs:label>failsTo</rdfs:label>
<owl:inverseOf rdf:resource="&exa;wasFailedBy"/>
</owl:ObjectProperty>
<!--
////////////////////////////////////////////////////////////////////////////
///////////
//
// Classes
//
////////////////////////////////////////////////////////////////////////////
///////////
-->
<owl:Class rdf:about="&exa;Student">
<rdfs:label>Student</rdfs:label>
</owl:Class>
<owl:Class rdf:about="&exa;Course">
<rdfs:label>Course</rdfs:label>
</owl:Class>
<owl:Class rdf:about="&exa;Lesson">
<rdfs:label>Lesson</rdfs:label>
</owl:Class>
<!--
////////////////////////////////////////////////////////////////////////////
///////////
//
// Individuals
//
////////////////////////////////////////////////////////////////////////////
///////////
-->
<owl:Thing rdf:about="&exa;Databases">
<rdfs:label>Databases</rdfs:label>
<rdf:type rdf:resource="&exa;Course"/>
</owl:Thing>
<owl:Thing rdf:about="&exa;ComputerProgramming">
<rdfs:label>Computer Programming</rdfs:label>
<rdf:type rdf:resource="&exa;Course"/>
</owl:Thing>
<owl:Thing rdf:about="&exa;Michael">
<rdfs:label>Michael</rdfs:label>
<rdf:type rdf:resource="&exa;Student"/>
</owl:Thing>
<owl:Thing rdf:about="&exa;Richard">
<rdfs:label>Richard</rdfs:label>
<rdf:type rdf:resource="&exa;Student"/>
</owl:Thing>
<owl:Thing rdf:about="&exa;LessonDB1">
<rdf:type rdf:resource="&exa;Lesson"/>
<isLessonOf rdf:resource="&exa;Databases"/>
<wasFailedBy rdf:resource="&exa;Michael"/>
</owl:Thing>
<owl:Thing rdf:about="&exa;LessonDB2">
<rdf:type rdf:resource="&exa;Lesson"/>
<isLessonOf rdf:resource="&exa;Databases"/>
<wasFailedBy rdf:resource="&exa;Michael"/>
<wasFailedBy rdf:resource="&exa;Richard"/>
</owl:Thing>
<owl:Thing rdf:about="&exa;LessonCP1">
<rdf:type rdf:resource="&exa;Lesson"/>
<isLessonOf rdf:resource="&exa;ComputerProgramming"/>
<wasFailedBy rdf:resource="&exa;Richard"/>
</owl:Thing>
<owl:Thing rdf:about="&exa;LessonCP2">
<rdf:type rdf:resource="&exa;Lesson"/>
<isLessonOf rdf:resource="&exa;ComputerProgramming"/>
<wasFailedBy rdf:resource="&exa;Michael"/>
<wasFailedBy rdf:resource="&exa;Richard"/>
</owl:Thing>
</rdf:RDF>