PlexiLisp Tutorial

See the Programming in Plexilisp chapter for an introduction to Plexilisp. Before we continue, it’s assumed you are using Emacs on a Unix-like system, and that you have checked out the latest plexil_exec module from SVN.

Emacs Setup

In order to have Plexilisp automatically compiled (when needed) and loaded every time you start Emacs, the file plexil/src/plexilisp/emacs.el should be automatically loaded. This file depends on the Unix environment variable PLEXIL_HOME to find things, so it must be set prior to loading the file. The easiest way to make all this happen is to insert the following two lines into your .emacs file. (If you don’t have a .emacs file, create one in your home directory):

(setenv "PLEXIL_HOME" "/home/fred/plexil")
(load (concat (getenv "PLEXIL_HOME") "/src/plexilisp/emacs.el"))

Of course, please edit the pathname /home/fred/plexil as needed. Using the full pathname of your plexil directory, and not the ~/ shortcut for your home directory, may be necessary, as the tilde character is not always handled correctly in this context.

First Example

We’re now ready to get our feet wet. Open the file plexilisp/examples/simple-assignment.pli, which looks like this:

(plexil-plan
 (assignment-node "SimpleAssignment"
  (variables (integer "foo" 0))
  (assignment (intvar "foo") 3)))

This is a trivial single-node PLEXIL plan that is just an assignment node. It declares an integer variable named foo and assigns 3 to it.

You might notice that this looks like Lisp. However, it is not Lisp, and it is impossible to invoke any Lisp though Plexilisp. If you prefer, you may use the Capitalized and “CamelCase” variants of all the Plexilisp constructs. Look at the file SimpleAssignment.pli:

(PlexilPlan
 (AssignmentNode "SimpleAssignment"
  (Variables (Integer "foo" 0))
  (Assignment (IntegerVariable "foo") 3)))

It differs only in the typecase of the Plexilisp identifiers, and is functionally equivalent to the first plan.

Compiling Plexilisp

Now, let’s generate some PLEXIL XML. Put your cursor in either of the buffers you created above, and either type ‘’’M-x plexil’’’ or ‘’’Control-C Control-C’’’ (the latter is a shortcut for the former).

Plexilisp goes through a two-step “compilation” process. The first generates an Extended PLEXIL file, which has a file extension of .epx. The second step compiles the Extended PLEXIL into Core PLEXIL, creating a .plx file. Buffers for both these files will be appear in your Emacs.

In this case a new buffer named simple-assignment.plx (or SimpleAssignment.plx) should appear, after a brief delay. Directly “underneath” this buffer will be one for the .epx file. The Core PLEXIL buffer should contain XML code that looks like this:

<?xml version="1.0" encoding="utf-8"?>
 <!-- Generated by PlexiLisp -->
 <PlexilPlan>
   <Node NodeType="Assignment">
     <NodeId>SimpleAssignment</NodeId>
     <VariableDeclarations>
       <DeclareInteger>
         <IntegerVariable>foo</IntegerVariable>
         <IntegerValue>0</IntegerValue>
       </DeclareInteger>
     </VariableDeclarations>
     <NodeBody>
       <Assignment>
         <IntegerVariable>foo</IntegerVariable>
         <NumericRHS>
           <IntegerValue>3</IntegerValue>
         </NumericRHS>
       </Assignment>
     </NodeBody>
   </Node>
 </PlexilPlan>

Simulation Script

If you’d like to run this plan with the PLEXIL Test Executive, you’ll need a simulation script. Since this plan does not interact with an external world, an empty script will do. We can create scripts with Plexilisp as well. There’s an empty script in your examples directory. Open one of empty-script.pli or EmptyScript.pli, whichever looks prettier to you.

(plexil-script
  (script))

Type M-x plexil (or type ‘’’Control-C Control-C’’’) again, which should give you the .plx version of the file:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generated by PlexiLisp -->
<PLEXILScript>
  <Script></Script>
</PLEXILScript>

More Examples

We’ll look at one more example plan, the “simple drive” plan that has two equivalent versions in the examples directory:

(PlexilPlan
 (ListNode "SimpleDrive"
   (EndCondition (NodeFinished "TakeSample"))
   (PostCondition (NodeSuccessful "TakeSample"))
   (List
    (CommandNode "Drive"
      (Precondition (= (LookupNow "At" "Rock") false))
      (RepeatCondition (= false (LookupOnChange "At" "Rock")))
      (Command "drive" 1.0))
    (CommandNode "TakeSample"
      (StartCondition (NodeFinished "Drive"))
      (InvariantCondition (= true (LookupOnChange "At" "Rock")))
      (Command "takeSample")))))

(plexil-plan
 (list-node "SimpleDrive"
   (end-condition (node-finished "TakeSample"))
   (postcondition (node-successful "TakeSample"))
   (list
    (command-node "Drive"
      (precondition (= (lookup-now "At" "Rock") false))
      (repeat-condition (= false (lookup-on-change "At" "Rock")))
      (command "drive" 1.0))
    (command-node "TakeSample"
      (start-condition (node-finished "Drive"))
      (invariant-condition (= true (lookup-on-change "At" "Rock")))
      (command "takeSample")))))

This plan translates into about 100 lines of PLEXIL XML, so we won’t show that here. But try it yourself! The corresponding simulation script is found in simple-drive-script.pli/SimpleDriveScript.pli:

(PlexilScript
 (InitialState
  (State "At" "bool" 0 (Param "Rock")))
 (Script
  (State "At" "bool" 1 (Param "Rock"))
  (CommandAck "drive" "bool" 1 (Param 1.0 "real"))
  (CommandAck "takeSample" "bool" 1)))

Its translation is:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generated by PlexiLisp  -->
<PLEXILScript>
  <InitialState>
    <State name="At" type="bool">
      <Param>Rock</Param>
      <Value>0</Value>
    </State>
  </InitialState>
  <Script>
    <State name="At" type="bool">
      <Param>Rock</Param>
      <Value>1</Value>
    </State>
    <CommandAck name="drive" type="bool">
      <Param type="real">1.0</Param>
      <Result>1</Result>
    </CommandAck>
    <CommandAck name="takeSample" type="bool">
      <Result>1</Result>
    </CommandAck>
  </Script>
</PLEXILScript>

A substantial Plexilisp plan example is found in examples/3209.pli. This is the actual ISS Procedure 3.209 that runs with the ISS-In-A-Box simulator.

For a comprehensive look at Plexilisp, see the Plexilisp Reference Manual.