I'm fairly new to RDF / Sparql, so apologies for any incorrect terminology, and also for the fairly terrible example that follows:
Given the following RDF dataset:
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix e: <http://www.example.com/#> .
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
e:Freemason a owl:Class .
e:Civilian a owl:Class .
e:Marty a e:Freemason .
e:Eugene a e:Freemason .
e:Mike a e:Freemason .
e:Alan a e:Freemason .
e:Paul a e:Civilian .
e:Marty foaf:knows e:Eugene .
e:Eugene foaf:knows e:Mike .
e:Eugene foaf:knows e:Paul .
e:Paul foaf:knows e:Alan .
I'm trying to identify friends-of-friends that e:Marty
knows through other e:Freemason
s only.
So:
- Marty knows Mike through Eugene, and they're all Freemason's so it's fine
- Marty knows Eugene, who has a Civilian friend Paul. Paul has a Freemason friend Alan. However, Marty doesn't have a "freemason only" path to Alan, so he should be excluded.
Here's the SPARQL query I have:
prefix e: <http://www.example.com/#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
SELECT *
{
<http://www.example.com/#Marty> foaf:knows+ ?target .
?target a e:Freemason .
}
This returns:
http://www.example.com/#Eugene
http://www.example.com/#Mike
http://www.example.com/#Alan
Here, Alan is included as he matches the is-a-freemason
criteria.
How I do modify the query to exclude Alan?
I don't know the solution in pure SPARQL, sorry. In OpenLink Virtuoso's SPARQL-BI, the solution is this query
-- with these results --
Here's an example using SPARQL that has been deprecated from the spec (for reasons I never understood) but remains supported in Virtuoso (which will be the case for the unforseeable future)
Live Links: