Qanary Explanation Service

Question Answering components following the Qanary methodology mostly create outputs (e.g., a query builder component typically generates RDF data or SPARQL queries, respectively ) and store them as new annotations to an RDF graph in the triplestore. To understand Qanary components it’s helpful to have knowledge about the data they generate while acknowledging that this is only a first step in explaining the component or even QA systems.

This webservice provides some functionalities to compute explanations for some Qanary components in triplestore graphs.

About the Annotation Types

Supported types

The explanation’s creation follows a rule-based approach, what means that each explanation for a component is created different depending on the annotationType of its written output.

Therefor not all Annotation types (=components) are supported yet. The supported ones are the following:

  1. AnnotationOfInstance

  2. AnnotationOfSpotInstance

  3. AnnotationOfAnswerSPARQL

  4. AnnotationOfAnswerJSON

  5. AnnotationOfRelation

  6. AnnotationOfQuestionTranslation

  7. AnnotationOfQuestionLanguage

You can check the output annotation type for existing components in the component’s README at https://github.com/WDAqua/Qanary-question-answering-component .

Adding new types

While the current version covers all - currently - existing Annotation types for the Qanary components you might want to add a new type and furthermore a new explanation as well.

To achieve this you might follow this straight-forward manual:

  1. Add a SPARQL query to the queries/queries_for_annotation_types folder

  2. Add a template for your potential explanation inside explanations/ - You may follow the naming convention for the existing ones, but it`s up to you

    1. The directory should contain four (4) files - a template for "de" and "en" as well as a prefix for "de" and "en". Please follow the naming conventions here.

    2. Inside the files you can declare two types of placeholders:

      1. these for definitely existing values with ${YOUR_VALUE}

      2. and conditional ones, i.e. &{conditional text ${VALUE}}& will be evaluated if the value for the inner placeholder exists, otherwise it`s replaced with a empty String

  3. Add the paths for your annotation type to the ExplanationService class

    1. firstly to the annotationsTypeAndQuery-Map

    2. secondly to the annotationTypeExplanationTemplate-Map

Editing existing types

  1. Simply edit the templates for the explanations inside the explanations/{desired_type}/.. folder

  2. take care for the defined test which have to be adjusted - src/test/resources/expected_list_explanations

Build and Run

Build

Preparations

You may change these settings to fit your requirements:

applications.properties
server.port = 4000
sparqlEndpoint = http://demos.swe.htwk-leipzig.de:40111/sparql

from scratch using Java

  • create a executable -jar-file like so:

    • mvn clean install

by using Docker

  1. locally:

    • build a Docker image with the existing Dockerfile by using the following command inside the projects folder

    • docker build . -t qanary-explanation-service

  2. from Dockerhub:

Running the application

using Java

  • start the built jar-file by executing java -jar PATH/TO/JAR/qanary-explanation-service.jar

    • the built jar is usually located inside the target-directory (of the projects directory)

using Docker

  1. locally built:

    • run the built image with docker run -p 12345:4000 qanary-explanation-service with parameters:

      • "p": is the optional port mapping if you wish to run the application on a different port on your machine, e.g. in this case the applications port (default: 4000) is mapped to port 12345

  2. from Dockerhub:

    • run the pulled image with docker run -p 12345:4000 qanary-explanation-service:latest with:

      • your previous selected tag (replace latest with your tag)

      • parameter "p": the optional port mapping if you wish to run the application on a different port on your machine, e.g. in this case the applications port (default: 4000) is mapped to port 12345

Functionalities

Currently, there are several endpoints with different tasks, as of the latest version these are:

/annotations/{graphURI}

Path variables:

  • required: graphURI::String

Returns:

  • a list of objects with all annotations (similar to /explanation but not as strict, see SPARQL query)

SPARQL query:

PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX oa: <http://www.w3.org/ns/openannotation/core/>
PREFIX qa: <http://www.wdaqua.eu/qa#>
SELECT *
FROM ?graphURI
WHERE {
    ?annotationId rdf:type ?type.
    ?annotationId oa:hasBody ?body.
    ?annotationId oa:hasTarget ?target.
    ?annotationId oa:annotatedBy $createdBy .
    ?annotationId oa:annotatedAt $createdAt .
}

/explanations/{graphURI}/{componentURI}

Path Variables:

  • required: graphURI::String

  • optional: componentURI::String

Returns:

  • with only the graphURI given: a formatted explanation for the QA-process on the graphURI depending on the following Accept header:

    • none: Turtle

    • application/ld+json: JSONLD

    • application/rdf+xml: RDFXML

    • text/turtle: Turtle

    • other: no response, NOT_ACCEPTABLE (406)

  • with graphURI and componentURI given: a formatted explanation for the specific component within the QA-process of the given graphURI depending on the following Accept-Header:

    • none: Turtle

    • application/ld+json: JSONLD

    • application/rdf+xml: RDFXML

    • text/turtle: Turtle

    • other: no response, NOT_ACCEPTABLE (406)

provides two endpoints to either request an explanation for a QA process with a given graphURI or a specific explanation for one componentURI (added as another path variable). In both cases, the explanation format depends on the Accept-Header: RDF/XML, JSONLD, or RDF Turtle. If there`s no Accept header provided in the request, then the format will be RDF Turtle.

Example Return for QA system:
@prefix explanations:
<urn:qanary:explanations#> .
@prefix rdf:
    <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:
        <http://www.w3.org/2000/01/rdf-schema#> .


            <http://demos.swe.htwk-leipzig.de:40111/question/stored-question__text_078f518e-4b51-4679-a800-1bb3c7fe91b7>
                <urn:qanary:wasProcessedBy>  [ rdf:type  rdf:Seq ;
                                       rdf:_1    [ rdf:type  rdf:Seq ;
                                                   rdf:_1    [ rdf:type       rdf:Statement ;
                                                               rdf:object     "The component urn:qanary:NED-DBpediaSpotlight has added the following properties to the graph:  Time: '2023-08-29T06:40:48.375' | Confidence: 93.4757 % | Content: http://dbpedia.org/resource/String_theory Time: '2023-08-29T06:40:48.595' | Confidence: 97.7748 % | Content: http://dbpedia.org/resource/Real_number Time: '2023-08-29T06:40:48.806' | Confidence: 99.9954 % | Content: http://dbpedia.org/resource/Batman"@en ;
                                                               rdf:predicate  explanations:hasExplanationForCreatedData ;
                                                               rdf:subject
                    <urn:qanary:NED-DBpediaSpotlight>
                                                             ] ;
                                                   rdf:_2    [ rdf:type       rdf:Statement ;
                                                               rdf:object     "Die Komponente urn:qanary:NED-DBpediaSpotlight hat folgende Ergebnisse berechnet und dem Graphen hinzugefügt:  Zeitpunkt: '2023-08-29T06:40:48.375' | Konfidenz: 93.4757 % | Inhalt: http://dbpedia.org/resource/String_theory Zeitpunkt: '2023-08-29T06:40:48.595' | Konfidenz: 97.7748 % | Inhalt: http://dbpedia.org/resource/Real_number Zeitpunkt: '2023-08-29T06:40:48.806' | Konfidenz: 99.9954 % | Inhalt: http://dbpedia.org/resource/Batman"@de ;
                                                               rdf:predicate  explanations:hasExplanationForCreatedData ;
                                                               rdf:subject
                        <urn:qanary:NED-DBpediaSpotlight>
                                                             ] ;
                                                   rdf:_3    [ rdf:type       rdf:Statement ;
                                                               rdf:object     explanations:hasExplanation ;
                                                               rdf:predicate  rdfs:subPropertyOf ;
                                                               rdf:subject    explanations:hasExplanationForCreatedData
                                                             ]
                                                 ] ;
                                       rdf:_2    [ rdf:type  rdf:Seq ;
                                                   rdf:_1    [ rdf:type       rdf:Statement ;
                                                               rdf:object     explanations:hasExplanation ;
                                                               rdf:predicate  rdfs:subPropertyOf ;
                                                               rdf:subject    explanations:hasExplanationForCreatedData
                                                             ] ;
                                                   rdf:_2    [ rdf:type       rdf:Statement ;
                                                               rdf:object     "The component urn:qanary:QB-SimpleRealNameOfSuperHero has added the following properties to the graph:  Time: '2023-08-29T06:40:49.691' | Confidence: 100 % | Content: PREFIX  rdfs:
                            <http://www.w3.org/2000/01/rdf-schema#> PREFIX  dct:
                                <http://purl.org/dc/terms/> PREFIX  dbr:
                                <http://dbpedia.org/resource/> PREFIX  rdf:
                                <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX  foaf:
                                    <http://xmlns.com/foaf/0.1/>  SELECT  * WHERE   { ?resource  foaf:name  ?answer ;               rdfs:label  ?label     FILTER ( lang(?label) = \"en\" )     ?resource  dct:subject  dbr:Category:Superheroes_with_alter_egos     FILTER ( ! strstarts(lcase(?label), lcase(?answer)) )     VALUES ?resource { dbr:Batman }   } ORDER BY ?resource "@en ;
                                                               rdf:predicate  explanations:hasExplanationForCreatedData ;
                                                               rdf:subject
                                    <urn:qanary:QB-SimpleRealNameOfSuperHero>
                                                             ] ;
                                                   rdf:_3    [ rdf:type       rdf:Statement ;
                                                               rdf:object     "Die Komponente urn:qanary:QB-SimpleRealNameOfSuperHero hat folgende Ergebnisse berechnet und dem Graphen hinzugefügt:  Zeitpunkt: '2023-08-29T06:40:49.691' | Konfidenz: 100 % | Inhalt: PREFIX  rdfs:
                                        <http://www.w3.org/2000/01/rdf-schema#> PREFIX  dct:
                                            <http://purl.org/dc/terms/> PREFIX  dbr:
                                            <http://dbpedia.org/resource/> PREFIX  rdf:
                                            <http://www.w3.org/1999/02/22-rdf-syntax-ns#> PREFIX  foaf:
                                                <http://xmlns.com/foaf/0.1/>  SELECT  * WHERE   { ?resource  foaf:name  ?answer ;               rdfs:label  ?label     FILTER ( lang(?label) = \"en\" )     ?resource  dct:subject  dbr:Category:Superheroes_with_alter_egos     FILTER ( ! strstarts(lcase(?label), lcase(?answer)) )     VALUES ?resource { dbr:Batman }   } ORDER BY ?resource "@de ;
                                                               rdf:predicate  explanations:hasExplanationForCreatedData ;
                                                               rdf:subject
                                                <urn:qanary:QB-SimpleRealNameOfSuperHero>
                                                             ]
                                                 ]
                                     ] ;

                                                    <urn:qanary:wasProcessedInGraph>
                                                        <urn:graph:ad7a72a6-9036-4219-803e-d6dab991a28e> .
Example Return for specific componentURI:
@prefix explanations:
<urn:qanary:explanations#> .
@prefix rdfs:
    <http://www.w3.org/2000/01/rdf-schema#> .


        <urn:qanary:NED-DBpediaSpotlight>
        explanations:hasExplanationForCreatedData
                "The component urn:qanary:NED-DBpediaSpotlight has added the following properties to the graph:  Time: '2023-08-29T06:40:48.375' | Confidence: 93.4757 % | Content: http://dbpedia.org/resource/String_theory Time: '2023-08-29T06:40:48.595' | Confidence: 97.7748 % | Content: http://dbpedia.org/resource/Real_number Time: '2023-08-29T06:40:48.806' | Confidence: 99.9954 % | Content: http://dbpedia.org/resource/Batman"@en , "Die Komponente urn:qanary:NED-DBpediaSpotlight hat folgende Ergebnisse berechnet und dem Graphen hinzugefügt:  Zeitpunkt: '2023-08-29T06:40:48.375' | Konfidenz: 93.4757 % | Inhalt: http://dbpedia.org/resource/String_theory Zeitpunkt: '2023-08-29T06:40:48.595' | Konfidenz: 97.7748 % | Inhalt: http://dbpedia.org/resource/Real_number Zeitpunkt: '2023-08-29T06:40:48.806' | Konfidenz: 99.9954 % | Inhalt: http://dbpedia.org/resource/Batman"@de .

explanations:hasExplanationForCreatedData
        rdfs:subPropertyOf  explanations:hasExplanation .

Example

  1. Firstly we start a QA process with the Question "What is the real name of Superman?" and the components

    • NED-DBpediaSpotlight and

    • QB-SimpleRealNameOfSuperhero

  2. As a result, we should get a graphURI

    • in our example, let’s assume it is urn:graph:c55b5c85-6a89-4dd6-83bc-3b6d1ea953ea

  3. Now, we can use this graphURI or a different one (maybe one where we don’t know the acting components) for some requests to the webservice.

Result
[
    {
        "source": null,
        "start": null,
        "end": null,
        "body": {
            "type": "uri",
            "value": "http://dbpedia.org/resource/String_theory"
        },
        "type": {
            "type": "uri",
            "value": "http://www.wdaqua.eu/qa#AnnotationOfInstance"
        },
        "createdBy": {
            "type": "uri",
            "value": "urn:qanary:NED-DBpediaSpotlight"
        },
        "createdAt": {
            "value": "2023-08-24T14:31:10.906821",
            "type": "typed-literal",
            "datatype": "http://www.w3.org/2001/XMLSchema#dateTime"
        },
        "score": {
            "value": 0.9835348759090881,
            "type": "typed-literal",
            "datatype": "http://www.w3.org/2001/XMLSchema#decimal"
        },
        "entity": null,
        "target": {
            "type": "bnode",
            "value": "b0"
        },
        "annotationID": {
            "type": "uri",
            "value": "0.6851129018166628"
        },
        "annotationId": {
            "type": "uri",
            "value": "0.6851129018166628"
        }
    },
    {
        "source": null,
        "start": null,
        "end": null,
        "body": {
            "type": "uri",
            "value": "http://dbpedia.org/resource/Stephen_Hawking"
        },
        "type": {
            "type": "uri",
            "value": "http://www.wdaqua.eu/qa#AnnotationOfInstance"
        },
        "createdBy": {
            "type": "uri",
            "value": "urn:qanary:NED-DBpediaSpotlight"
        },
        "createdAt": {
            "value": "2023-08-24T14:31:10.919961",
            "type": "typed-literal",
            "datatype": "http://www.w3.org/2001/XMLSchema#dateTime"
        },
        "score": {
            "value": 0.9999999999941593,
            "type": "typed-literal",
            "datatype": "http://www.w3.org/2001/XMLSchema#decimal"
        },
        "entity": null,
        "target": {
            "type": "bnode",
            "value": "b1"
        },
        "annotationID": {
            "type": "uri",
            "value": "0.5337743826833434"
        },
        "annotationId": {
            "type": "uri",
            "value": "0.5337743826833434"
        }
    }
]

SpringDocs & SwaggerUI

API Docs are available at http://localhost:40190/api-docs