Создание параметризованного запроса SPARQL с использованием предиката append / 3

Относится к моему предыдущему сообщению: Как параметризовать запрос SPARQL в SWI Prolog?

В качестве упражнения я пытался реализовать предикат, который создает и выполняет запрос SPARQL, используя только предикат append / 3 (в отличие от решения, предложенного в моем старом сообщении), но он не работает. Что ж.

Это мой предикат:

buildQuery(Place, Query, Row) :- 

    % Q1 = 'select COUNT(*) where {?place a dbpedia-owl:Place ; rdfs:label "
    Q1 = [39, 115, 101, 108, 101, 99, 116, 32, 67, 79, 85, 78, 84, 40, 42, 41, 32, 119, 104, 101, 114, 101, 32, 123, 63, 112, 108, 97, 99, 
              101, 32, 97, 32, 100, 98, 112, 101, 100, 105, 97, 45, 111, 119, 108, 58, 80, 108, 97, 99, 101, 32, 59, 32, 114, 100, 102, 115, 58,
              108, 97, 98, 101, 108, 32, 34],
    append(Q1, Place, Q2),
    %End = @en }}'
    End = [34, 64, 105, 116, 32, 125, 39],

    append(Q2, End, Query),
    sparql_query(Query, Row, [ host('dbpedia.org'), path('/sparql/')] ).

Поскольку я обнаружил некоторую проблему при вставке символа " непосредственно в строку (то есть, вставив " в ""; возможно, я могу поставить " в "", который представляет начало и конец строки, экранируя его каким-либо образом. Я не знаю.)

Я пытаюсь построить свой запрос следующим образом: в Прологе строка представляет собой список символов ASCII, поэтому я создал строку \ список Q1, представляющую строку: 'select COUNT(*) where {?place a dbpedia-owl:Place ; rdfs:label ", которая является первой часть моего запроса. Затем я добавляю к нему значение переменной Place, которая будет строкой, представляющей место (например, "Roma"), создавая новую строку Q2. Затем я добавляю строку End к Q2, создавая окончательный запрос Query, где end - последняя часть моего запроса: % End = @en}} ' Наконец, я выполняю запрос SPARQL с помощью sparql_query / 3, встроенного в предикат, передавая ему свой последний запрос Query и два других необходимых параметра (как в хорошем рабочем примере из предыдущего поста).

Проблема в том, что вроде не работает. В оболочке Prolog я выполняю следующую команду:

  1. Чтобы загрузить необходимую библиотеку SPARQL:

    ?- use_module(library(semweb/sparql_client)).
    %   library(uri) compiled into uri 0.02 sec, 290,256 bytes
    %   library(readutil) compiled into read_util 0.00 sec, 17,464 bytes
    %   library(socket) compiled into socket 0.00 sec, 11,936 bytes
    %   library(option) compiled into swi_option 0.00 sec, 14,288 bytes
    %   library(base64) compiled into base64 0.01 sec, 17,912 bytes
    %   library(debug) compiled into prolog_debug 0.00 sec, 21,864 bytes
    %  library(http/http_open) compiled into http_open 0.03 sec, 438,368 bytes
    %   library(sgml) compiled into sgml 0.01 sec, 39,480 bytes
    %     library(quintus) compiled into quintus 0.00 sec, 23,896 bytes
    %    rewrite compiled into rewrite 0.00 sec, 35,336 bytes
    %    library(record) compiled into record 0.00 sec, 31,368 bytes
    %   rdf_parser compiled into rdf_parser 0.01 sec, 132,840 bytes
    %    library(gensym) compiled into gensym 0.00 sec, 4,792 bytes
    %   rdf_triple compiled into rdf_triple 0.00 sec, 39,672 bytes
    %  library(rdf) compiled into rdf 0.02 sec, 244,240 bytes
    % library(semweb/sparql_client) compiled into sparql_client 0.06 sec, 707,080 bytes
    true.
    
  2. Выполняю свой предикат:

    ?- buildQuery("Roma", Query, Row), write(Query).
    ERROR: uri:uri_query_components/2: Type error: `atomic' expected, found `[39,115,101,108,101,99,116,32,67,79,85,78,84,40,42,41,32,119,104,101,114,101,32,123,63,112,108,97,99,101,32,97,32,100,98,112,101,100,105,97,45,111,119,108,58,80,108,97,99,101,32,59,32,114,100,102,115,58,108,97,98,101,108,32,34,82,111,109,97,34,64,105,116,32,125,39]'
    ^  Exception: (12) ignore(http_open:parts_search([protocol(http), host('dbpedia.org'), port(80), path('/sparql/'), search([...])], _G1079)) ? creep
    

Как видите, возникает ошибка. Странно то, что мое значение Query (я напечатал его с помощью write / 1) кажется нормальным. Фактически, если я переведу список ASCII в символы, его значение будет:

'выберите COUNT (*) где {? разместить dbpedia-owl: Place; rdfs: label "Roma" @it} '

Это мой исходный запрос (поэтому кажется, что строка запроса будет правильно построена), но похоже, что проблема в другом параметре sparql_query / 3, и это странно, потому что оно было скопировано из предыдущее решение, которое отлично работает. Почему? Что мне не хватает?


person AndreaNobili    schedule 30.05.2013    source источник
comment
вы должны использовать End = [34, 64, 105, 116, 32, 125, 125]. В итоге у вас есть два }}, а не один. А 39 - это код для одинарной кавычки, "\'". Это не часть текста, это разделитель вокруг имени атома. Аналогично, Q1 должен начинаться с Q1 = [115, ... (код для "s"). Но вместо того, чтобы записывать коды, вы можете просто написать Q1 = "select COUNT(*) where .... ", Prolog считывает строки в двойных кавычках как списки кодов символов. Значит, sparql_query/3 работает, я не знаю, чего он ожидает. В предыдущем вопросе вы показали, что он используется с атомами. используйте atom_codes/2 для преобразования строкового ‹-› атома.   -  person Will Ness    schedule 30.05.2013


Ответы (1)


Вы получаете сообщение об ошибке, потому что аргумент запроса (первый) sparql_query / 3 является атомом. Итак, самый простой способ построить запрос -

atomic_list_concat([ 'select COUNT(*) where {?place a dbpedia-owl:Place ; rdfs:label "',
                     Place,
                     '"@en }'
                   ], Query),
sparql_query(Query, Row, [ host('dbpedia.org'), path('/sparql/')] ).

Обратите внимание, что это работает только до тех пор, пока Place des не содержит двойных кавычек или другого специального символа, как определено синтаксисом строки SPARQL.

person Jan Wielemaker    schedule 13.07.2014