SQWRLQueryAPI

Martin O'Connor edited this page Feb 7, 2018 · 42 revisions

The SQWRL Query API is a subsystem of SWRLAPI that provides a JDBC-like Java interface to execute SQWRL queries and to access the results of SQWRL queries.

SQWRL queries effectively return a two dimensional table containing the results of the query.

For example, if we have an OWL ontology containing a class Person with data properties hasName and hasSalary we can write the following SQWRL query to query the names and salaries for all persons in an ontology:

 Person(?p) ^ hasName(?p, ?name) ^ hasSalary(?p, ?salary) 
   -> sqwrl:select(?name, ?salary)

If this query generates a result it will return a table with two columns and a row for each name/salary pair matched by the query.

The active OWL ontology is not modified when queries are executed using this API.

Table of Contents

Creating a SQWRL Query Engine

We can run create a SQWRL query engine and run SQWRL queries on an ontology using the SQWRLQueryEngine interface, an implementation of which can be created using the SWRLAPIFactory class. We must first have an OWLAPI-based instance of that ontology, which is represented by the OWLOntology interface.

 // Create OWLOntology instance using the OWLAPI
 OWLOntologyManager ontologyManager = OWLManager.createOWLOntologyManager();
 OWLOntology ontology 
   = ontologyManager.loadOntologyFromOntologyDocument(new File("/ont/Ont1.owl")); 
 
 // Create SQWRL query engine using the SWRLAPI
 SQWRLQueryEngine queryEngine = SWRLAPIFactory.createSQWRLQueryEngine(ontology);

Creating and Running SQWRL Queries

A named query can be generated using the query engine's createSQWRLQuery method.

 queryEngine.createSQWRLQuery("Q1", "Person(?p) -> sqwrl:select(?p)");

Once created, the query can be referred to by name and executed using the runSQWRLQuery method:

 SQWRLResult result = queryEngine.runSQWRLQuery("Q1");

If an errors occurs during execution of this method a SQWRLException will be thrown.

A query can also be generated and executed in one step using the runSQWRLQuery method with a second parameter containing the query text:

 SQWRLResult result 
  = queryEngine.runSQWRLQuery("Q1", "Person(?p) -> sqwrl:select(?p)");

Note that when a query is executed the enabled SWRL rules in the ontology are also executed and any inferences made by those rules are available for querying. However, unlike the SWRLTab's rule engine, the SQWRL query engine does not modify the underlying OWL ontology.

Processing SQWRL Query Results

The interface SQWRLResult defines methods for processing query results. As mentioned, results for a particular query can be retrieved from the query engine by using the method getSQWRLResult on a query engine.

A SQWRLResult object contains one or more rows that in turn contain a list of objects defined by the interface SQWRLResultValue. There are several types of values that can be returned by a SQWRL query:

  • an OWL literal, represented by a SQWRLLiteralValue
  • an OWL entity, represented by a SQWRLEntityResultValue
  • an OWL named individual, represented by a SQWRLNamedIndividualResultValue
  • an OWL object property, represented by a SQWRLObjectPropertyResultValue
  • an OWL data property, represented by a SQWRLDataPropertyResultValue
  • an OWL annotation property, represented by a SQWRLAnnotationPropertyResultValue
  • an OWL datatype, represented by a SQWRLDatatypeResultValue
  • an OWL class expression, represented by a SQWRLClassExpressionResultValue,
  • an OWL object property expression, represented by a SQWRLObjectPropertyExpressionResultValue
  • an OWL data property expression, represented by a SQWRLDataPropertyExpressionResultValue
  • an OWL data range, represented by a SQWRLDataRangeResultValue
  • an OWL anonymous individual, represented by a SQWRLIndividualResultValue

Rows in a SQWRLResult object can be iterated through using the next method. The contents of each column in a row can then be retrieved using appropriate accessor method for each result type. The methods are: getLiteral, getClassValue, getObjectPropertyValue, getDataPropertyValue, and getAnnotationPropertyValue. Either column names or indexes can be supplied to these methods. Associated methods that can be used to determine the types of elements are also provided by the SQWRLResult interface.

For example, to process the results of the query

  Person(?p) ^ hasName(?p, ?name) ^ hasSalary(?p, ?salary) -> sqwrl:select(?name, ?salary)

we can write:

 while (result.next()) {
  SQWRLLiteralResultValue nameValue = result.getLiteral("name");
  SQWRLLiteralResultValue salaryValue = result.getLiteral("salary");
  System.out.println("Name: " + nameValue.getString());
  System.out.println("Salary: " + salaryValue.getInteger());
 }

If an error occurs during result processing, a SQWRLException will be thrown. Attempts to retrieve values of an incorrect type will generate a LiteralException, which is a sub exception of a SQWRLException.

A SQWRLLiteralResultValue defines an array of methods to retrieve literals of particular types.

Using these methods, for example, the previous query processing code can be shortened to:

 while (result.next()) {
  System.out.println("Name: " + result.getLiteral("name").getString());
  System.out.println("Salary: " + result.getLiteral("salary").getInteger()); 
 }

Processing Result Columns

The SQWRL columnNames operator can also be used to assign user-defined names to columns in a query result. We can thus rewrite the previous query to supply these names:

 Person(?p) ^ hasName(?p, ?name) ^ hasSalary(?p, ?salary) 
  -> sqwrl:select(?name, ?salary) ^ sqwrl:columnNames("Name", "Salary")

The code to access these columns can then be rewritten as:

 System.out.println("Name: " + result.getLiteralValue("Name").getString());
 System.out.println("Salary: " + result.getLiteralValue("Salary").getInteger());

Complete Example

The following is a complete showing the creation of a SQWRL query engine, the definition and execution of a SQWRL query, and the processing of the results from that query.

 // Create OWLOntology instance using the OWLAPI
 OWLOntologyManager ontologyManager = OWLManager.createOWLOntologyManager();
 OWLOntology ontology 
   = ontologyManager.loadOntologyFromOntologyDocument(new File("/ont/Ont1.owl")); 
 
 // Create SQWRL query engine using the SWRLAPI
 SQWRLQueryEngine queryEngine = SWRLAPIFactory.createSQWRLQueryEngine(ontology);
 
 // Create and execute a SQWRL query
 SQWRLResult result = queryEngine.runSQWRLQuery("Q1", 
   "Person(?p) ^ hasName(?p, ?name) ^ hasSalary(?p, ?salary)" +
   " -> sqwrl:select(?name, ?salary)");
 
 // Process the results of the SQWRL query
 while (result.next()) {
   System.out.println("Name: " + result.getLiteral("name").getString());
   System.out.println("Salary: " + result.getLiteral("salary").getInteger());
 }

A reset method is provided by the SQWRLResult class and can be called if the user wishes to process a result more than once.

Executing queries using this API does not modify the underlying OWL ontology: query results are maintained inside the query engine only. As mentioned in the SQWRL language FAQ, SQWRL queries can run in conjunction with SWRL rules. Any inferences made by those rules are also stored in the query engine and are not saved in the underlying ontology. SQWRL queries, however, can access this inferred knowledge.