# hasValue reasoning in AllegroGraph 3.3

# Table of Contents

## Introduction

## How to use it from Java:

## How to use it from the http-client interface

## How to use it from Lisp: a tutorial

### Deriving default values from type information

### Deriving types from value information

## Introduction

We added an extension to the AllegroGraph RDFS++ reasoner so that we now also can reason over hasValue restrictions in equivalent classes or subclasses.

For example, here is an owl class definition for AtlantisMission, defined as a SpaceMission where the 'shuttleUsed' property has the value 'Atlantis'.

    <owl:Class rdf:ID="AtlantisMission">
        <rdfs:subClassOf
            rdf:resource="http://www.w3.org/2002/07/owl#Thing"/>
        <rdfs:label
            rdf:datatype="http://www.w3.org/2001/XMLSchema#string">
            Atlantis mission
        </rdfs:label>
        <owl:equivalentClass>
            <owl:Class>
                <owl:intersectionOf rdf:parseType="Collection">
                <rdf:Description rdf:ID="SpaceMission"/>
                <owl:Restriction>
                    <owl:onProperty rdf:resource="#shuttleUsed"/>
                    <owl:hasValue rdf:resource="#Atlantis"/>
                </owl:Restriction>
                </owl:intersectionOf>
            </owl:Class>
        </owl:equivalentClass>
    </owl:Class>

We can make two types of inferences from this definition.

1. We can derive the default value for 'shuttleUsed' when we have an Instance of an AtlantisMission. So say we have the above definition in an owl file that we loaded, then if we add the following triple to the triple-store

       (add-triple
        !m:Mission4 !rdf:type !m:AtlantisMission)

we can derive that the `shuttleUsed` property must be `Atlantis` with the following query.

    (select (?val)
      (q !m:Mission3 !m:shuttleUsed ?val))

2. In reverse: we can also derive the type of an instance to be an `AtlantisMission` if we added the following instance properties to a triple-store

       (add-triple
         !m:Mission5 !m:shuttleUsed !m:Atlantis)
       (add-triple
         !m:Mission5 !rdf:type !m:SpaceMission)

then the following query would derive that `?x` is an `AtlantisMission`.

    (select (?x)
      (q !m:Mission5 !rdf:type ?x))

hasValue reasoning is not enabled by default. The tutorial below will show how to turn this on.

## How to use it from Java:

Please read the tutorial below to get a better understanding of how things are supposed to work with the hasValue restrictions. The one thing that is important for Java is that you add the hasValue reasoner after you opened a triple-store.. You do this by calling the method `enableHasValueReasoning()` from the AllegroGraphConnection class.

## How to use it from the http-client interface

Not implemented yet.

## How to use it from Lisp: a tutorial

In principle the following code will all run. Just evaluate every expression from top to bottom and you will see the results.

    ; load agraph into lisp
    (require :agraph)

    ; go into the triple-store-user package
    (in-package :triple-store-user)

    ;; make it easier to type URIs
    (enable-!-reader)

The following will define the function to load the files `SpaceMissions2.ntriples` into the triple-store. This file is included in the distribution. It will help you understanding of the contents of this file to inspect it in TopBraid Composer.

    (defun read-sm ()
      (create-triple-store  "test11" :directory "/tmp/"
                :if-exists :supersede
                :expected-unique-resources 200000)
      (load-ntriples "sys:agraph;tutorial-files;SpaceMissions2.ntriples")
      (index-all-triples))

    (time (read-sm))                  ; do the actual read

We are lazy and don't want to type long namespaces:

    (register-namespace
      "m" "http://www.topbraid.org/spacemissions.owl#")

    ;; lets look at the triples..
    (print-triples *db* :limit nil :format :terse)

To use hasValue reasoning, we must first apply-rdfs++-reasoner and then use has-value-reasoning-enabled:

    (apply-rdfs++-reasoner)

    (setf (has-value-reasoning-enabled *db*) t)

### Deriving default values from type information

1. First we demonstrate how we to derive default values from type information

       (add-triple
         !m:Mission1 !rdf:type !m:SpaceMissionIn2000)
       (add-triple
         !m:Mission1 !m:added-by !m:Jans)

       (select (?x ?y)
         (q !m:Mission1 !m:startYear ?x)
         (q- !m:Mission1 !m:added-by ?y))

and some more examples:

    (add-triple
       !m:Mission3 !rdf:type !m:DiscoveryMission)
    (add-triple
       !m:Mission4 !rdf:type !m:AtlantisMission)

    (select (?val)
      (q !m:Mission3 !m:shuttleUsed ?val))

    (select (?val)
      (q !m:Mission4 !m:shuttleUsed ?val))

    (select ()
      (q !m:Mission4 !m:shuttleUsed !m:Atlantis)
      (write 'SUCCESS))

### Deriving types from value information

1. Second, we demo how we can derive types from values. We add the `shuttleUsed` property to `Mission5` and then we can automatically derive that `Mission5` is an `AtlantisMission`.

       (add-triple
         !m:Mission5 !m:shuttleUsed !m:Atlantis)

Now this `select` query returns two results:

    (select (?x)
      (q !m:Mission5 !rdf:type ?x))

    (("http://www.topbraid.org/spacemissions.owl#SpaceMission")
     ("http://www.topbraid.org/spacemissions.owl#AtlantisMission"))

The first result is due to the fact that the `rdfs:range` of the property `shuttleUsed` is 'SpaceMission'. So by adding the fact `shuttleUsed` to `Mission5` the RDFS++ range reasoning will derive that `Mission5` is a `SpaceMission`.

Then the `hasValue` reasoning module uses the fact that `Misison5` is a `SpaceMission` and the `shuttleUsed` is `Atlantis` to derive that `Mission5` is an `AtlantisMission`.

The following queries are also interesting. The first select will only return `Mission4` because we use `q-` and `q-` looks only at the ground triples. It returns `Mission4` because we added that triple above:

    (select (?x)
      (q- ?x !rdf:type !m:AtlantisMission))
    -> (("http://www.topbraid.org/spacemissions.owl#Mission4"))

The following query returns `Mission4` and also `Mission5` because of `hasValue` reasoning. (Note how we use `q` here to use the reasoner)

    (select (?x)
      (q ?x !rdf:type !m:AtlantisMission))
    ->
    (("http://www.topbraid.org/spacemissions.owl#Mission4")
     ("http://www.topbraid.org/spacemissions.owl#Mission5"))

Now we can add some more triples:

    (add-triple !m:Mission6 !m:shuttleUsed !m:Columbia)
    (add-triple !m:Mission6 !rdf:type !m:SpaceMission)

    (select (?x)
      (q !m:Mission6 !rdf:type ?x))

    (select (?x)
      (q ?x !rdf:type !m:DiscoveryMission))

    (select ()
      (q !m:Mission6 !rdf:type !m:DiscoveryMission)
      (lisp (print 'SUCCESS)))

And finally we show that we can do quite complex `hasValue` restrictions. Please look in TopBraidComposer or any other ontology browser how a `MilitarySpaceMission` is defined by multiple `hasValue` restrictions.

We add some values and everything should work.

    (add-triple !m:Mission7 !rdf:type !m:SpaceMission)
    (add-triple !m:Mission7 !m:hasMissionType !m:SpecialMissionType)
    (add-triple !m:Mission7 !m:hasMissionType !m:MilitaryMissionType)

    (select (?x ?y)
      (q !m:Mission7 ?x ?y))

    (select (?type)
      (q !m:Mission7 !rdf:type ?type))

    (select (?x)
      (q ?x !rdf:type !m:MilitarySpaceMission))