【问题标题】:How to parameterize a SPARQL query in SWI Prolog?如何在 SWI Prolog 中参数化 SPARQL 查询?
【发布时间】:2025-12-16 22:45:01
【问题描述】:

我很难将以下 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.00 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.00 sec, 39,480 bytes
%     library(quintus) compiled into quintus 0.00 sec, 23,896 bytes
%    rewrite compiled into rewrite 0.01 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.01 sec, 244,240 bytes
% library(semweb/sparql_client) compiled into sparql_client 0.04 sec, 707,080 bytes
true.

我有这个查询,如您所见,它似乎运行良好:

?- sparql_query('select COUNT(*) where {?place a dbpedia-owl:Place ; rdfs:label "Pescara"@it.}', Row, [ host('dbpedia.org'), path('/sparql/')]).
Row = row(literal(type('http://www.w3.org/2001/XMLSchema#integer', '1'))).

我的问题是我希望这个查询是参数化的。在前面的示例中,我有一个 Pescara 值是固定的,应该是一个变量。我有类似的东西:

?- Place = 'Roma'

在查询中:

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

这似乎不起作用。

【问题讨论】:

    标签: prolog sparql swi-prolog semantic-web dbpedia


    【解决方案1】:

    您可以使用atom_concat/3atomic_list_concat/3

    :- val('select COUNT(*) where {?place a dbpedia-owl:Place ; rdfs:label $Place@it.}').
    
    12 ?- Z='rdfs:label $', val(X), atom_concat(A,B,X), atom_concat(Z,C,B), 
          atom_concat('Place',D,C), Place='"Roma"', 
          atomic_list_concat([A,Z,Place,D],R).
    .....
    Place = '"Roma"',
    R = 'select COUNT(*) where {?place a dbpedia-owl:Place ; rdfs:label $"Roma"@it.}' ;
    false.
    

    然后

    ?- sparql_query($R, Row, [ host('dbpedia.org'), path('/sparql/')]).
    

    或者,简单地说,

    makeQuery(Place, Query, Row) :-   %% e.g. Place = '"Rome"'
        atomic_list_concat( [ 'select COUNT(*) where {?place a dbpedia-owl:Place ;',
          ' rdfs:label $', Place, '@it.}'], Query),
        sparql_query(Query, Row, [ host('dbpedia.org'), path('/sparql/')] ).
    

    【讨论】:

    • tnx 这么多...实际上我需要一个生成此查询的谓词,例如 buildQuery(Place, Query) 其中 Place 是要插入查询字符串 Query 的变量,现在我正在尝试用你的例子自己做...但是如果对你来说不是问题并且可以给我看这个版本我会非常感谢你因为我赶紧把这个项目交给我的老师:-/
    • mmm makeQuery/3 谓词出错并告诉我:?- makeQuery("Roma", Query, Row)。错误:atomic_list_concat/2:类型错误:text' expected, found [82,111,109,97]
    • 不是"Roma"'"Roma"'。仔细查看我的答案中的代码。
    • 好吧,谢谢你,现在我将研究你的谓词......所以我必须将地点 vvaue 放入“地名”中?
    • ?- makeQuery('"Roma"', Query, Row).。像这样称呼它。