3

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:Freemasons 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?

Marty Pitt
  • 28,822
  • 36
  • 122
  • 195
  • I don't have an answer for you right away, but I am almost sure that you cannot do this in a single query. If it _is_ possible, it would certainly be a fairly complex SPARQL query. – Jeen Broekstra Jul 28 '16 at 23:48
  • Related question: http://stackoverflow.com/questions/18024413/finding-all-steps-in-property-path – Jeen Broekstra Jul 28 '16 at 23:48
  • I think Jeen is right; I don't think you can do this with a single sparql query. I'd you are using an endpoint that supports querying over CONSTRUCTed data (I think dot net RDF does, but I don't know whether any other ones do) then this is a fairy simple query over constructed data. – Joshua Taylor Jul 29 '16 at 02:11
  • 1
    You could do this with a query over CONSTRUCT-ed data though. See http://stackoverflow.com/questions/17363199/how-to-get-a-concise-bounded-description-of-a-resource-with-sesame and some of the comments on my answer for some ideas. Instead of a self isIRI property, you'd want a isSelfFreemason property. It's a kind of rolification. – Joshua Taylor Jul 29 '16 at 02:15

2 Answers2

2

I don't know the solution in pure SPARQL, sorry. In OpenLink Virtuoso's SPARQL-BI, the solution is this query

prefix e: <http://www.example.com/#>
prefix foaf:  <http://xmlns.com/foaf/0.1/>
select * 
where
  {
    { select ?orig ?target 
      where
       { ?orig   foaf:knows ?target . 
         ?target a          e:Freemason .
       } 
    } 
    option ( TRANSITIVE, 
             T_IN(?orig), 
             T_OUT(?target), 
             T_DISTINCT, 
             T_MIN(1)
           )
    filter ( ?orig = <http://www.example.com/#Marty> )
  }

-- with these results --

orig                               target
<http://www.example.com/#Marty>    <http://www.example.com/#Eugene>
<http://www.example.com/#Marty>    <http://www.example.com/#Mike>
TallTed
  • 9,069
  • 2
  • 22
  • 37
1

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 unforeseeable future)

## RDF-Turtle Start ##

@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 .

## RDF-Turtle End ##

Using Property Path Pattern from SPARQL that has been deprecated

but preserved in Virtuoso

PREFIX e: <http://kingsley.idehen.net/DAV/home/kidehen/Public/Linked%20Data%20Documents/Tutorials/club-member-test.ttl#>
PREFIX dsn: <http://kingsley.idehen.net/DAV/home/kidehen/Public/Linked%20Data%20Documents/Tutorials/club-member-test.>
PREFIX foaf:  <http://xmlns.com/foaf/0.1/>
    
SELECT *
FROM dsn:ttl
WHERE {
       e:Marty foaf:knows{2} ?target .
       ?target a e:Freemason .
      }

Live Links:

  1. Query Solution
  2. Query Definition