0

In a previous question

SPARQL if an instance has a property, others must as well

I asked that if i have an instance that has a value for a specific predicate, then the all the output of my sparql query must have the same value for the same predicate.

I got an excellent answer there,

now I am trying to expand it because i've found a new scenario,

the new scenario is:

if an instance has a value to a specific predicate then all the output items must either have the same value for the same predicate or if they have another value, these two values must be from the same class

I extended that sparql query to the following:

    PREFIX : <http://example.org/rs#>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ?item ?predicate ?similarity where 
{
  values ?x {:instance1}
  ?x ?predicate ?value.
  ?item ?predicate ?value.
  ?predicate :hasSimilarityValue ?similarity.
  filter (?x != ?item)
  filter not exists {
    ?x ?p ?v1.
    ?v1 a   ?class.
    ?p  rdfs:subPropertyOf  :isCriticalPredicate.
    filter not exists {
        ?item ?p ?v2.
        ?p rdfs:subPropertyOf :isCriticalPredicate.
        ?v2 a   ?class.
        ?class  rdfs:subClassOf :ImportantClass
    }
  }
}

and here is my data:

  @prefix : <http://example.org/rs#>
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

:instance1  :p1 :value1.
:instance2  :p1 :value2.
:p1 :hasSimilarityValue 0.5.
:value1 a   :class1.
:value2 a   :class1.
:class1 rdfs:subClassOf :ImportantClass.
:p1 rdfs:subPropertyOf  :isCriticalPredicate.

but the result is always empty i don't know why.

note1

by specific predicate, i mean the predicate that are rdfs:subClassOf :isCriticalPredicate

by specific class, I mean that class that are rdfs:subClassOf :ImportantClass

Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
Ania David
  • 1,168
  • 1
  • 15
  • 36
  • Be careful with `:isCriticalPredicate.` That `.` at the end can be significant, since things like `:foo.bar` are legal. Make sure you have space between `:isCriticalPredicate` and `.`. – Joshua Taylor Mar 07 '16 at 13:42
  • *"by specific class, I mean that class that are rdfs:subClassOf :ImportantClass"* You don't mention a "specific class" anywhere earlier; you say that *"if they have another value, these two values must be from the same class"* Which do you actually want? They must be values from the same class, or they must both be values from ImportantClass? – Joshua Taylor Mar 07 '16 at 13:47
  • 1
    Your query starts with: `?x ?predicate ?value. ` ?item ?predicate ?value.`. In your same data, instance1 and instance2 don't have any values in common, so this part of the query never matches. There aren't any results to get. – Joshua Taylor Mar 07 '16 at 13:59

1 Answers1

2

The Immediate Problem: There's No Matching Data!

As written, this is a pretty simple issue: there's actually no data that matches the query you've written. As such, I don't think the data and query really reproduce the problem that you're describing. You query begins with

  values ?x {:instance1}
  ?x ?predicate ?value.
  ?item ?predicate ?value.
  filter (?x != ?item)

Your data has:

:instance1  :p1 :value1.
:instance2  :p1 :value2.

There are no possible values for ?instance. The only candidate would be :instance2, but it doesn't have any values in common with :instance1, so there's no candidate for ?value.

The Query You Want

Now, even though the question as written doesn't really have the issue that you're describing, I think I see what you're asking about. When you're trying to create minimal data for your debugging process, you should try to include all the relevant cases. In this case, you'd want to have at least an instance that has the same value for a critical predicate, and an instance that has a different value for a critical predicate but where both values are important. Here's some data:

@prefix : <urn:ex:>

:instance1 :p :v1 .
:instance1 :q :v2 .

:instance2 :p :v1 . 
:instance2 :q :v2 .  #-- same value for :q

:instance3 :p :v1 .
:instance3 :q :v3 .  #-- different, but important, value for :q

:instance4 :p :v1 .
:instance4 :q :v4 .  #-- different, non-important, value for :q

:q a :CriticalPredicate .

:v2 a :ImportantValue .
:v3 a :ImportantValue .

Given the query that you're already working with, I think this one will be relatively clear. It's not much different from what you've already got.

prefix : <urn:ex:>

select distinct ?item where  {
  values ?x { :instance1 }
  ?x    ?predicate ?value .
  ?item ?predicate ?value .
  filter (?x != ?item)

  #-- Exclude any results where
  #-- ?x has a value ?v1 for a
  #-- critical predicate ?p...
  filter not exists {
    ?x ?p ?v1 .
    ?p a :CriticalPredicate .

    #-- ...unless either ?item has
    #-- the same value ?v1 for the
    #-- predicate ?p, or ?item has
    #-- another value ?v2 and both
    #-- ?v1 and ?v2 are
    #-- :ImportantValues.
    filter not exists {
      { ?item ?p ?v1 }
      union
      { ?item ?p ?v2 .
        :ImportantValue ^a ?v1, ?v2 . }
    }
  }
}
--------------
| item       |
==============
| :instance2 |
| :instance3 |
--------------
Joshua Taylor
  • 84,998
  • 9
  • 154
  • 353
  • hello, thanks for the whole answer, i noticed that i did mistake in the providing data, i forgot to correct it on the question sorry. I am trying to understand the query, kindly what did you mean the `^a`, this is the first time i see this. – Ania David Mar 07 '16 at 14:55
  • @Ania it's just a backwards property path. In sparql and turtle you can use "a" instead of rdf:type. "X ^p Y, Z." Is just shorthand for "Y rdf:type X. Z rdf:type X." Saves a bit of typing. – Joshua Taylor Mar 07 '16 at 14:58