Magic Properties with SPIN
Magic Properties (aka property functions) are a popular extension point supported by many SPARQL engines. Looking like normal triple matches, magic properties can be used to dynamically compute property values even if there are no corresponding triples in the actual model. For example, in the kennedys ontology, a magic property called :grandParent could be used to dynamically find grandparent relationships even though only the direct parent relationships are asserted in the model:
In the example above, the SPARQL engine will use some internal "magic" to figure out which values need to be returned for the ?grandParent variable. How this internal magic is implemented is left to the particular engine, and in the case of Jena this is simply a Java method call in which people can add their own custom code.
These magic properties can be extremely powerful, and often are the only escape mechanism if the default expressivity of SPARQL isn't good enough for a task. However, the current mechanisms of defining such magic properties require low-level (Java) programming and leads to queries that are neither transparent to the end user, nor platform independent.
The new version of SPIN 1.1 addresses those shortcomings and provides a powerful mechanism for defining magic properties entirely in RDF. Let's look at an example first. The following TopBraid Composer 3.2 screenshot shows the definition of the magic property :grandParent:
A magic SPIN property is an instance of the property metaclass spin:MagicProperty. Like regular SPIN functions, magic properties can define arguments that represent the left hand side of the magic property. Here, the argument sp:arg1 has type kennedys:Person indicating that this property can be applied to subjects of type Person. The results of the right hand side of the triple are computed by the nested SPARQL query specified as spin:body. In this body, the variable ?arg1 represents the Person whose grand parents we are asking for. When a SPIN-aware SPARQL engine hits the triple pattern with the :grandParent predicate in it, it will execute the nested body query and bind the variable on the right with the results of the SELECT query. The results in the first screenshot (JosephKennedy and RoseFitzgerald) have been computed this way: the grand parents are the parents of the parents.
An interesting characteristic of magic properties is that they may be applied in any "direction", i.e. either with a variable on the subject position, a variable as object or even in both places. For example, the :grandParent relationship can be queried to find all grand children of RoseFitzgerald (including JohnKennedyJr):
In this case, the nested SPARQL query is simply executed with different bindings (?arg1 is left blank and ?grandParent is pre-bound with RoseFitzgerald). We can also leave both sides blank and the system will return all existing grand parent/grand child relationships in the whole model.
Now comes the really interesting bit. Think about it: this is a mechanism that can be used to define new (SPARQL) predicates entirely based on other SPARQL queries. These SPARQL queries may be recursive and may use other magic properties. The SPARQL engine can walk through the results delivered by one magic property and, while doing this, can consider any other kind of background knowledge that it needs to compute to fulfill its task. If a solution does not lead to new matches, the system will backtrack and try the next one. In traditional rule languages (incl. Prolog) this technique is called backward chaining. Each user-defined magic SPIN property can be regarded as a rule that is fired on demand to support the task of solving a goal (finding matches).
Magic SPIN properties greatly extend the power of SPARQL, and do so in a very transparent and Semantic Web compliant way.