I have an RDF/XML dataset, and it has some relations that can be built into some inference rules. I built my inference rules using SPARQL
in Jena API. For example, there is a part_of
relation, if termA
is part_of
termB
, and termB
is part_of
termC
, so we can infer that termA
is part_of
termC
. But I need to make this rule work recursively, so I want all the triples inferred from this rule to be let say the input dataset again then be checked using this rule. To infer new triples I used construct
in SPARQL
:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX go: <http://www.geneontology.org/dtds/go.dtd#>
CONSTRUCT {?termA go:part_of ?termC}
WHERE {
?termA go:part_of ?termB .
?termB go:part_of ?termC .
FILTER (?termA != ?termC) .
}
from this query above, I can infer only the two level of part_of
relation, but what I need is the multilevel one. So I tried to make a subquery like this, using the syntax shown in slide 9 of Marianne Shaw's Ontology Views Update, which in turn might be based on Simon Schenk's A SPARQL Semantics Based on Datalog:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX go: <http://www.geneontology.org/dtds/go.dtd#>
CONSTRUCT {?termA go:part_of ?termC}
FROM <A:/workspace_luna/RDFQuery/src/test.rdf>
FROM NAMED ?g <CONSTRUCT {?termA go:part_of ?termC}
FROM <A:/workspace_luna/RDFQuery/src/test.rdf>
WHERE {
?termA go:part_of ?termB .
?termB go:part_of ?termC .
FILTER (?termA != ?termC) .
}>
WHERE {
?termA go:part_of ?termB .
?termB go:part_of ?termC .
FILTER (?termA != ?termC) .
}
But I obtained an error. I've looked around in many sources and also I tried to apply to my queries, but no one works. Is there any other way to do this?
Problems in your code
I'm not sure what subquery syntax you're trying to use, but it's not legal. Subqueries are just wrapped in braces. E.g.,
The query you've written isn't legal.
If you don't show us the error, we certainly can't help in fixing it. I expect that you got a syntax error. You can validate your query using sparql.org's query validator. That probably won't help too much in this case, though, because you can only use select queries in subqueries. (It would be very helpful, though, if construct queries were supported for subqueries.)
Transitive closures for construct queries
In general, you can't do arbitrary recursion in SPARQL. However, in the specific case that you've got, you can use property paths in the pattern to construct the transitive closure of a pattern. E.g.,
This says that if there's a path of non-zero length from ?a to ?c using just :partOf links, then include a triple ?a :partOf ?b in the constructed output.