SPARQLMotion is an entirely declarative language. Scripts are defined
by means of instances of the SPARQLMotion ontologies and then interpreted
by a SPARQLMotion execution engine. The engine "knows" how to
execute each step and executes internal (Java) code to actually perform
the necessary steps. If two modules are linked via the sm:next
property, then the output of the first module becomes the input of the
second module.
SPARQLMotion scripts typically start with modules that import data from
the outside into the script. A typical examples are sml:ImportRDFFromURL
that imports RDF from some server. A simple way of getting started is to
take sml:ImportCurrentRDF
as starting point - this will simply
pass all the triples of the currently open model (the script itself) into
the script, including all imports etc.
Most modules process RDF data. In the default implementation, this means that they operate on Jena RDF Graphs. If a module takes multiple input modules, then it will operate on the union graph that results from merging the single input graphs.
Many modules are controlled by SPARQL queries (Select, Construct and Ask). These queries will be executed over the input RDF graphs.
In addition to passing RDF, modules can bind variables and use variables
defined by their predecessors. Some modules such as sml:EnterLiteral
create new variable bindings. There are two common ways of using variables
in modules:
First, if a bound variable is mentioned in a SPARQL query, then the query will be executed with the current variable's value. Note that variables that are bound to a blank node will be ignored if a SPARQL query calls a remote server (with a FROM clause).
Second, all string properties of a module definition can reference
variables bindings using a construct such as {?varName}
.
For example, if the variable ?placeName
contains the value
"London", then the URL
http://ws.geonames.org/search?type=rdf&maxRows=10&q={?placeName}
will be converted into
http://ws.geonames.org/search?type=rdf&maxRows=10&q=London
SPARQLMotion scripts are always executed from top to bottom, i.e.
starting with the nodes that don't have any predecessors and then walking
down into the sm:next
nodes. The order of execution is
non-predictable when a script branches, but the engine will always make
sure that all predecessors have been executed before the module itself.
In addition to this execution policy, there are currently two control
constructs available: branching (if-then-else) and iterating (for each).
sml:IterateOverSelect
runs a SPARQL Select query and
repeats a nested sub-script (the body) for each match of the query.
The variable mentioned in the Select query will be bound in each iteration.sml:BranchByAsk
runs a SPARQL Ask query which delivers
a boolean. Depending on the outcome, either the sm:if
or the
sm:else
branch are executed.
In both cases, the main execution thread stops until the nested script
is completed. The outcome of the end nodes of the nested scripts will
then be passed into the sm:next
node of the control module.