How to query for cyclical relationships in an RDF graph? - sparql

I have the following sample graph of services that includes dependencies information:
#base <https://meta.acme.com/> .
#prefix : <http://schema.meta.acme.com/> .
#prefix dc: <http://purl.org/dc/terms/> .
</service/c84acffd-944a-43c1-8f06-956a4a6033da>
a :Service ;
dc:title "Service 1" ;
:serviceDependency
</service/70987802-9157-4881-ab0c-049b04b7798d>,
</service/2b47109e-26e3-4d06-b245-98730bdb7d43>.
</service/70987802-9157-4881-ab0c-049b04b7798d>
a :Service ;
dc:title "Service 2" ;
:serviceDependency
</service/c84acffd-944a-43c1-8f06-956a4a6033da>,
</service/f45b998c-b496-4318-be40-46c1aafaf6cd> .
</service/2b47109e-26e3-4d06-b245-98730bdb7d43>
a :Service ;
dc:title "Service 3" ;
:serviceDependency </service/> .
</service/f45b998c-b496-4318-be40-46c1aafaf6cd>
a :Service ;
dc:title "Service 4" ;
:serviceDependency </service/> .
I'm writing a SPARQL query to find cycles in the dependency relationships. I have a query that is producing correct results, but it yields pseudo-duplicates.
For example:
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix c: <http://schema.meta.acme.com/>
prefix dc: <http://purl.org/dc/terms/>
select ?a ?aname ?b ?bname
where
{
{
?a a c:Service ;
dc:title ?aname ;
c:serviceDependency ?b .
?b dc:title ?bname .
} filter ( EXISTS { ?b c:serviceDependency ?a } )
}
yields the following output:
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| a | aname | b | bname |
===========================================================================================================================================================================
| <https://meta.acme.com/service/70987802-9157-4881-ab0c-049b04b7798d> | "Service 2" | <https://meta.acme.com/service/c84acffd-944a-43c1-8f06-956a4a6033da> | "Service 1" |
| <https://meta.acme.com/service/c84acffd-944a-43c1-8f06-956a4a6033da> | "Service 1" | <https://meta.acme.com/service/70987802-9157-4881-ab0c-049b04b7798d> | "Service 2" |
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Again, this is as expected - however, the information that I want the query to reflect is the cycle itself and not both sides of the cycle.
My thinking for how to solve this is to calculate an identifier by sorting and concatenating the 2 IDs, then grouping by those IDs, but I wanted to ask whether there's a more natural way to do this in SPARQL?
thanks!

Are these always one-step loops?
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix c: <http://schema.meta.acme.com/>
prefix dc: <http://purl.org/dc/terms/>
select ?a ?aname ?b ?bname
where
{
?a a c:Service ;
dc:title ?aname ;
c:serviceDependency ?b .
?b dc:title ?bname ;
c:serviceDependency ?a
}

Related

SPARQL selecting unittext (blank nodes)

I recently started working with Linked Data and SPARQL.
I've a dataset which contains unittext, indicating what kind of unit the property has (meters, kilograms and so on).
The unit is a values which is inserted on the relationship between object and its quantitative property.
In my RDF dataset the units are included in a blank node and indicated by https://schema.org/unitText.
An example of the data set is included below.
], [
a owl:Restriction ;
owl:minCardinality "0"^^xsd:nonNegativeInteger ;
owl:onProperty <https://someuri> ;
ns1:unitText "kg"
How can I select this property?
The query so far is:
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX owl: <http://www.w3.org/2002/07/owl#>
PREFIX skos: <http://www.w3.org/2004/02/skos/core#>
PREFIX sh: <http://www.w3.org/ns/shacl#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
select distinct ?label ?aspect ?datatype where {
?s rdfs:subClassOf/owl:onProperty ?aspect .
?aspect rdf:type owl:ObjectProperty.
?aspect skos:prefLabel ?label .
?aspect rdfs:range ?datatype .
FILTER EXISTS{ ?aspect rdfs:range ?datatype. }
VALUES ?datatype {
xsd:string
xsd:gYear
xsd:boolean
xsd:decimal
xsd:integer
xsd:date
}
}
The RDF dataset looks actually like this:
rdfs:subClassOf [ a owl:Restriction ;
owl:minCardinality "0"^^xsd:nonNegativeInteger ;
owl:onProperty <someuri> ;
<https://schema.org/unitText> "kg"
] ;

Inferencing in Protege does not infer types based on `subClassOf`

We are developing an ontology, where we need to infer the type of each node, based on some mappings defined in # Test mapping file section. We tried rdfs:subClassOf, as in the below snippet, but it doesn't infer types. Ideally we want to infer Person 1 and Person 2 to NodeTypePerson, also sydney and canberra to NodeTypeCity.
I tried owl:equivalentClass instead but no luck. rdfs:range and rdfs:domain infer types as expected, but having trouble inferring with rdfs:subClassOf. Any advice is highly appreciated.
UPDATE:
owl:equivalentClass works in Protege. (If infers the type). But can't we use rdfs:subClassOf similarly? Actually I want a way to get this done with RDFS inferencing, where owl:equivalentClass doesn't work obviously. Is there any other RDFS property we can use here?
# baseURI: http://www.Test-app.com/ns
#prefix : <http://www.Test-app.com/ns#> .
#prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
#prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
#prefix owl: <http://www.w3.org/2002/07/owl#> .
#prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
#prefix acl: <http://www.w3.org/ns/auth/acl#> .
#prefix cc: <http://creativecommons.org/ns#> .
#prefix cert: <http://www.w3.org/ns/auth/cert#> .
#prefix csvw: <http://www.w3.org/ns/csvw#> .
#prefix dc: <http://purl.org/dc/terms/> .
#prefix dcam: <http://purl.org/dc/dcam/> .
#prefix dcat: <http://www.w3.org/ns/dcat#> .
#prefix dctype: <http://purl.org/dc/dcmitype/> .
#prefix foaf: <http://xmlns.com/foaf/0.1/> .
#prefix ldp: <http://www.w3.org/ns/ldp#> .
#prefix posixstat: <http://www.w3.org/ns/posix/stat#> .
#prefix schema: <https://schema.org/> .
#prefix shacl: <http://www.w3.org/ns/shacl#> .
#prefix skos: <http://www.w3.org/2004/02/skos/core#> .
#prefix skosxl: <http://www.w3.org/2008/05/skos-xl#> .
#prefix solid: <http://www.w3.org/ns/solid/terms#> .
#prefix swapdoc: <http://www.w3.org/2000/10/swap/pim/doc#> .
#prefix ui: <http://www.w3.org/ns/ui#> .
#prefix vann: <http://purl.org/vocab/vann/> .
#prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
#prefix vs: <http://www.w3.org/2003/06/sw-vocab-status/ns#> .
#prefix ws: <http://www.w3.org/ns/pim/space#> .
#base <http://www.Test-app.com/ns> .
<http://www.Test-app.com/ns>
rdf:type owl:Ontology ;
dc:title "Test Ontology"#en ;
owl:versionIRI <http://www.Test-app.com/ns/0.1> .
# Test mapping file
#prefix test: <http://www.Test-app.com/ns#> .
:Person
a rdfs:Class ;
owl:equivalentClass :NodeTypePerson .
:locatedNear
a rdf:Property ;
rdfs:subClassOf :NodeCustomAttribute ;
rdfs:label "Located Near" .
:Location
a rdfs:Class ;
rdfs:label "Location" ;
rdfs:subClassOf :NodeTypeCity ;
rdfs:comment "This represents a geolocation." .
:City
a rdfs:Class ;
rdfs:label "City" ;
rdfs:comment "This represents a city." ;
rdfs:subClassOf :Location .
# Some graph instances data
:sydney
a :City ;
rdfs:label "Sydney" ;
rdfs:comment "Australia's largest city." .
:canberra
a :City ;
rdfs:label "Canberra" ;
rdfs:comment "Australia's national capital." .
:person1
a :Person ;
rdfs:label "Person 1" ;
rdfs:comment "First vertex." ;
:locatedNear :sydney .
:person2
a :Person ;
rdfs:label "Person 2" ;
rdfs:comment "Second vertex." ;
:locatedNear :canberra .
# Types
:NodeTypePerson
rdf:type rdfs:Class ;
rdfs:label "NodeTypePerson" ;
rdfs:comment "" ;
vs:term_status "stable" ;
rdfs:isDefinedBy <http://www.Test-app.com/ns> .
:NodeTypeCity
rdf:type rdfs:Class ;
rdfs:label "NodeTypeCity" ;
rdfs:comment "" ;
vs:term_status "stable" ;
rdfs:isDefinedBy <http://www.Test-app.com/ns> .```

SPARQL help to build modify query

I have to add a few new fields to existing report. Our system already have a lot of reports with types AccountTeamBodReport, CoordinatorBodReport. Also I want to set default value for new fields.
PREFIX : <http://example.com/knowledge-black-belt#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
INSERT { ?s :hasResult "" ; //(new fields)
:hasResultPriority "MEDIUM";
:hasLowMarginComments "";
:hasLowMarginCommentsPriority "MEDIUM";
}
WHERE
{ ?s rdf:type ?type ;
FILTER ( ?type IN (:AccountTeamBodReport, :CoordinatorBodReport) )
}
It doesn't work. There is any errors. What I did wrong? I use fuseki server and check all my query there. Fuseki logs have only successful responds. When I want to see specific report I use:
PREFIX : <http://dataart.com/knowledge-black-belt#>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
SELECT *
WHERE
{ ?s :hasId ?name ;
rdf:type ?type ;
:hasCreationTime ?created ;
:hasReportMonth ?reportMonth ;
:hasAchievements ?achievements ;
:hasAchievementsPriority ?achievementsPriority ;
:hasRisksIssues ?risksIssues ;
:hasRisksIssuesPriority ?risksIssuesPriority ;
:hasOther ?other ;
:hasOtherPriority ?otherPriority ;
:hasPerformance ?performance ;
:hasCustomerRelationship ?customerRelationship ;
:hasTeamMorale ?teamMorale ;
:hasNoNews ?noNews ;
:hasResult ?result ;
:hasResultPriority ?resultPriority;
:hasLowMarginComments ?lowMarginComments;
:hasLowMarginCommentsPriority ?lowMarginCommentsPriority;
:hasClient ?client
OPTIONAL
{ ?s :hasIndicatorDescription ?indicatorDescription}
?s rdf:type ?type ;
:hasClient :clientSomeId
FILTER ( ?type IN (:AccountTeamBodReport, :CoordinatorBodReport) )
}
And there is any changes after Insert query.

Ask for the presence of all specified values?

I have exactly these triples in GraphDB:
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
<http://example.com/greeting>
a <http://example.com/word> ;
rdfs:label "hello" .
I want to know if there is a thing in my triplestore with the label "hello" and another with the label "goodbye"
PREFIX : <http://example.com/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
ASK
WHERE
{ VALUES ?l { "goodbye" "hello" }
?s a :thing ;
rdfs:label ?l
}
I am being told that yes, this is true, as if it is saying at least one of those are true. But I want to know if all of those patterns are true.
Can I do that in a SPARQL ASK?
I also tried the following but got the same (unwanted) result:
PREFIX : <http://example.com/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
ASK
WHERE
{ VALUES (?l) { ("goodbye") ("hello") }
?s a :thing ;
rdfs:label ?l
}
Sanity check: the answer to this ASK is false
PREFIX : <http://example.com/>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
ASK
WHERE
{ VALUES (?l) { ("goodbye") }
?s a :thing ;
rdfs:label ?l
}
Rather than asking "are all of these present", ask "is any of these not present" (and then negate the result either I've your application or with another "filter not exists":
ask {
values ?label { "hello" "goodbye" }
filter not exists {
?s a :thing ; rdfs:label ?word
}
}
My group is developing tools to convert tabular data about hospital records into RDF triples and then perform various cleanups and aggregations.
I have started this "answer" by writing out an illustration of this workflow with sample data.
Working implementations of the suggestions from #Joshua Taylor and #AKSW's are at the bottom.
The tabular data is first converted into "shortcut triples", which instantiate a minimal number of classes and link all literal values to those classes, even if the literal values are really "more about" something else.
So tabular data like this:
+-------+------------+----------+----------+
| EncID | EncDate | DiagCode | CodeType |
+-------+------------+----------+----------+
| 102 | 12/05/2015 | J44.9 | ICD-10 |
| 103 | 11/25/2015 | 602.9 | ICD-9 |
| 102 | 12/05/2015 | I50.9 | ICD-10 |
+-------+------------+----------+----------+
First becomes triples like this (ignoring the EncDates and CodeTypes.)
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX turbo: <http://example.org/ontologies/>
PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
INSERT DATA {
GRAPH turbo:encounters_from_karma {
turbo:5f62d61cee174283a4f875ccb8bb91a1 rdf:type obo:OGMS_0000097 .
turbo:5f62d61cee174283a4f875ccb8bb91a1 turbo:ScEnc2DiagCode "J44.9" .
turbo:5f62d61cee174283a4f875ccb8bb91a1 turbo:ScEnc2DiagCodeRegText "ICD-10" .
turbo:5f62d61cee174283a4f875ccb8bb91a1 turbo:ScEnc2EncID "102" .
turbo:81fcbb5c5bd141c9bde7f23321648ff7 rdf:type obo:OGMS_0000097 .
turbo:81fcbb5c5bd141c9bde7f23321648ff7 turbo:ScEnc2DiagCode "I50.9" .
turbo:81fcbb5c5bd141c9bde7f23321648ff7 turbo:ScEnc2DiagCodeRegText "ICD-10" .
turbo:81fcbb5c5bd141c9bde7f23321648ff7 turbo:ScEnc2EncID "102" .
turbo:820dd597229244ab853ed845dd740f1f rdf:type obo:OGMS_0000097 .
turbo:820dd597229244ab853ed845dd740f1f turbo:ScEnc2DiagCode "602.9" .
turbo:820dd597229244ab853ed845dd740f1f turbo:ScEnc2DiagCodeRegText "ICD-9" .
turbo:820dd597229244ab853ed845dd740f1f turbo:ScEnc2EncID "103" . }
}
And is then expanded like this
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX turbo: <http://example.org/ontologies/>
INSERT {
GRAPH turbo:expanded_encounters {
?NewEnc rdf:type obo:OGMS_0000097 .
?NewEnc turbo:previousUriText ?previousUriText .
?NewEnc obo:OBI_0000299 ?DiagCrid .
?DiagCrid rdf:type turbo:DiagCrid .
?DiagCrid obo:BFO_0000051 ?DiagSymb .
?DiagSymb rdf:type turbo:EncounterDiagCodeSymbol .
?DiagSymb turbo:thingLiteralValue ?DiagSymbVal .
}
}
WHERE
{ GRAPH turbo:encounters_from_karma
{ ?EncFromKarma
rdf:type obo:OGMS_0000097 ;
turbo:ScEnc2DiagCode ?DiagSymbVal
BIND(str(?EncFromKarma) AS ?previousUriText)
BIND(uri(concat("http://transformunify.org/ontologies/", struuid())) AS ?NewEnc)
BIND(uri(concat("http://transformunify.org/ontologies/", struuid())) AS ?DiagCrid)
BIND(uri(concat("http://transformunify.org/ontologies/", struuid())) AS ?DiagSymb)
}
}
And therefore looks like this:
#prefix turbo: <http://purl.obolibrary.org/obo/> .
#prefix obo: <http://example.org/ontologies/> .
<http://example.org/ontologies/b9dc5b08-cf1b-465e-8773-4b19bfbcf803>
a <http://purl.obolibrary.org/obo/OGMS_0000097> ;
turbo:OBI_0000299 <http://example.org/ontologies/8a04f52f-22d2-4aab-bacf-d96e1c7fe900> ;
obo:previousUriText "http://example.org/ontologies/5f62d61cee174283a4f875ccb8bb91a1" .
obo:8a04f52f-22d2-4aab-bacf-d96e1c7fe900
a obo:DiagCrid ;
turbo:BFO_0000051 obo:6738d8c0-8bb8-4078-8430-5e9294e5af15 .
obo:6738d8c0-8bb8-4078-8430-5e9294e5af15
a obo:EncounterDiagCodeSymbol ;
obo:thingLiteralValue "J44.9" .
obo:d3a8a700-2eb9-420d-a863-d47462fa393c
a turbo:OGMS_0000097 ;
turbo:OBI_0000299 obo:c12acc26-6dbe-486d-9ae9-9f34c9561aea ;
obo:previousUriText "http://example.org/ontologies/81fcbb5c5bd141c9bde7f23321648ff7" .
obo:c12acc26-6dbe-486d-9ae9-9f34c9561aea
a obo:DiagCrid ;
turbo:BFO_0000051 obo:3b784151-b369-4594-9ce3-285f5fe60850 .
obo:3b784151-b369-4594-9ce3-285f5fe60850
a obo:EncounterDiagCodeSymbol ;
obo:thingLiteralValue "I50.9" .
obo:af0e949a-99e4-48cd-885b-7cb1aa3dd265
a turbo:OGMS_0000097 ;
turbo:OBI_0000299 obo:c2da52ec-7331-4011-b8f8-6fbf8b419708 ;
obo:previousUriText "http://example.org/ontologies/820dd597229244ab853ed845dd740f1f" .
obo:c2da52ec-7331-4011-b8f8-6fbf8b419708
a obo:DiagCrid ;
turbo:BFO_0000051 obo:7f8399ef-5fcd-447c-80a4-18dfb160e99c .
obo:7f8399ef-5fcd-447c-80a4-18dfb160e99c
a obo:EncounterDiagCodeSymbol ;
obo:thingLiteralValue "602.9" .
Finally, I can check for the correct transformation with the suggestions from #Joshua Taylor or #AKSW:
#Joshua Taylor
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX turbo: <http://example.org/ontologies/>
ASK
WHERE
{ { GRAPH turbo:expanded_encounters
{ VALUES ( ?previousUriTextVal ?DiagSymbVal ) {
( "http://example.org/ontologies/5f62d61cee174283a4f875ccb8bb91a1" "J44.9" )
( "http://example.org/ontologies/820dd597229244ab853ed845dd740f1f" "602.9" )
( "http://example.org/ontologies/81fcbb5c5bd141c9bde7f23321648ff7" "I50.9" )
}
FILTER NOT EXISTS { ?NewEnc rdf:type obo:OGMS_0000097 ;
turbo:previousUriText ?previousUriTextVal ;
obo:OBI_0000299 ?DiagCrid .
?DiagCrid rdf:type turbo:DiagCrid ;
obo:BFO_0000051 ?DiagSymb .
?DiagSymb rdf:type turbo:EncounterDiagCodeSymbol ;
turbo:thingLiteralValue ?DiagSymbVal
}
}
}
}
#AKSW
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX obo: <http://purl.obolibrary.org/obo/>
PREFIX turbo: <http://example.org/ontologies/>
ASK
WHERE
{ GRAPH turbo:expanded_encounters
{ FILTER ( ?count = 3 )
{ SELECT (COUNT(DISTINCT ?NewEnc) AS ?count)
WHERE
{ VALUES ( ?previousUriTextVal ?DiagSymbVal ) {
( "http://example.org/ontologies/5f62d61cee174283a4f875ccb8bb91a1" "J44.9" )
( "http://example.org/ontologies/820dd597229244ab853ed845dd740f1f" "602.9" )
( "http://example.org/ontologies/81fcbb5c5bd141c9bde7f23321648ff7" "I50.9" )
}
?NewEnc rdf:type obo:OGMS_0000097 ;
turbo:previousUriText ?previousUriTextVal ;
obo:OBI_0000299 ?DiagCrid .
?DiagCrid rdf:type turbo:DiagCrid ;
obo:BFO_0000051 ?DiagSymb .
?DiagSymb rdf:type turbo:EncounterDiagCodeSymbol ;
turbo:thingLiteralValue ?DiagSymbVal
}
}
}
}

Sparql - Applying limiting criteria to predicates

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?
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>
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:
Query Solution
Query Definition