3. Getting Started

This page will guide you through running the RDFox® executable for the first time. It is organised into one section of common setup steps, followed by three equivalent sections demonstrating how to access RDFox’s querying and reasoning functionality through different interfaces (GUI, CLI and REST API), and finally a section of suggestions for how to learn more.

If you are looking to get started with the Java, or the experimental C or C++ APIs to RDFox, see instead the appropriate demo program included with each RDFox release.

3.1. Setup

Before you begin, make sure that you have downloaded the latest RDFox release for your system from www.rdfox.com/downloads and unzipped it. This will produce a new directory containing the RDFox executable (named RDFox on Linux and macOS, and RDFox.exe on Windows) and some other files. The following instructions refer to this directory as <working_directory>.

You will also need to ensure that RDFox can find a valid license key. The quickest way to do this is to add a copy of your license key file directly to <working_directory> (see Section 2.4.1.3 for other ways). If you do not have a license key file, you can request one at https://www.rdfox.com/tryrdfoxforfree.

The following small RDF graph in Turtle format will be used in the instructions below.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
@prefix : <https://rdfox.com/getting-started/> .

:peter :forename "Peter" ;
    a :Person ;
    :marriedTo :lois ;
    :gender "male" .

:lois :forename "Lois" ;
    a :Person ;
    :gender "female" .

:meg :forename "Meg" ;
    a :Person ;
    :hasParent :lois, :peter ;
    :gender "female" .

:chris :forename "Chris" ;
    a :Person ;
    :hasParent :peter ;
    :gender "male" .

:stewie :forename "Stewie" ;
    a :Person ;
    :hasParent :lois ;
    :gender "male" .

:brian :forename "Brian" . # Brian is a dog

Additionally, the following Datalog file will be used to demonstrate RDFox’s reasoning capabilities.

1
2
@prefix : <https://rdfox.com/getting-started/> .
[?p, :hasChild, ?c] :- [?c, :hasParent, ?p] .

Download data.ttl and hasChild.dlog into <working_directory>.

Next, open a terminal, change directory to <working_directory>, and then start RDFox as follows:

./RDFox sandbox
RDFox.exe sandbox

You should be presented with a command prompt indicating that you have an instance of the RDFox shell awaiting input. If not, you may find this video demonstrating how to start the executable on Windows and macOS, helpful. Otherwise, run the following command to prepare for the main tutorial:

endpoint start

This starts RDFox’s endpoint which serves the REST API, including a SPARQL over HTTP endpoint, and RDFox’s graphical web console.

You are now ready to proceed to the tutorial. There are three versions of the tutorial. Each follows the same workflow using a different RDFox interface. To complete the tutorial using the web console (GUI) jump to Section 3.2. To complete the tutorial using the RDFox shell (CLI), jump to Section 3.3. To complete the tutorial using REST (API) jump to Section 3.4.

3.2. Tutorial (Web Console version)

Ensure all steps from the Setup chapter have been completed and then load the web console by pointing your browser to http://localhost:12110/console/.

3.2.1. Creating a Data Store

All facts and rules in RDFox live inside a data store. Initially no data stores exist so we must create one before we can load any triples. To create a data store, click CreateDataStoreLanding in the welcome dialog to display the data store creation dialog. Enter family as the name and click CreateDataStore.

3.2.2. Importing Data

On successfully creating the data store, the console displays an option to import data into the data store. Click ImportContent to display the “Add content” dialog. Drag the data.ttl file you downloaded earlier onto the dialog. The dialog should update to show the pending import. Toggle the “Update prefixes” switch to “on” to also load the prefixes stored within data.ttl. Prefixes are used to abbreviate IRIs (internationalized URIs) so that they are easier to type in queries and other commands. To assist in setup, RDFox adds eight default prefixes to every new datastore (see Section 4.1.5). Click AddContent to confirm no further data files are to be added for now, in order to proceed with the import.

A status report of the number of facts read (21) and added (21) to the data store is displayed. Dismiss the report by clicking OK.

3.2.3. Running Queries

You are now ready to run your first query!

The newly created data store is automatically selected and so the SPARQL query editor is enabled. SPARQL is the primary query language recognized by RDFox.

Run the default query, which returns all of the triples in the store, by clicking Run. You should see that 21 answers were retrieved from the server and presented in a table below the editor.

To demonstrate a simple conjunction, print each person’s forename by replacing the default query with the query below and clicking Run again.

SELECT ?p ?n
WHERE {
    ?p a :Person ;
        :forename ?n
}

Note that :brian is not returned as there is no triple to say that it is of type :Person as required by the first part of the WHERE clause.

3.2.4. Inserting Data Using SPARQL

It is also possible to modify the contents of the data store using SPARQL updates. For example, make the :marriedTo relationship symmetric by running:

INSERT { ?x :marriedTo ?y }
WHERE  { ?y :marriedTo ?x }

This adds one new triple to the data store reflecting the fact that Lois is married to Peter, which was derived from the fact that Peter is married to Lois. Rerunning the first SELECT query should now return 22 triples. You can use the back button in the browser to return to the original query.

3.2.5. Adding Rules

Reasoning is the ability to calculate the logical consequences of applying a set of rules to a set of facts. To illustrate how this can be useful, consider a query to find a particular person’s children. The above data has the inverse information — i.e. only :hasParent relationships — so querying for :hasChild, though more natural for this use case, will return no results. We could remodel the data but this could make the phrasing of any queries about parents less natural. We could add all the :hasChild relationships as new facts in the Turtle file but the dataset would then have a bunch of redundancy and we would need to make sure that we always add both relationships together when we add new people to the dataset.

With reasoning we can have the best of both worlds. Keeping the original dataset, we add a rule to state that if ?c has a parent ?p then ?p has a child ?c. RDFox can then determine all of the :hasChild relationships itself — including for any new families that we add later on.

RDFox uses the Datalog language for expressing rules. The rule described above is captured in the Datalog file hasChild.dlog that you downloaded to <working_directory> earlier. Import it by clicking on the AddContentHeader button in the header. In the “Add content” dialog that opens, click ChooseFile, navigate to <working_directory>, select hasChild.dlog, click to confirm and then click AddContent.

Importing this file will cause RDFox to run its reasoning algorithms, adding the triples that result from applying the loaded rules to the loaded facts to the data store as additional facts. Facts loaded explicitly from data are referred to as explicit whereas those derived through reasoning are referred to as derived.

To check that we now have some derived triples, run the following query which looks for any triple that uses the :hasChild predicate we introduced in the Datalog rule:

SELECT ?p ?c WHERE { ?p :hasChild ?c }

Four results are returned, all of which were added by reasoning.

3.2.6. Deleting Facts

If a fact or rule that was used in the derivation of a derived triple is removed from a data store, RDFox will also remove the derived triple. To check that this is the case, delete the triple that says :stewie has :lois as a parent by running:

DELETE DATA { :stewie :hasParent :lois }

and then re-query the triples using the :hasChild property with:

SELECT ?p ?c WHERE { ?p :hasChild ?c }

Observe that the answer :lois :stewie ., which was derived from the combination of the rule we added and the fact we just deleted, no longer appears.

3.2.7. Exploring a Data Store

In addition to the SPARQL runner, the web console provides a way to explore the facts in a data store visually. Click the Explore icon to the right of :peter where it appears in the results table to switch to begin an exploration.

Initially, a single purple rectangle is displayed representing the node :peter. The dot icon in the upper right of the purple peter node indicates that there are links present in the data store that are not being visualized. Right-click the node to display a context menu of the connections between :peter and other entities in this data store.

Select :gender "male" from “Outbound edges” and :lois :marriedTo from “Inbound edges” as seen on the menu and click “Update”. The link to the literal "male" is displayed, as is the link from :lois to :peter.

You have now completed the tutorial for the web console. Enter quit into the RDFox shell to shut the process down then, if you would like to repeat the tutorial using a different interface (CLI or REST API), repeat the setup steps and then navigate to the appropriate section. Alternatively, see Section 3.5 for some suggested next steps.

3.3. Tutorial (Shell version)

Ensure all steps from the Setup chapter have been completed before proceeding.

3.3.1. Creating a Data Store

All facts and rules in RDFox live inside a data store. Initially no data stores exist so we must create one before we can load any triples. To create a data store, use the dstore command as follows:

dstore create family

The above command initializes our family data store. To ensure that subsequent shell commands address our new data store, we use the active command to tell the shell to connect to the family data store when running commands that address a data store:

active family

3.3.2. Importing Data

Import the data.ttl file you downloaded to <working_directory> earlier with:

import +p data.ttl

Using the +p option ensures the prefixes stored within the data.ttl file are also imported. Prefixes are used to abbreviate IRIs (internationalized URIs) so that they are easier to type in queries and other commands. To assist in setup, RDFox adds eight default prefixes to every new datastore (see Section 4.1.5).

This command should report the time taken by the import and that 21 data items were processed and updated.

3.3.3. Running Queries

By default, RDFox does not specify where query answers must be sent. To instruct RDFox to print answers to the terminal, run the following command:

set output out

You are now ready to run your first query!

The primary query language recognized by RDFox is SPARQL. SPARQL queries can be typed or pasted directly into the shell.

Copy and paste the following SPARQL into the shell and hit enter to print all of the triples in the store:

SELECT ?S ?P ?O WHERE { ?S ?P ?O }

You should see a few lines beginning @prefix followed by a blank line and then the original 21 triples (facts) from data.ttl. After the triples, a summary of the number of answers returned and the time taken for the query is printed.

To demonstrate a simple conjunction, print each person’s forename by running the following query:

SELECT ?p ?n WHERE { ?p a :Person . ?p :forename ?n }

Note that :brian is not returned as there is no triple to say that it is of type :Person as required by the first part of the where clause.

3.3.4. Inserting Data Using SPARQL

It is also possible to modify the contents of the data store using SPARQL updates. For example, make the :marriedTo relationship symmetric by running:

INSERT { ?x :marriedTo ?y } \
WHERE  { ?y :marriedTo ?x }

This adds one new triple to the data store reflecting the fact that Lois is married to Peter, which was derived from the fact that Peter is married to Lois. Rerunning the first SELECT query should now return 22 triples. You can use the up arrow key to step back through your command history to find the original query.

3.3.5. Adding Rules

Reasoning is the ability to calculate the logical consequences of applying a set of rules to a set of facts. To illustrate how this can be useful, consider a query to find a particular person’s children. The above data has the opposite information — i.e. only :hasParent relationships — so querying for :hasChild, though more natural for this use case, will turn up no results. We could remodel the data but this could make the phrasing of any queries about parents less natural. We could add all the :hasChild relationships as new facts in the Turtle file but the dataset would then have a bunch of redundancy and we would need to make sure that we always add both relationships together when we add new people to the dataset.

With reasoning we can have the best of both worlds. Keeping the original dataset, we add a rule to state that if ?c has a parent ?p then ?p has a child ?c. RDFox can then determine all of the :hasChild relationships itself — including for any new families that we add later on.

RDFox uses the Datalog language for expressing rules. The rule described above is captured in the Datalog file hasChild.dlog that you downloaded to <working_directory> earlier. Import it with:

import hasChild.dlog

Importing this file will cause RDFox to run its reasoning algorithms, adding the triples that result from applying the loaded rules to the loaded facts to the data store as additional facts. Facts loaded explicitly from data are referred to as explicit whereas those derived through reasoning are referred to as derived.

To check that we now have some derived triples, run the following query which looks for any triple that uses the :hasChild predicate we introduced in the Datalog rule:

SELECT ?p ?c WHERE { ?p :hasChild ?c }

Four results are returned, all of which were added by reasoning.

3.3.6. Deleting Facts

If a fact or rule that was used in the derivation of a derived triple is removed from a data store, RDFox will also remove the derived triple. To check that this is the case, delete the triple that says :stewie has :lois as a parent by running:

DELETE DATA { :stewie :hasParent :lois }

and then requery the triples using the :hasChild property with:

SELECT ?p ?c WHERE { ?p :hasChild ?c }

Observe that the answer :lois :stewie ., which was derived from the combination of the rule we added and the fact we just deleted, no longer appears.

3.3.7. Stopping and Restarting RDFox

Shut down RDFox by typing the quit command. Since RDFox is an in-memory database, and because we started the process using the sandbox command which disables any form of persistence, the contents of the data store will be dropped when the process exits. While experimenting with RDFox, it may therefore be useful to write the commands to initialize the data store and load data into a script which can be passed to RDFox at startup. The following script repeats the whole of this tutorial. Save it to a new file <working_directory>/start.rdfox and then run it with ./RDFox sandbox . start (on Linux or Mac) or RDFox.exe sandbox . start (on Windows).

endpoint start
dstore create family
active family
import +p data.ttl
set output out
SELECT ?S ?P ?O WHERE { ?S ?P ?O }
SELECT ?p ?n WHERE { ?p rdf:type :Person . ?p :forename ?n }
INSERT { ?x :marriedTo ?y } WHERE { ?y :marriedTo ?x }
import hasChild.dlog
SELECT ?p ?c WHERE { ?p :hasChild ?c }
DELETE DATA { :stewie :hasParent :lois }
SELECT ?p ?c WHERE { ?p :hasChild ?c }

For alternative ways of starting RDFox which do not disable persistence, see Section 18.

You have now completed the tutorial with the RDFox shell. Enter quit to shut the process down again then, if you would like to repeat the tutorial using a different interface (GUI or REST API), repeat the setup steps and then navigate to the appropriate section.

3.4. Tutorial (REST version)

Ensure all steps from the Setup chapter have been completed before proceeding.

The steps in this section use the cURL tool which is normally installed on MacOS, Linux and modern versions of Windows. You will need to open a new shell to run the cURL commands in addition to the shell where RDFox is running. Inside the new shell, change directory to <working_directory> so that the relative paths in the examples correctly locate the files you downloaded in the setup steps.

At the end of this section, we give an example of achieving the same results using Python.

3.4.1. Creating a Data Store

All facts and rules in RDFox live inside a data store. Initially no data stores exist so we must create one before we can load any triples. To create a data store, issue a POST request to path datastores/<data-store-name> such as:

curl -i -X POST localhost:12110/datastores/family

Note we run cURL with the -i option to include the response headers in the output which means the output will be similar to:

HTTP/1.1 201 Created
Date: Wed, 13 Jul 2022 15:39:06 GMT
Server: RDFox Endpoint
ETag: "09649913528177635553-1"
Location: /datastores/family
Content-Length: 0

3.4.2. Importing Data

Import the data.ttl file you downloaded to <working_directory> earlier, into the data store created above by issuing a PATCH request to path datastores/family/content path:

curl -i -X PATCH "localhost:12110/datastores/family/content?operation=add-content-update-prefixes" -H "Content-Type:" -T data.ttl

This sends the content of the file to RDFox and reports success with:

HTTP/1.1 200 OK
Date: Wed, 13 Jul 2022 15:40:02 GMT
Server: RDFox Endpoint
ETag: "09649913528177635553-2"
Content-Type: text/plain; charset=UTF-8
Transfer-Encoding: chunked

prefix: : = https://rdfox.com/getting-started/
information: #aborted = false
information: #errors = 0
information: #warnings = 0
information: #processed-facts = 21
information: #changed-facts = 21
information: #processed-rules = 0
information: #changed-rules = 0
information: #processed-axioms = 0
information: #changed-axioms = 0

Note the use of -H "Content-Type:" in the cURL command. By default, cURL will set the content type to application/x-www-form-urlencoded which is a not a supported RDFox Content-Type. Using -H "Content-Type:" instructs cURL not to set the Content-Type and allows RDFox to automatically detect that we have data in Turtle format. Alternatively, we could explicitly set the type using -H "Content-Type: text/turtle". For the different formats supported by RDFox for encoding data store content, see Section 8.1.

Including operation=add-content-update-prefixes ensures the prefixes stored within the data.ttl file are also imported. Prefixes are used to abbreviate IRIs (internationalized URIs) so that they are easier to type in queries and other commands. To assist in setup, RDFox adds eight default prefixes to every new datastore (see Section 4.1.5).

3.4.3. Running Queries

You are now ready to run your first query!

The primary query language recognized by RDFox is SPARQL. RDFox exposes a fully compliant SPARQL-over-HTTP endpoint at path /datastores/<data-store-name>/sparql. To run a query we send a POST request to this path and set the query parameter to a SPARQL query.

Run the following cURL command to retrieve all of the triples in the store:

curl -i -X POST localhost:12110/datastores/family/sparql \
     -H "Accept: application/x.sparql-results+turtle-abbrev" \
     -d "query=SELECT ?S ?P ?O WHERE { ?S ?P ?O }"

After the HTTP response headers you should see a few lines beginning @prefix followed by a blank line and then the original 21 triples (facts) from data.ttl in the proprietary format application/x.sparql-results+turtle-abbrev.

To demonstrate a simple conjunction, print each person’s forename by running the following cURL command:

curl -i -X POST localhost:12110/datastores/family/sparql \
   -H "Accept: application/x.sparql-results+turtle-abbrev" \
   -d "query=SELECT ?p ?n WHERE { ?p a :Person . ?p :forename ?n }"

Note that :brian is not returned as there is no triple to say that it is of type :Person as required by the first part of the where clause.

3.4.4. Inserting Data Using SPARQL

It is also possible to modify the contents of the data store using SPARQL updates. To run a SPARQL update via REST, we must use the update parameter rather than the query parameter. For example, make the :marriedTo relationship symmetric by running:

curl -i -X POST localhost:12110/datastores/family/sparql \
   -d "update=INSERT { ?x :marriedTo ?y } WHERE { ?y :marriedTo ?x }"

this returns the no content (204) status code to indicate success:

HTTP/1.1 204 No Content
Date: Wed, 13 Jul 2022 16:53:28 GMT
Server: RDFox Endpoint
ETag: "09649913528177635553-3"

3.4.5. Adding Rules

Reasoning is the ability to calculate the logical consequences of applying a set of rules to a set of facts. To illustrate how this can be useful, consider a query to find a particular person’s children. The above data has the opposite information — i.e. only :hasParent relationships — so querying for :hasChild, though more natural for this use case, will turn up no results. We could remodel the data but this could make the phrasing of any queries about parents less natural. We could add all the :hasChild relationships as new facts in the Turtle file but the dataset would then have a bunch of redundancy and we would need to make sure that we always add both relationships together when we add new people to the dataset.

With reasoning we can have the best of both worlds. Keeping the original dataset, we add a rule to state that if ?c has a parent ?p then ?p has a child ?c. RDFox can then determine all of the :hasChild relationships itself — including for any new families that we add later on.

RDFox uses the Datalog language for expressing rules. The rule described above is captured in the Datalog file hasChild.dlog that you downloaded to <working_directory> earlier. Import it with:

curl -i -X POST localhost:12110/datastores/family/content \
     -H "Content-Type: application/x.datalog" \
     -T hasChild.dlog

If successful, the 200 OK response code should be returned.

Importing this file will cause RDFox to run its reasoning algorithms, adding the triples that result from applying the loaded rules to the loaded facts to the data store as additional facts. Facts loaded explicitly from data are referred to as explicit whereas those derived through reasoning are referred to as derived.

To check that we now have some derived triples, run the following query which looks for any triple that uses the :hasChild predicate we introduced in the Datalog rule:

curl -i -X POST localhost:12110/datastores/family/sparql \
   -H "Accept: application/x.sparql-results+turtle-abbrev" \
   -d "query=SELECT ?p ?c WHERE { ?p :hasChild ?c }"

Four results are returned, all of which were added by reasoning.

3.4.6. Deleting Facts

If a fact or rule that was used in the derivation of a derived triple is removed from a data store, RDFox will also remove the derived triple. To check that this is the case, delete the triple that says :stewie has :lois as a parent by running:

curl -i -X POST localhost:12110/datastores/family/sparql \
   -d "update=DELETE DATA { :stewie :hasParent :lois }"

and then requery the triples using the :hasChild property with:

curl -i -X POST localhost:12110/datastores/family/sparql \
   -H "Accept: application/x.sparql-results+turtle-abbrev" \
   -d "query=SELECT ?p ?c WHERE { ?p :hasChild ?c }"

Observe that the answer :lois :stewie ., which was derived from the combination of the rule we added and the fact we just deleted, no longer appears.

3.4.7. Python example

The following Python script uses the requests module to reproduce the same steps as used in the cURL examples presented previous.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import requests

# helper function to raise exception if the REST endpoint returns an
# unexpected status code
def assert_response_ok(response, message):
    if not response.ok:
        raise Exception(
            message + "\nStatus received={}\n{}".format(response.status_code, response.text))

rdfox_server = "http://localhost:12110"

# Create the data store
response = requests.post(
    rdfox_server + "/datastores/family")
assert_response_ok(response, "Failed to create datastore.")

# Add facts
turtle_data = """
@prefix : <https://rdfox.com/getting-started/> .

:peter :forename "Peter" ;
    a :Person ;
    :marriedTo :lois ;
    :gender "male" .

:lois :forename "Lois" ;
    a :Person ;
    :gender "female" .

:meg :forename "Meg" ;
    a :Person ;
    :hasParent :lois, :peter ;
    :gender "female" .

:chris :forename "Chris" ;
    a :Person ;
    :hasParent :peter ;
    :gender "male" .

:stewie :forename "Stewie" ;
    a :Person ;
    :hasParent :lois ;
    :gender "male" .

:brian :forename "Brian" . # Brian is a dog
"""


payload = {'operation': 'add-content-update-prefixes'}
response = requests.patch(
    rdfox_server + "/datastores/family/content", params=payload, data=turtle_data)
assert_response_ok(response, "Failed to add facts to data store.")

# Issue select query
sparql_text = "SELECT ?p ?n WHERE { ?p a :Person . ?p :forename ?n }"
response = requests.get(
    rdfox_server + "/datastores/family/sparql", params={"query": sparql_text})
assert_response_ok(response, "Failed to run select query.")
print("== Initial query result ==")
print(response.text)

# Issue insert
sparql_insert = "INSERT { ?x :marriedTo ?y } WHERE { ?y :marriedTo ?x }"
response = requests.post(
    rdfox_server + "/datastores/family/sparql", data={"update": sparql_insert})
assert_response_ok(response, "Failed to insert fact via sparql.")

# Add rule
datalog_rule = "[?p, :hasChild, ?c] :- [?c, :hasParent, ?p] ."
response = requests.post(
    rdfox_server + "/datastores/family/content", data=datalog_rule)
assert_response_ok(response, "Failed to add rule.")

# Query to confirm rule
sparql_text = "SELECT ?p ?c WHERE { ?p :hasChild ?c }"
response = requests.get(
    rdfox_server + "/datastores/family/sparql", params={"query": sparql_text})
assert_response_ok(response, "Failed to run select query.")
print("== Query for derived facts ==")
print(response.text)

# Delete fact
datalog_text = "[:stewie, :hasParent, :lois] ."
response = requests.patch(
    rdfox_server + "/datastores/family/content", params={"operation": "delete-content"}, data=datalog_text)
assert_response_ok(response, "Failed to delete fact.")

# Query to confirm derived facts updated (stewie is no longer a child of lois)
sparql_text = "SELECT ?p ?c WHERE { ?p :hasChild ?c }"
response = requests.get(
    rdfox_server + "/datastores/family/sparql", params={"query": sparql_text})
assert_response_ok(response, "Failed to run select query.")
print("== Query for updated derived facts ==")
print(response.text)

Download: pythonRest.py.

You have now completed the tutorial for the REST API. Enter quit into the RDFox shell to shut the process down then, if you would like to repeat the tutorial using a different interface (CLI or GUI), repeat the setup steps and then navigate to the appropriate section.

3.5. Next Steps

To learn more about RDFox’s shell environment see Section 15.

To learn more about how to use RDFox programatically, including via REST or Java, see Section 16.

To learn how RDFox structures the information loaded into the system, see Section 4.