Implementing and extending SPARQL queries over DLVHEX Gennaro Frazzingaro Bachelor Thesis Presentation - October 5, 2007 From a work performed in Madrid, Spain Galway, Ireland Rende, Italy
How to solve problems arising Searching the Web Organize my journeys... Who can do this for me??
Making the Web more... Semantic Creating distributed knowledge: Shared distributed vocabularies (OWL, RDFS) Shared distributed information using these vocabularies How to store this information??
Making the Web more... Semantic Creating distributed knowledge: Shared distributed vocabularies (OWL, RDFS) Shared distributed information using these vocabularies How to store this information??
by the Resource Description Framework (RDF) = W3C standard from February 1999 Provides a framework to represent META-DATA about resources RDF model by TRIPLES subject - predicate - object
by the Resource Description Framework (RDF) = W3C standard from February 1999 Provides a framework to represent META-DATA about resources RDF model by TRIPLES subject - predicate - object
RDF representations (standard form) <rdf:rdf xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:contact="http://www.w3.org/2000/10/swap/pim/contact#"> <contact:person rdf:about="http://www.w3.org/people/em/contact#me"> <contact:fullname>eric Miller</contact:fullName> <contact:mailbox rdf:resource="mailto:em@w3.org"/> <contact:personaltitle>dr.</contact:personaltitle> </contact:person> </rdf:rdf> contact:fullname http://www.w3.org/people/em/contact#me contact:personaltitle RDF/XML or Graph Data Model Eric Miller contact:mailbox mailto:em@w3.org Dr. Namespace contact="http://www.w3.org/2000/10/swap/pim/contact#
RDF representations (more readable forms) subject - predicate - object @prefix contact: @prefix : <http://www.w3.org/2000/10/swap/pim/contact> <http://www.w3.org/people/em/contact> :me contact:fullname Eric Miller :me contact:mailbox <mailto:em@w3.org> :me contact:personaltitle Dr. ^^xsd:string Notation 3 N-Triples Turtle just the syntax changes, not the content!
How to retrieve this information (what we need) A cross language for handling RDF s semi-structured data A language which allow higherlevel application development A platform-independent query language and which can retrieve triples from different data sources SQL-like languages Retrieve data from Databases composed of TRIPLES Simple and familiar SELECT form XQuery-like languages Retrieve data from XML (RDF/XML) Platform independent
How to retrieve this information (what we need) A cross language for handling RDF s semi-structured data A language which allow higherlevel application development A platform-independent query language and which can retrieve triples from different data sources SQL-like languages Retrieve data from Databases composed of TRIPLES Simple and familiar SELECT form XQuery-like languages Retrieve data from XML (RDF/XML) Platform independent
How to retrieve this information (what we need) A cross language for handling RDF s semi-structured data A language which allow higherlevel application development A platform-independent query language and which can retrieve triples from different data sources SQL-like languages Retrieve data from Databases composed of TRIPLES Simple and familiar SELECT form XQuery-like languages Retrieve data from XML (RDF/XML) Platform independent
How to retrieve this information (what we need) A cross language for handling RDF s semi-structured data A language which allow higherlevel application development A platform-independent query language and which can retrieve triples from different data sources SQL-like languages Retrieve data from Databases composed of TRIPLES Simple and familiar SELECT form XQuery-like languages Retrieve data from XML (RDF/XML) Platform independent ENCODING DEPENDENT
SPARQL is the W3C answer PREFIX (optional) SELECT FROM prefixes list of variables (* for all in the WHERE clause) default graph FROM NAMED named graphs WHERE (conjunction of patterns) pattern(s) SQL-like SELECT query form FROM and FROM NAMED to specify the data-sets Use of TRIPLE patterns written in TURTLE
SPARQL is the W3C answer PREFIX (optional) SELECT FROM prefixes list of variables (* for all in the WHERE clause) default graph FROM NAMED named graphs WHERE (conjunction of patterns) pattern(s) SQL-like SELECT query form FROM and FROM NAMED to specify the data-sets Use of TRIPLE patterns written in TURTLE
SPARQL is the W3C answer PREFIX (optional) SELECT FROM prefixes list of variables (* for all in the WHERE clause) default graph FROM NAMED named graphs WHERE (conjunction of patterns) pattern(s) SQL-like SELECT query form FROM and FROM NAMED to specify the data-sets Use of TRIPLE patterns written in TURTLE
How to solve these queries? Current approach: ARQ on Jena Jena is a Java API for Semantic Web applications (which supports RDQL answering) ARQ is a module for executing SPARQL queries translating them into RDQL RDQL is query language for extracting information from RDF graphs Our approach: SPARQL on DLVHEX DLVHEX is a framework which extends DLV to calculate answer-sets for HEX-programs HEX-programs are an extension of ASP-programs allowing external and higher-order atoms DLVHEX-SPARQL translate SPARQL queries into rules to calculate solutions
How to solve these queries? Current approach: ARQ on Jena Jena is a Java API for Semantic Web applications (which supports RDQL answering) ARQ is a module for executing SPARQL queries translating them into RDQL RDQL is query language for extracting information from RDF graphs Our approach: SPARQL on DLVHEX DLVHEX is a framework which extends DLV to calculate answer-sets for HEX-programs HEX-programs are an extension of ASP-programs allowing external and higher-order atoms DLVHEX-SPARQL translate SPARQL queries into rules to calculate solutions
HEX-programs A rule r is of the form α1... αk β1,...,βn, not βn+1,...,not βm where m, k >= 0 α1...αk are atoms β1...βm are either atoms or external atoms An external atom is of the form &g[y1,...,yn](x1,...xm) where &g is the external predicate name Y1,...,Yn are the input list of term X1,...,Xm are the output list of term A HEX-program is a finite set P of r rules
HEX-programs A rule r is of the form α1... αk β1,...,βn, not βn+1,...,not βm where m, k >= 0 α1...αk are atoms β1...βm are either atoms or external atoms An external atom is of the form &g[y1,...,yn](x1,...xm) where &g is the external predicate name Y1,...,Yn are the input list of term X1,...,Xm are the output list of term A HEX-program is a finite set P of r rules
HEX-programs A rule r is of the form α1... αk β1,...,βn, not βn+1,...,not βm where m, k >= 0 α1...αk are atoms β1...βm are either atoms or external atoms An external atom is of the form &g[y1,...,yn](x1,...xm) where &g is the external predicate name Y1,...,Yn are the input list of term X1,...,Xm are the output list of term A HEX-program is a finite set P of r rules
HEX Semantics HBP is the Herbrand Base of such a program P, a set of all possible ground version of atoms and HEX-atoms occurring in P Given an interpretation I relative to P, I is a model of atom a in HBP, if a is in I. f&g is a boolean function assigning each tuple (I, y1..., yn, x1,..., xm) either 0 or 1 I is a model of a ground external atom a=&g[y1..., yn](x1,..., xm) if and only if f&g(i, y1..., yn, x1,..., xm) = 1
How does it work? What DLVHEX needs: Import data from RDF graphs Store it into predicates to allow its evaluation Restrict solutions to those that match with the pattern in the WHERE clause What DLVHEX provides: External atom (RDF-plugin) &rdf[uri](s,p,o) to read triples from URI Infer predicates from this atom triple(s,p,o) :- &rdf[uri](s,p,o) Rewriting of the input (SPARQL) in its equivalent program in rules (SPARQL-plugin)
How does it work? What DLVHEX needs: Import data from RDF graphs Store it into predicates to allow its evaluation Restrict solutions to those that match with the pattern in the WHERE clause What DLVHEX provides: External atom (RDF-plugin) &rdf[uri](s,p,o) to read triples from URI Infer predicates from this atom triple(s,p,o) :- &rdf[uri](s,p,o) Rewriting of the input (SPARQL) in its equivalent program in rules (SPARQL-plugin)
SPARQL translation Conjuction and disjunction PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT?N FROM <http://alice.org> WHERE {?X a foaf:person. { {?X foaf:name?n } UNION {?X foaf:nick?n } } } QUERY DATA @prefix foaf: <http://xmlns.com/foaf/0.1/>. @prefix alice: <http://www.alice.org#>. @prefix bob: <http://ex.org/bob#>. :bob a foaf:person; foaf:name "Bob"; foaf:nick "Bobby". alice:me foaf:knows _:c. _:c a foaf:person foaf:nick "Bob" ; foaf:nick "Bobby". RESULT?N "Bobby" "Bob" "Bobby" "Bob"
SPARQL translation Matching Alternatives PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT?N FROM <http://alice.org> WHERE {?X a foaf:person. { {?X foaf:name?n } UNION {?X foaf:nick?n } } } becomes answervars("n"). triple(s,p,o,default) :- &rdf["http://alice.org"](s,p,o). answer_1(x_x,default) :- triple(x_x,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:name",x_n,default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:nick",x_n,default). answer(x_x) :- answer_1(x_x,default),answer_2(x_n,x_x,default).
SPARQL translation Matching Alternatives PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT?N FROM <http://alice.org> WHERE {?X a foaf:person. { {?X foaf:name?n } UNION {?X foaf:nick?n } } } becomes answervars("n"). triple(s,p,o,default) :- &rdf["http://alice.org"](s,p,o). answer_1(x_x,default) :- triple(x_x,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:name",x_n,default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:nick",x_n,default). answer(x_x) :- answer_1(x_x,default),answer_2(x_n,x_x,default).
SPARQL translation Matching Alternatives PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT?N FROM <http://alice.org> WHERE {?X a foaf:person. { {?X foaf:name?n } UNION {?X foaf:nick?n } } } becomes answervars("n"). triple(s,p,o,default) :- &rdf["http://alice.org"](s,p,o). answer_1(x_x,default) :- triple(x_x,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:name",x_n,default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:nick",x_n,default). answer(x_x) :- answer_1(x_x,default),answer_2(x_n,x_x,default).
SPARQL translation Matching Alternatives PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT?N FROM <http://alice.org> WHERE {?X a foaf:person. { {?X foaf:name?n } UNION {?X foaf:nick?n } } } becomes answervars("n"). triple(s,p,o,default) :- &rdf["http://alice.org"](s,p,o). answer_1(x_x,default) :- triple(x_x,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:name",x_n,default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:nick",x_n,default). answer(x_x) :- answer_1(x_x,default),answer_2(x_n,x_x,default).
SPARQL translation Matching Alternatives PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT?N FROM <http://alice.org> WHERE {?X a foaf:person. { {?X foaf:name?n } UNION {?X foaf:nick?n } } } becomes answervars("n"). triple(s,p,o,default) :- &rdf["http://alice.org"](s,p,o). answer_1(x_x,default) :- triple(x_x,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:name",x_n,default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:nick",x_n,default). answer(x_x) :- answer_1(x_x,default),answer_2(x_n,x_x,default).
SPARQL translation Matching Alternatives PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT?N FROM <http://alice.org> WHERE {?X a foaf:person. { {?X foaf:name?n } UNION {?X foaf:nick?n } } } becomes answervars("n"). triple(s,p,o,default) :- &rdf["http://alice.org"](s,p,o). answer_1(x_x,default) :- triple(x_x,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:name",x_n,default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:nick",x_n,default). answer(x_x) :- answer_1(x_x,default),answer_2(x_n,x_x,default).
SPARQL translation Matching Alternatives answervars("x"). triple(s,p,o,default) :- &rdf["http://alice.org"](s,p,o). answer_1(x_x,default) :- triple(x_x,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:name",x_n,default). answer_2(x_n,x_x,default) :- triple(x_x,"foaf:nick",x_n,default). answer(x_x) :- answer_1(x_x,default),answer_2(x_n,x_x,default). whose solution is which corresponds to {answer("'bobby'"), answer("'bob'")} RESULT?N "Bobby" "Bob"
Drawbacks of current translation SPARQL on DLVHEX is not fully compliant with the specifications described by W3C: Just plain RDF literals are supported (not datatyped) Solution modifier not supported Every query is solved as a DISTINCT query (if a binding appears more than once in the solution, DLVHEX shows it just once, like in the example above) Evaluation of FILTERs is still sloppy and often not yet supported.
Specific starting point of my thesis Enable both DISTINCT and not DISTINCT queries (showing, in the latter case, the results the same times they are matched in the graph) Complete evaluation of FILTERs
How to distinguish bindings Inserting an identifier (constant) for each branch of UNION propagated upwards by a variable Always carrying over all the variables in all subpatterns to the answer predicate answervars("","n",""). triple(s,p,o,default) :- &rdf["http://alice.org"](s,p,o). answer_1(x_x,default) :- triple(x_x,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(union_2_1,x_n,x_x,default) :- triple(x_x,"foaf:name",x_n,default). answer_2(union_2_2,x_n,x_x,default) :- triple(x_x,"foaf:nick",x_n,default). answer(union_2,x_n,x_x) :- answer_1(x_x,default), answer_2(union_2,x_n,x_x,default).
How to distinguish bindings Inserting an identifier (constant) for each branch of UNION propagated upwards by a variable Always carrying over all the variables in all subpatterns to the answer predicate answervars("","n",""). triple(s,p,o,default) :- &rdf["http://alice.org"](s,p,o). answer_1(x_x,default) :- triple(x_x,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(union_2_1,x_n,x_x,default) :- triple(x_x,"foaf:name",x_n,default). answer_2(union_2_2,x_n,x_x,default) :- triple(x_x,"foaf:nick",x_n,default). answer(union_2,x_n,x_x) :- answer_1(x_x,default), answer_2(union_2,x_n,x_x,default).
Now the solution is... {answer(union_2_2,"'bobby'","#genid_<http://www.alice.org#>_c"), answer(union_2_2,"'bobby'","<http://ex.org/bob#>"), answer(union_2_2,"'bob'","#genid_<http://www.alice.org#>_c"), answer(union_2_1,"'bob'","<http://ex.org/bob#>")} which corresponds to real result RESULT?N "Bobby" "Bobby" "Bob" "Bob"
FILTERs evaluation What is a FILTER FILTERs restrict solutions to those for which the filter expression evaluates to TRUE Once values of a solution are substituted in the constraint expression, are discarded solution that either FILTER pattern produces FALSE ( F ) or produce an error ( E ). How we implemented it Use of external atoms for external computation of FILTER constraints We provide an external atom &eval which takes: The string following the FILTER keyword The value of the (possible) variable values to evaluate the constraint
FILTERs evaluation What is a FILTER FILTERs restrict solutions to those for which the filter expression evaluates to TRUE Once values of a solution are substituted in the constraint expression, are discarded solution that either FILTER pattern produces FALSE ( F ) or produce an error ( E ). How we implemented it Use of external atoms for external computation of FILTER constraints We provide an external atom &eval which takes: The string following the FILTER keyword The value of the (possible) variable values to evaluate the constraint
FILTERs evaluation What is a FILTER FILTERs restrict solutions to those for which the filter expression evaluates to TRUE Once values of a solution are substituted in the constraint expression, are discarded solution that either FILTER pattern produces FALSE ( F ) or produce an error ( E ). How we implemented it Use of external atoms for external computation of FILTER constraints We provide an external atom &eval which takes: The string following the FILTER keyword The value of the (possible) variable values to evaluate the constraint
FILTERs evaluation when we encounter for example In a nutshell WHERE... <patterns> FILTER <constraint>... we will use the external atom &eval["<constraint>",<variables value in the constraint>](x). where X could be "T", "F" or "E"
FILTERs evaluation PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT?name?mbox WHERE {?x foaf:name?name ; foaf:mbox?mbox. FILTER ( lang(?name) = "ES" && isiri(?mbox) ) } becomes answervars("mbox","name",""). answer(x_mbox,x_name,x_x) :- triple(x_x,"foaf:mbox",x_mbox,default), triple(x_x,"foaf:name",x_name,default), &eval["lang(?name) = \"ES\" && isiri(?mbox)",x_name,x_mbox]("t").
Particular case: FILTER + OPTIONAL (1) WHERE... <patterns> OPTIONAL <pattern>... Queries which contains OPTIONAL patterns do not reject solutions which has no binding for <pattern>. OPTIONAL patterns in SPARQL corresponds to the left join operator in Relational Algebra. Given the patterns Ω1 = <patterns> and Ω2 = <pattern> they could be transformed following the left join definition as follows Ω1 leftjoin Ω2 = (Ω1 join Ω2) U (Ω1 - Ω2)
Particular case: FILTER + OPTIONAL (2) OPTIONAL <pattern> FILTER <constraint> When a FILTER constraint appears in an OPTIONAL pattern there are 3 cases to consider: 1. there are bindings for <pattern> and <constraint> is true 2. there are bindings for <pattern>, but <constraint> is false or generate an error 3. there are no bindings for <pattern>
SPARQL translation Optional Patterns PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT * FROM <http://alice.org> WHERE { {?X1 a foaf:person. OPTIONAL {?X1 foaf:name?n. FILTER isliteral(?n) } } becomes answer_1(x_x1,default) :- triple(x_x1,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x1,default) :- triple(x_x1,"foaf:name",x_n,default). answer_bjoin_1(null,x_x1,default) :- answer_1(x_x1,default), not answer_2_prime(x_x1,default). answer_2_prime(x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default). answer_bjoin_1(x_n,x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default), &eval["isliteral(?n)",x_n]("t"). answer_bjoin_1(x_n,x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default), not &eval["isliteral(?n)",x_n]("t"). answer(x_n,x_x1) :- answer_bjoin_1(x_n,x_x1,default).
SPARQL translation Optional Patterns PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT * FROM <http://alice.org> WHERE { {?X1 a foaf:person. OPTIONAL {?X1 foaf:name?n. FILTER isliteral(?n) } } becomes answer_1(x_x1,default) :- triple(x_x1,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x1,default) :- triple(x_x1,"foaf:name",x_n,default). answer_bjoin_1(null,x_x1,default) :- answer_1(x_x1,default), not answer_2_prime(x_x1,default). answer_2_prime(x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default). answer_bjoin_1(x_n,x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default), &eval["isliteral(?n)",x_n]("t"). answer_bjoin_1(x_n,x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default), not &eval["isliteral(?n)",x_n]("t"). answer(x_n,x_x1) :- answer_bjoin_1(x_n,x_x1,default).
SPARQL translation Optional Patterns {?X1 a foaf:person. OPTIONAL {?X1 foaf:name?n. FILTER isliteral(?n) } } = Ω1 OPTIONAL Ω2 = (Ω1 join Ω2) U (Ω1 - Ω2) becomes FILTER is true generates an error answer_1(x_x1,default) :- triple(x_x1,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x1,default) :- triple(x_x1,"foaf:name",x_n,default). answer_bjoin_1(null,x_x1,default) :- answer_1(x_x1,default), not answer_2_prime(x_x1,default). answer_2_prime(x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default). answer_bjoin_1(x_n,x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default), &eval["isliteral(?n)",x_n]("t"). answer_bjoin_1(x_n,x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default), not &eval["isliteral(?n)",x_n]("t"). answer(x_n,x_x1) :- answer_bjoin_1(x_n,x_x1,default).
SPARQL translation Optional Patterns {?X1 a foaf:person. OPTIONAL {?X1 foaf:name?n. FILTER isliteral(?n) } } = Ω1 OPTIONAL Ω2 = (Ω1 join Ω2) U (Ω1 - Ω2) becomes FILTER is false or generates an error answer_1(x_x1,default) :- triple(x_x1,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x1,default) :- triple(x_x1,"foaf:name",x_n,default). answer_bjoin_1(null,x_x1,default) :- answer_1(x_x1,default), not answer_2_prime(x_x1,default). answer_2_prime(x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default). answer_bjoin_1(x_n,x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default), &eval["isliteral(?n)",x_n]("t"). answer_bjoin_1(x_n,x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default), not &eval["isliteral(?n)",x_n]("t"). answer(x_n,x_x1) :- answer_bjoin_1(x_n,x_x1,default).
SPARQL translation Optional Patterns Ω1 OPTIONAL Ω2 = (Ω1 join Ω2) U (Ω1 - Ω2) We need SAFETY! We need answer_2_prime to apply negation on answer_2 (Ω1 - Ω2) = Ω1 - (Ω1 Ω2) becomes answer_1(x_x1,default) :- triple(x_x1,"<http://www.w3.org/1999/02/22-rdf-syntax-ns#type>", "foaf:person",default). answer_2(x_n,x_x1,default) :- triple(x_x1,"foaf:name",x_n,default). answer_bjoin_1(null,x_x1,default) :- answer_1(x_x1,default), not answer_2_prime(x_x1,default). answer_2_prime(x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default). answer_bjoin_1(x_n,x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default), &eval["isliteral(?n)",x_n]("t"). answer_bjoin_1(x_n,x_x1,default) :- answer_1(x_x1,default), answer_2(x_n,x_x1,default), not &eval["isliteral(?n)",x_n]("t"). answer (X_N,X_X1) :- answer_bjoin_1(x_n,x_x1,default).
DLVHEX+SPARQL web service We provide also a web-service developed with Apache Axis, available at http://axel.deri.ie:8080/axis/services/sparqlevaluator?wsdl It evaluates queries using dlvhex-sparql and its RuleML output It transforms this output in the official SPARQL Query Result XML format
Thanks. Questions?