AndreaNobili
AndreaNobili

Reputation: 42957

I can't call a parametric SPARQL query from an internal Prolog predicate

I am going crazy with the following problem:

I have a predicate makeQuery/3 that build a parametric SPARQL query to interrogate DBpedia, this one:

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/')] ).

As you can see it work well in the Prolog shell, in fact I can pass it a specific Place parameter and then it check if this is a place using DbPedia, this is the output in my Prolog shell:

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

As you can see the parameter have to be passed in this way: '"Roma"', I think that this means that Roma is an atom (or is it wrong interpretation?)

Ok, this work well infact my result (Row) find an occurrence so, for me, Roma is a place !!!

Now I am finding a big problem: This makeQuery/3 predicate have to be used by others predicates and not in the Prolog shell and I can't use it into an other predicate.

I have create the following execute/2 predicate that try to use it:

execute([FirstToken|Tail], TokenValue, OccurrencesPlaces) :-
    write(FirstToken),
    arg(2, FirstToken, TokenValue),
    atom_codes(Atom, TokenValue),
    makeQuery(Atom, Query, OccurrencesPlaces),
    write(OccurrencesPlaces).

This predicate take a list of tokens (for me a token is something like: t(1, [82, 111, 109, 97]) that have a t: functor, a identifier progressive number and the token content that is a list of ASCII rappresenting a String that is a word)

For example the previous token have 1 as identifier and its content rappresent the string Roma (that is a place so the query will found an occurrence)

Ok, so this predicate put in the TokenValue variable the string and execute the previous makeQuery/2 predicate passing to it my TokenValue value (in the previous example the string Roma)

Now in the prolog shell I do:

[debug]  ?- SystemTokenized = [t(1, [82, 111, 109, 97])].
SystemTokenized = [t(1, [82, 111, 109, 97])].

and now I call the execute/3 predicate passing to it SystemTokenized:

[debug]  ?- execute($SystemTokenized, TokenValue, OccurrencePlaces).
t(1,[82,111,109,97])
false.

As you can see seems don't work well because I am passing the string Roma to the query as parameter but I think that there is some problem because it is not an atom or something like this...

I am trying to solve from some hours but I can't find a solution

So my problem is: how can call the execute/3 predicate from another predicate that take the parameter like in the previous example?

Upvotes: 1

Views: 86

Answers (1)

CapelliC
CapelliC

Reputation: 60004

I do prefer format/2 when I have to - well - format complex strings. I tackled your problem with

execute([FirstToken|_Tail], TokenValue, OccurrencesPlaces) :-
    arg(2, FirstToken, TokenValue),
    format(atom(Place), '"~s"', [TokenValue]),
    makeQuery(Place, _Query, OccurrencesPlaces),
    write(OccurrencesPlaces).

What's suggested by Daniel should work as well.

Upvotes: 1

Related Questions