This tutorial builds a small assurance case for a kettle. You apply the rules of the GSN Community Standard to the case, validate the case, and ask questions about it. The output on this page comes from OntoGSN 1.3.0.

You need Python 3 and a copy of the OntoGSN repository. Run the commands from the root folder of the repository.

1. Set up

  1. Clone the repository.
  2. Install the Python packages.
git clone https://github.com/fortiss/OntoGSN.git
cd OntoGSN
pip install rdflib pyshacl

The ontology is in ontology/serializations/ontogsn.ttl. Its permanent IRI is https://w3id.org/OntoGSN/ontology. The front page also has RDF/XML, JSON-LD, and one file for each section of the standard.

If you prefer an editor, open ontogsn.ttl in Protégé. If you prefer a graph store, load it into a store such as GraphDB. The steps below use plain files and Python, so that you can follow them without a store.

2. Write the case

An assurance case is a set of individuals. The ontology is the vocabulary (the TBox). Your case is the data (the ABox). The repository has no case of yours, only examples.

Save this file as my-case.ttl:

@prefix ex:     <https://example.org/my-case#> .
@prefix gsn:    <https://w3id.org/OntoGSN/ontology#> .
@prefix rdfs:   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix schema: <http://schema.org/> .

ex:AC1 a gsn:AssuranceCase ;
    schema:identifier "AC1" ;
    gsn:statement "The kettle is acceptably safe to use at home." ;
    gsn:contains ex:Arg1 , ex:E1 .

ex:Arg1 a gsn:Argument ;
    schema:identifier "Arg1" ;
    gsn:contains ex:G1 , ex:S1 , ex:G2 , ex:G3 , ex:C1 , ex:Sn1 , ex:Sn2 .

ex:G1 a gsn:Goal ;
    schema:identifier "G1" ;
    gsn:statement "The kettle is acceptably safe to use at home." ;
    gsn:supportedBy ex:S1 ;
    gsn:inContextOf ex:C1 .

ex:C1 a gsn:Context ;
    schema:identifier "C1" ;
    gsn:statement "Home use as defined in the user manual." .

ex:S1 a gsn:Strategy ;
    schema:identifier "S1" ;
    gsn:statement "Argument over each identified hazard." ;
    gsn:supportedBy ex:G2 , ex:G3 .

ex:G2 a gsn:Goal ;
    schema:identifier "G2" ;
    gsn:statement "The kettle cannot boil dry." ;
    gsn:supportedBy ex:Sn1 .

ex:G3 a gsn:Goal ;
    schema:identifier "G3" ;
    gsn:statement "The kettle does not give an electric shock." ;
    gsn:supportedBy ex:Sn2 .

ex:Sn1 a gsn:Solution ;
    schema:identifier "Sn1" ;
    gsn:statement "Boil-dry test report." ;
    gsn:refersTo ex:E1 .

ex:Sn2 a gsn:Solution ;
    schema:identifier "Sn2" ;
    gsn:statement "Insulation test report." ;
    gsn:true false .

ex:E1 a gsn:Artefact ;
    schema:identifier "E1" ;
    rdfs:label "TEST-REPORT-017"@en .

The case uses these terms:

Term Meaning
gsn:Goal, gsn:Strategy, gsn:Solution, gsn:Context The GSN element types
schema:identifier The element identifier, for example “G1”
gsn:statement The text of the element
gsn:supportedBy The support link from a goal or strategy to the element below it
gsn:inContextOf The link from a goal or strategy to its context
gsn:refersTo The link from a solution to the artefact that is its evidence
gsn:true false The insulation test failed

3. Apply the rules

The ontology has 58 SWRL rules from the standard. Each rule is also a SPARQL update in ontology/queries/rules/, for stores with no reasoner. The script run_rules.py applies the updates until no rule adds a new fact.

python ontology/example/run_rules.py my-case.ttl --out my-case-materialised.ttl

The script reports which rules fired:

reached a fixpoint after 3 pass(es)

9 of 58 rules fired; 4,008 -> 4,058 triples
    S6  Goal Top Flag
   S11  Solution Propagation (False)
   ...

Rule S11 found that the failed solution Sn2 supports G3, so G3 is now gsn:true false. Rule S6 found that G2 and G3 have a parent, so they are not top goals.

In Protégé, a reasoner that supports SWRL, for example Pellet, applies the SWRL form of the same rules.

4. Validate the case

The SHACL shapes in ontology/shapes/ check the case against the standard. Run the validation on the output of step 3, because some shapes expect the facts that the rules add.

pyshacl -s ontology/shapes/ontogsn-shapes_0_full.ttl \
        -e ontology/serializations/ontogsn.ttl \
        -a -f human \
        my-case-materialised.ttl

The -e option adds the ontology to the data, so that the shapes see the class hierarchy. The -a option turns on the SPARQL-based constraints. The result has four warnings:

Element Problem Fix
Sn2 The solution points at no artefact Add gsn:refersTo to the insulation test report
G1 The goal has no parent, but it is not marked as the top goal Add gsn:top true to G1
G2, G3 The goals have no context Add gsn:inContextOf, or accept the warning

A warning is not a violation. To accept the warnings, add --allow-warnings. A violation always makes the result fail.

5. Ask questions

The folder ontology/queries/ has 43 stored SPARQL queries. Each query answers one question about a case. The questions are in the query catalogue. Parameters are in a VALUES block near the top of the query.

Save this script as query.py:

import sys, rdflib

g = rdflib.Graph()
for f in sys.argv[2:]:
    g.parse(f)
for row in g.query(open(sys.argv[1], encoding="utf-8").read()):
    print(*row)

Then run some queries:

python query.py ontology/queries/read_goal_support_tree.rq my-case-materialised.ttl
python query.py ontology/queries/read_element_status_flags.rq my-case-materialised.ttl
python query.py ontology/queries/read_solutions_without_artefact.rq my-case-materialised.ttl
Query Question Result for the kettle
read_goal_support_tree What is the whole argument below goal G1? S1, G2, G3, Sn1, Sn2, with their depth
read_element_status_flags What is the status of each element? G3 and Sn2 are false
read_solutions_without_artefact Which solutions cite no artefact? Sn2

In a graph store, paste the query into the SPARQL editor of the store. Load the ontology and the case into the same graph first, because some queries need the class hierarchy.

6. Connect the case to the system

A static case stops here. A dynamic case keeps up with the system that it argues about:

  1. Describe the system in its own ontology, for example the parts of a car.
  2. Link each claim to the system element that it is about, with a property of your own. gsn:refersTo is only for artefacts.
  3. Write queries that write test results and runtime data into the store as artefacts.
  4. Run the queries, then the rules, then the validation, in a scheduled job.

The Playground shows this with a car and its roof load. See also the OntoGSN Workbench.

More examples

File Contents
ontology/example/patterns/ An argument pattern for control design and effectiveness
ontology/example/example_case.ttl A test case that uses every section of the standard. Its last section has deliberate errors. Do not copy that section.

How the ontology is built

Every term of OntoGSN comes from the GSN Community Standard v3 (SCSC-141C). The download of the standard needs an SCSC login. The ontology covers the five sections of the standard: core GSN, and the argument pattern, modular, confidence and dialectic extensions.

The work had two parts, done in many cycles:

Part What it gives
Vocabulary Each sentence of the standard that names a concept became an OWL class or property
Rules Each sentence that sets a condition became a SWRL rule or an OWL axiom

The design record links each axiom to the passage of the standard behind it, and records the decision and the reason.

Artifact Format Folder
Ontology OWL 2, in Turtle, RDF/XML and JSON-LD ontology/serializations/
Rules SWRL in the ontology, and SPARQL 1.1 updates ontology/queries/rules/
Shapes SHACL ontology/shapes/
Stored queries SPARQL 1.1 ontology/queries/

The ontology imports no other ontology. It uses annotation terms from Dublin Core, Schema.org, SKOS, VANN and BIBO.