Запросы rdflib SPARQL (включая подклассы) ведут себя не так, как ожидалось

Я только начал самостоятельно изучать RDF и библиотеку Python rdflib. Но я столкнулся с проблемой со следующим кодом. Я ожидал, что запросы вернут mark и nat в качестве Person и только natalie в качестве профессора. Я не вижу, где я ошибся. (Кстати, я знаю, что Профессор должен быть титулом, а не видом Человека, но я просто возился с банкоматом.) Любая помощь приветствуется. Спасибо.

рдфлиб 4, питон 2.7

>>> from rdflib import Graph, BNode, URIRef, Literal
INFO:rdflib:RDFLib Version: 4.2.
>>> from rdflib.namespace import RDF, RDFS, FOAF
>>> G = Graph()
>>> mark = BNode()
>>> nat = BNode()
>>> G.add((mark, RDF.type, FOAF.Person))
>>> G.add((mark, FOAF.firstName, Literal('mark')))
>>> G.add((URIRef('Professor'), RDF.type, RDFS.Class))
>>> G.add((URIRef('Professor'), RDFS.subClassOf, FOAF.Person))
>>> G.add((nat, RDF.type, URIRef('Professor')))
>>> G.add((nat, FOAF.firstName, Literal('natalie')))
>>> qres = G.query(
        """SELECT DISTINCT ?aname
           WHERE {
              ?a rdf:type foaf:Person .
              ?a foaf:firstName ?aname .
           }""", initNs = {"rdf": RDF,"foaf": FOAF})
>>> for row in qres:
    print "%s is a person" % row


mark is a person
>>> qres = G.query(
        """SELECT DISTINCT ?aname
           WHERE {
              ?a rdf:type ?prof .
              ?a foaf:firstName ?aname .
           }""", initNs = {"rdf": RDF,"foaf": FOAF, "prof": URIRef('Professor')})
>>> for row in qres:
    print "%s is a Prof" % row


natalie is a Prof
mark is a Prof
>>> 

person duncan smith    schedule 04.03.2016    source источник


Ответы (1)


Ваш запрос возвращает все типы, потому что переменная ?prof не привязана к значению.

Я думаю, вы хотите использовать initBindings kwarg для передачи URI для «Профессор» на ваш запрос. Таким образом, изменение вашего запроса на приведенный ниже извлекает только natalie.

qres = G.query( """SELECT DISTINCT ?aname WHERE { ?a rdf:type ?prof . ?a foaf:firstName ?aname . }""", initNs ={"rdf": RDF,"foaf": FOAF}, initBindings={"prof": URIRef('Professor')})

person Ted Lawless    schedule 12.03.2016
comment
Да, точно. Еще одна вещь, которую я не понял, это то, почему Натали не была признана личностью через отношения подкласса. Но я думаю, что ответ на этот вопрос заключается в том, что движок rdflib SPARQL просто не выполняет такого рода рассуждения. Ваше здоровье. - person duncan smith; 14.03.2016
comment
Могу ли я использовать initBindings для имен людей? - person msc87; 24.05.2016
comment
@ msc87 вы также можете использовать это для переменной ?aname в примере запроса. Вы захотите передать RDFlib Literal через привязки инициализации. Итак: initBindings={aname: Literal('natalie')}) - person Ted Lawless; 14.08.2016