title: SPARQL query for individuals with same properties
body: <p>I'd like to identify all individuals, that have the same properties as some other individuals. Imagine having different shopping lists with different items on them one can either buy or rent (object properties). To make things more complex, I also want to pay an exact amount for the parking and travel a certain distance (data properties). At the same time, there exist different stores offering different items.
  Being a lazy person, I would like to identify the stores for each list, that offer all the items on the list.</p>
  
  <p>I believe this is a generalization of this <a href="https://stackoverflow.com/questions/27607609/sparql-query-find-objects-with-same-property-objects">question</a> but I somehow cannot wrap my head around how to do this.</p>
  
  <p>I created some sample individuals:</p>
  
  <pre><code>@prefix : &lt;http://www.shopping.org/model#&gt; .
  @prefix owl: &lt;http://www.w3.org/2002/07/owl#&gt; .
  @prefix rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt; .
  @prefix xml: &lt;http://www.w3.org/XML/1998/namespace&gt; .
  @prefix xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt; .
  @prefix rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt; .
  @base &lt;http://www.shopping.org/model&gt; .
  
  &lt;http://www.shopping.org/model&gt; rdf:type owl:Ontology .
  
  #    Object Properties
  :buy rdf:type owl:ObjectProperty .
  :rent rdf:type owl:ObjectProperty .
  
  #    Data properties
  :distance rdf:type owl:DatatypeProperty .
  :parking rdf:type owl:DatatypeProperty .
  
  #    Classes
  :Product rdf:type owl:Class .
  :ShoppingList rdf:type owl:Class .
  :Store rdf:type owl:Class .
  
  #    Individuals
  :Apples rdf:type owl:NamedIndividual ,
                   :Product .
  :Cereal rdf:type owl:NamedIndividual ,
                   :Product .
  :List1 rdf:type owl:NamedIndividual ,
                  :ShoppingList ;
         :buy :Apples ,
              :Milk ;
         :distance "9.0"^^xsd:float ;
         :parking "10.0"^^xsd:float .
  :List2 rdf:type owl:NamedIndividual ,
                  :ShoppingList ;
         :buy :Cereal ,
              :Milk ;
         :rent :TV ;
         :distance "5.0"^^xsd:float ;
         :parking "10.0"^^xsd:float .
  :Milk rdf:type owl:NamedIndividual ,
                 :Product .
  :Store1 rdf:type owl:NamedIndividual ,
                   :Store ;
          :buy :Apples ,
               :Cereal ,
               :Milk ,
               :TV ;
          :distance "9.0"^^xsd:float ;
          :parking "10.0"^^xsd:float .
  :Store2 rdf:type owl:NamedIndividual ,
                   :Store ;
          :buy :Cereal ,
               :Milk ;
          :rent :TV ;
          :distance "5.0"^^xsd:float ;
          :parking "10.0"^^xsd:float .
  :TV rdf:type owl:NamedIndividual ,
               :Product .
  
  #    General axioms
  
  [ rdf:type owl:AllDisjointClasses ;
    owl:members ( :Product
                  :ShoppingList
                  :Store
                )
  ] .
  </code></pre>
  
  <p>and also tried some first queries. This is the best I have:</p>
  
  <pre><code>PREFIX rdf: &lt;http://www.w3.org/1999/02/22-rdf-syntax-ns#&gt;
  PREFIX owl: &lt;http://www.w3.org/2002/07/owl#&gt;
  PREFIX rdfs: &lt;http://www.w3.org/2000/01/rdf-schema#&gt;
  PREFIX xsd: &lt;http://www.w3.org/2001/XMLSchema#&gt;
  PREFIX : &lt;http://www.shopping.org/model#&gt;
  SELECT DISTINCT ?list ?store ?prop 
  WHERE {
      ?list a :ShoppingList . 
      ?store a :Store . 
      ?list ?prop [] . 
  
      FILTER NOT EXISTS { 
          ?list ?prop ?value . 
          FILTER NOT EXISTS { 
              ?store ?prop ?value . 
          } 
      } 
  }
  ORDER BY ?list ?store 
  </code></pre>
  
  <p>However, this query returns all combinations of stores and lists, since every store charges 10.0f for parking.
  How can I filter only those stores, which meet <strong>all</strong> the requirements of a list?
  An additional assumption is, that there may exist other business models than <em>buy</em> and <em>rent</em>, as well as other criteria, i.e. data properties, which are of interest, too. This is why I do not want to specify these properties, but want to use variables instead.</p>
  
  <p><strong>This query did what I intended to do:</strong></p>
  
  <pre><code>PREFIXES [as above]
  PREFIX : &lt;http://www.shopping.org/model#&gt;
  SELECT DISTINCT ?list ?store 
      WHERE {
          ?list a :ShoppingList . 
          ?store a :Store . 
  
          FILTER NOT EXISTS { 
              ?compat a owl:DatatypeProperty 
              FILTER NOT EXISTS {
                  ?list ?compat ?value . 
                  ?store ?compat ?value . 
              }
          } 
  
          FILTER NOT EXISTS {
              ?subset a owl:ObjectProperty . 
              ?list ?subset ?value . 
              FILTER NOT EXISTS {
                  ?store ?subset ?value . 
              }
          }
      }
      ORDER BY ?list ?store
  </code></pre>
  
  <p>My mistake was actually just that I defined the <em>?prop</em> outside of the filters. This resulted in them being part of the solution, i.e. I was was unable to remove whole stores through the filter(s).</p>