Running SPARK
To run SPARK from a UNIX command line, execute the shell script spark that is in the bin directory of the SPARK release:
[spark/bin/]% ./spark
Usage information for the interpreter is displayed, default configuration settings are made, and you will see the SPARK interpreter prompt:
spark>>>
To see usage information again at any time, type "help":
spark>>> help
Optional trace information can be displayed while using SPARK. When you are new to SPARK, it may be useful to see this trace information, which will provide you with information about what beliefs and intentions the SPARK system has. To turn on tracing, type "trace":
spark>>> trace
For simplicity for these examples, you can turn tracing off:
spark>>> notrace
You can also put the SPARK interpreter into stepping mode, which will pause it at each trace point and wait for you to hit [enter] to proceed.
spark>>> step
To take SPARK out of this mode:
spark>>> nostep
As you interact with the SPARK interpreter, you will be adding facts and intentions to the SPARK knowlege base (KB). If at any time you want to begin again, removing all changes that you have made, you can do so:
spark>>> clear all
Loading a SPARK Module
All interaction with SPARK is performed with respect to a SPARK module, which defines predicates and procedures and serves as a source of initial facts for SPARK's KB. When you open the SPARK intepreter, the default module is spark.lang.builtin, the module that all other modules load automatically. Other, example modules can be found in the spark_examples directory. The spark_examples.delivery module, which is defined in the file spark_examples/delivery.spark provides some simple examples of the syntax for creating SPARK modules.
For help with writing modules, please see the manual "SPARK In a Nutshell".
For this tutorial, we will use the module spark_example.hello_world. This module is defined by the file spark_examples/hello_world.spark in the SPARK src directory and contains some simple examples. Load this module into the SPARK interpreter:
spark>>> module spark_examples.hello_world
This module declares:
- Actions - things to perform that may succeed or fail. For example, the action helloWorld prints "Hello World!".
- Procedures - which describe ways of performing action and responding to changes. For example, helloWorldProcedure describes how to perform the action helloWorld
- Predicates - which are properties of or relations between things. For example, HasParent represents the child-parent relationship.
- Facts - specific pieces of information. For example, "Alice" has a parent "Betty".
- Functions - things to transform values or match values. For example, couple takes two individuals and constructs a data structure containing both.
Running an Action
We can use the interpreter to run an action. The SPARK representation of ``Run the action helloWorld without passing in any parameters'' is [do: (helloWorld)]. This is an example of a task expression, which is something that can be executed, potentially more complex than just running a single action. Task expressions are always enclosed in brackets [].
To run the action helloWorld from the SPARK command line you type:
spark>>> [do: (helloWorld)]
Note that the task expression runs asynchronously. A new SPARK prompt appears before the action (printing "Hello World!") completes. To run a task expression synchronously, use the run command:
spark>>> run [do: (helloWorld)]This will not allow you to execute any more commands until the task expression has completed.
Evaluating a Term Expression
SPARK allows functions, such as +, which can be applied to arguments. The application of a function to arguments, such as (+ 1 2) is an example of a term expression. Some functions, such as couple in spark_examples.hello_world construct a simple record-like data structure, similar to the use of functors in Prolog. For example, if $person1 is bound to "Betty" and $person2 is bound to "Charles", then the result of (couple $person1 $person2) is the structure (couple "Betty" "Charles").
To evaluate a term expression from the SPARK command line, we use the eval command:
spark>>> eval (+ 1 2)
eval (+ 1 2)
-> 3
Testing a Predicate
The example module defines a The SPARK representation of the question "Who is a parent of Charles?" is (HasParent "Charles" $person). This is an example of a logical expression, which is something that can be tested, potentially more complex than just a single predicate. The variable $person is a placeholder for a parent of Charles. To ask this question from the SPARK command prompt, we use the "test" command, which prints solutions for a given predicate expression:
spark>>> test (HasParent "Charles" $person)
test (HasParent "Charles" $person)
1. $person: "Denise"
2. $person: "Edward"
(Note that SPARK is case-sensitive, and that predicates are traditionally written with initial capital letters.)
Similarly, if we test a predicate that is not known to be true, we will get no solutions:
spark>>> test (HasParent "Denise" $parent)
test (HasParent "Denise" $parent)
This more complex predicate expression will find all the child-parent-grandparent relationships:
spark>>> test (and (HasParent $someone $parent) (HasParent $parent $grandparent))
test (and (HasParent $someone $parent) (HasParent $parent $grandparent))
1. $grandparent: "Denise" $parent: "Charles" $someone: "Alice"
2. $grandparent: "Edward" $parent: "Charles" $someone: "Alice"
Adding a new fact
To add a new fact to the KB, we use the "addfact" command:
spark>>> addfact (Male "Frank")
addfact (Male "Frank")
adding fact to KB
The example module defines a procedure to respond to new HasParent facts by printing out a message:
spark>>> addfact (HasParent "Frank" "Betty")
addfact (HasParent "Frank" "Betty")
adding fact to KB
Betty is the parent of Frank
If we try to add this same fact again, we see that no action is triggered, because this time, the fact is not new to the KB.
Some other commands
Other things you can do from the SPARK interpreter:
View listings of the ID numbers of all current intentions:
spark>>> get intentions
View listings of all predicates known by the system. Note that, because of how modules are loaded, this will only really work if you have already interacted in some way with the current module.
spark>>> get predicates
This will display predicate symbols that are accessible from the current module. To see all predicate symbols currently declared within the SPARK KB, type:
spark>>> get all predicates
Similarly, you can view all known tasks or functions:
spark>>> get functions
spark>>> get tasks
spark>>> get all functions
spark>>> get all tasks
To leave the SPARK interpreter, type "exit"
spark>>> exit