The documentation on this page applies to the APIs in the Protege 3.4.8 release. In 3.5, the SWRLTab APIs changed slightly. Information on updating code to use the 3.5 APIs can be found here. (CHH)
The SQWRLQueryAPI is a subsystem of SWRLTab that provides a JDBC-like Java interface to retrieve the result of SQWRL queries. A description of writing SQWRL queries can be found here. (9Z2)
SQWRL queries effectively return a two dimensional table containing the results of the query. Say, for example, we have an OWL ontology containing a class Person with associated properties hasName and hasSalary and also a SQWRL query named "Query-1" that uses this information to query the names and salaries for all persons in an ontology: (9Z3)
- Person(?p) ^ hasName(?p, ?name) ^ hasSalary(?p, ?salary) -> sqwrl:select(?name, ?salary) (9Z4)
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. (9Z5)
The loaded OWL ontology is not modified when queries are executed using this API. (CC1)
Creating a SQWRL Query Engine (BJI)
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 SQWRLQueryEngineFactory class. (9Z6)
OWLModel owlModel = ... // Create using normal Protege-OWL mechanisms SQWRLQueryEngine queryEngine = SQWRLQueryEngineFactory.create(owlModel); (AEO)
Creating and Running SQWRL Queries (BJJ)
A named query can be generated using the query engine's createSQWRLQuery method. (BJH)
queryEngine.createSQWRLQuery("Query-2", "Person(?p)-> sqwrl:select(?p)"); (AES)
Once created, the query can be referred to by name and executed using the runSQWRLQuery method: (BJD)
SQWRLResult result = queryEngine.runSQWRLQuery("Query-1"); (AER)
If the named query does not return any results, this method will return null. If an errors occurs during execution of this method, a SQWRLException will be thrown. (BJE)
A query can also be generated and executed in one step using the runSQWRLQuery method with a second parameter containing the query text: (BJF)
SQWRLResult result = queryEngine.runSQWRLQuery("Query-2", "Person(?p)-> sqwrl:select(?p)"); (AES)
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. (CC0)
Processing SQWRL Query Results (BJK)
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 supplied with the name of the SQWRL query. (BJG)
A SQWRLResult object contains one or more rows that in turn contain a list of objects defined by the interface SQWRLResultValue. There are four main types of values that can be returned by a SQWRL query: (1) a DataValue, representing values of OWL data properties; (2) an IndividualValue, representing OWL individuals; (3) a ClassValue, representing OWL classes; and (4) a PropertyValue, representing OWL properties. (9ZB)
Rows in a SQWRLResult object can be iterated through using the hasNext and next methods. The contents of each column in a row can then be retrieved using appropriate accessor method for each result type. The methods for the four main types are: getDataValue, getObjectValue, getClassValue, and getPropertyValue. Either column names or indexes can be supplied to these methods. Associated method that can be used to determine the types of elements are also provided by the SQWRLResult interface. (9ZC)
For example, to process the results of the previous query, we can write: (AEU)
while (result.hasNext()) { DataValue nameValue = result.getDataValue("?name"); DataValue salaryValue = result.getDataValue("?salary"); System.out.println("Name: " + nameValue.getString()); System.out.println("Salary: " + salaryValue.getInt()); result.next(); } (9ZE)
If an error occurs during result processing, a SQWRLException will be thrown. Attempts to retrieve values of an incorrect type will generate a DataValueConversionException, which is a sub exception of SQWRLException. So, for example, the previous query processing code can safely be shortened to (A39)
while (result.hasNext()) { System.out.println("Name: " + result.getDataValue("?name").getString()); System.out.println("Salary: " + result.getDataValue("?salary").getInt()); result.next(); } (9ZE)
A DataValueConversionException will be thrown if an invalid conversion is attempted during result process. (A3A)
Processing Result Columns (BJN)
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: (9ZG)
- Person(?p) ^ hasName(?p, ?name) ^ hasSalary(?p, ?salary) -> sqwrl:select(?name, ?salary) ^ sqwrl:columnNames("Name", "Salary") (9ZH)
The code to access these columns can then be rewritten as: (9ZI)
System.out.println("Name: " + result.getDataValue("Name").getString()); System.out.println("Salary: " + result.getDataValue("Salary").getInt()); (AX8)
Complete Example (BJO)
So, a complete example to create a query and execute it using a SQWRL query engine can be written as follows: (AXB)
OWLModel owlModel = ... // Create using normal Protege-OWL mechanisms. SQWRLQueryEngine queryEngine = SWRLQueryEngineFactory.create(owlModel); SQWRLResult result = queryEngine.runSQWRLQuery("Query-1", Person(?p) ^ hasName(?p, ?name) ^ hasSalary(?p, ?salary) -> sqwrl:select(?name, ?salary)"); while (result.hasNext()) { System.out.println("Name: " + result.getDataValue("?name").getString()); System.out.println("Salary: " + result.getDataValue("?salary").getInt()); result.next(); } (AXA)
A reset method is provided by the SQWRLResult class that can be called if the user wishes to process a result more than once. (9ZK)
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. (A5V)
Installing the SQWRLQueryAPI (BJL)
The SQWRLQueryAPI is distribute with the standard Protege-OWL distribution. (BJM)
It requires a rule engine to execute queries. In the 3.4.8 release, the Jess rule engine is the only engine supported by the SWRLTab. Information on installing Jess can be found here. In the 3.5 and later release, the Drools rule engine is also supported. Unlike Jess, Drools is open source and does not require a license for use so is preinstalled. (CHI)
Changing the Default SQWRL Rule Engine (CI6)
In the 3.5 release of Protege, both Drools and Jess plugins can process SQWRL queries. Drools is the default rule engine in both the SQWRLQueryTab and the SQWRLQueryAPI. This default behaviour can be changed by setting a property named protege.owl.swrl.default_rule_engine in the protege.properties file, which is in the base of the Protege installation directory. For example, an entry to set the default rule engine to Jess would be: (CI7)
protege.owl.swrl.default_rule_engine=Drools (CI8)
Protege must be restarted for this assignment to take effect. (CI9)