Странное поведение SPARQL с использованием переменных и IRI

Я столкнулся со странным поведением при использовании Аллегрографа 4.13

Это данные для тестового примера

prefix : <http://example.com/example#> 

INSERT DATA {
:A rdfs:label "A" .
:A :hasProp :Prop1 .
:Prop1 :Key "1" .
:Prop1 :Value "AA" .

:B :hasProp :Prop2 .
:Prop2 :Key "1" .
:Prop2 :Value "AA" .

:C :hasProp :Prop3 .
:C :hasProp :Prop4 .
:Prop3 :Key "1" .
:Prop3 :Value "AA" .

:Prop4 :Key "2" .
:Prop4 :Value "BB" .
}

Дано: A, мне нужно найти ресурсы с точно такими же свойствами. То есть я хочу найти: B, но не: C, потому что: C имеет на одно свойство больше (ключ «2» и значение «BB»)

См. Также этот вопрос Поиск людей в SPARQL на основе других отношений / Сравнить наборы

Следующий запрос, любезно предоставленный Джошуа Тейлор, напрямую использует ресурс (: A) и делает именно то, что я хочу:

prefix : <http://example.com/example#> 

select ?other ?k ?v {
   :A    :hasProp [ :Key ?k ; :Value ?v ] .
   ?other :hasProp [ :Key ?k ; :Value ?v ] .
   filter not exists { 
     { :A :hasProp [ :Key ?kk ; :Value ?vv ] .
       filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
       }
     }
     union
     {
      ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists { :A :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
   }
  }
 }

Отвечать:

 -------------------  
 |other|  k  | v  
 |A    | "1" | "AA"  
 |B    | "1" | "AA"  
 -------------------  

Во втором используется переменная? A, потому что мне нужно найти: Первое в соответствии с некоторыми критериями (rdfs: label в этом примере)

Запрос с использованием переменной? A:

 prefix : <http://example.com/example#> 

select ?other ?k ?v {
   ?a rdfs:label "A" .
   ?a    :hasProp [ :Key ?k ; :Value ?v ] .
   ?other :hasProp [ :Key ?k ; :Value ?v ] .
   filter not exists { 
     { ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
       filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
       }
     }
     union
     {
      ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists { ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
    }
   }
 }

возвращается

 -------------------  
 |other|  k  | v  
 |A    | "1" | "AA"  
 |B    | "1" | "AA"  
 |C    | "1" | "AA"  
 -------------------   

Этот запрос также возвращает: C, что, на мой взгляд, неверно.

Может ли кто-нибудь объяснить это поведение или проверить этот тестовый пример с другими тройными хранилищами / движками SPARQL?


Дополнительные тесты

По запросу в комментариях я добавил префикс для rdfs, а также заменил пустые узлы переменными. Похоже, это не имеет никакого эффекта.

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

select ?a ?pr1 ?pr2 ?other ?k ?v {
  ?a rdfs:label "A" .
  # bind (:A as ?a) .
  ?a    :hasProp ?pr1 .
  ?pr1 :Key ?k ; :Value ?v .
  ?other :hasProp ?pr2 .
  ?pr2 :Key ?k ; :Value ?v .

 filter not exists { 
   { ?a :hasProp ?pp1 .
     ?pp1 :Key ?kk ; :Value ?vv  .
  filter not exists { ?other :hasProp ?pp2 .
                     ?pp2 :Key ?kk ; :Value ?vv .
  }
}
union
{
 ?other :hasProp ?pp3 .
  ?pp3 :Key ?kk ; :Value ?vv .
 filter not exists { ?a :hasProp ?pp4 .
                    ?pp4 :Key ?kk ; :Value ?vv .
 }
 }
 }  
 }
a    pr1     pr2   other k       v  
A   Prop1   Prop1   A   "1"     "AA"  
A   Prop1   Prop2   B   "1"     "AA"  
A   Prop1   Prop3   C   "1"     "AA"  

Если я использую BIND (закомментированный) вместо строки с rdfs: label, он выглядит так же.


person Andrej    schedule 14.07.2014    source источник
comment
Отличная работа! Это намного понятнее и самодостаточнее!   -  person Joshua Taylor    schedule 15.07.2014
comment
Запросы, которые у вас здесь, выполняются как есть? То есть, Allegro автоматически вставляет определение для rdfs:?   -  person Joshua Taylor    schedule 15.07.2014
comment
Что произойдет, если вы замените пустые узлы в запросе некоторыми переменными? Например, если вы сделаете ?a rdfs:label "A". ?a :hasProp ?aprop . ?aprop :Key ?k ; ?Value ?v и аналогично с ?otherprop? Интересно, с какими ресурсами они сопоставляются.   -  person Joshua Taylor    schedule 15.07.2014
comment
Я добавил содержание вашего ответа на вопрос (ответ был удален, потому что это не ответ, но это была полезная информация). Если тебе это еще не надоело, можешь попробовать еще один тест? Что, если вместо filter not exists { {…} union {…} } использовать filter not exists {…} filter not exists {…}?   -  person Joshua Taylor    schedule 15.07.2014
comment
Я попробовал, но ничего не изменилось.   -  person Andrej    schedule 15.07.2014
comment
Вы добились каких-либо успехов в этом?   -  person Joshua Taylor    schedule 19.07.2014
comment
Я отправил отчет об ошибке, но пока не получил ответа   -  person Andrej    schedule 21.07.2014


Ответы (1)


Я думаю, что вы нашли ошибку в AllegroGraph. Кажется, что добавление ? A rdfs: label "A" должно ограничить значение ? A значением : A, и это поведение мы видим с Йеной.

Jena:       VERSION: 2.11.0
Jena:       BUILD_DATE: 2013-09-12T10:49:49+0100
ARQ:        VERSION: 2.11.0
ARQ:        BUILD_DATE: 2013-09-12T10:49:49+0100
RIOT:       VERSION: 2.11.0
RIOT:       BUILD_DATE: 2013-09-12T10:49:49+0100
prefix : <http://example.com/example#> 
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>

select ?other ?k ?v {
   ?a rdfs:label "A" .
   ?a    :hasProp [ :Key ?k ; :Value ?v ] .
   ?other :hasProp [ :Key ?k ; :Value ?v ] .
   filter not exists { 
     { ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
       filter not exists { ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
       }
     }
     union
     {
      ?other :hasProp [ :Key ?kk ; :Value ?vv ] .
      filter not exists { ?a :hasProp [ :Key ?kk ; :Value ?vv ] .
      }
   }
  }
 }
----------------------
| other | k   | v    |
======================
| :B    | "1" | "AA" |
| :A    | "1" | "AA" |
----------------------

Вероятно, имеет смысл придумать минимальный пример, воспроизводящий это поведение, и отправить отчет об ошибке.

person Joshua Taylor    schedule 14.07.2014