It's much easier to answer this type of question if you provide data and code that we can work with without having to add a whole bunch of stuff to make it complete. E.g., provide complete working RDF documents. Your data is something like this (in Turtle):
@prefix ns: <http://stackoverflow.com/q/20287293/1281433/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
ns:Person a owl:Class .
ns:Man rdfs:subClassOf ns:Person .
ns:Woman rdfs:subClassOf ns:Person .
ns:Family a owl:Class .
ns:jean a ns:Man .
ns:roger a ns:Man .
ns:chris a ns:Woman .
ns:sofy a ns:Woman .
ns:chloe a ns:Woman .
ns:jean ns:isMarriedWith ns:chris .
ns:roger ns:isMarriedWith ns:chloe .
In your SPARQL query, it's not clear what f0
is, since it's not legal SPARQL syntax, but based on your description of the problem, you've got something like the following. I've changed to a construct
query so that we can look at the results of the query and see the triples that are constructed, which would be the same as the triples that get inserted. This just makes it easier to see what's happening.
prefix ns: <http://stackoverflow.com/q/20287293/1281433/>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <urn:ex:>
construct {
:f0 a ns:Family . # This can be written as
:f0 ns:contains ?p . # :f0 a ns:Family ; ns:contains ?p, ?q .
:f0 ns:contains ?q . #
}
where {
?p ns:isMarriedWith ?q .
}
Now, your problem is that when you run this query on that data, you get results like:
:f0 a ns:Family ;
ns:contains ns:chris , ns:jean , ns:chloe , ns:roger .
where there's one family that contains all four people, but you want a different family for each pair. The trick is to replace the constant :f0
with a blank node, which will be unique for each match in the query. You could do this just by changing :f0
to _:f0
:
_:f0 a ns:Family .
_:f0 ns:contains ?p .
_:f0 ns:contains ?q .
but I'd prefer to use a bit more of the syntactic sugar that we have available to us and just write:
[ a ns:Family ; ns:contains ?p, ?q ]
so that we have:
prefix ns: <http://stackoverflow.com/q/20287293/1281433/>
prefix owl: <http://www.w3.org/2002/07/owl#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
prefix : <urn:ex:>
construct {
_:f0 a ns:Family ; ns:contains ?p, ?q .
}
where {
?p ns:isMarriedWith ?q .
}
The results of this query contain two different families:
@prefix : <urn:ex:> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix ns: <http://stackoverflow.com/q/20287293/1281433/> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
[ a ns:Family ;
ns:contains ns:chris , ns:jean
] .
[ a ns:Family ;
ns:contains ns:chloe , ns:roger
] .
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:ns="http://stackoverflow.com/q/20287293/1281433/"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns="urn:ex:"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<ns:Family>
<ns:contains rdf:resource="http://stackoverflow.com/q/20287293/1281433/chris"/>
<ns:contains rdf:resource="http://stackoverflow.com/q/20287293/1281433/jean"/>
</ns:Family>
<ns:Family>
<ns:contains rdf:resource="http://stackoverflow.com/q/20287293/1281433/chloe"/>
<ns:contains rdf:resource="http://stackoverflow.com/q/20287293/1281433/roger"/>
</ns:Family>
</rdf:RDF>