Author: Jeff Dalton

Using an I-Plan panel

To use I-Plan, use main program class ix.iplan.IPlan.

Although I-Plan looks much like an I-X Process Panel (I-P2), the functionality is very different. For instance, the only significant action you can apply to an activity is to expand it (if there's a suitable refinement).

In I-Plan, you can set up a planning problem by adding activities, changing the world-state, and (if you want) expanding activities by using refinements in the domain or by using the "details" editor.

The "I-Plan" entry in the "Tools" menu brings up a window that can be used to run the automatic planner, to replan (i.e., find an alternative plan), or to run the plan-checking execution-simulator.

You can use the "Send plan" entry in the "File" menu to send the plan to another agent. You can also use that menu entry in another agent to send a plan to an I-Plan.

By default, I-Plan supports multiple "options", where each option is a separate plan. Options are created by replanning and in other ways.

For more about options, see the Notes on Options.

Annotations that affect planning

Restrictions on condition-satisfaction

There is a simple mechanism that controls whether the planner tries to "achieve" a condition (by potentially adding an activity). Without this, it will treat all conditions as achievable. The mechanism will be replaced once we implement proper condition types.

There is a domain annotation, achievable-world-state-conditions, with possible values:

   (word ...)
where each word is one that can appear first in a pattern. This specifies which world-state conditions the planner will attempt to satisfy by achieving. The default is :all.

There is also a refinement annotation, use-for-world-state-effects, with similar values. It specifies which effects in that refinement will be considered when trying to achieve conditions. Again the default is :all.

(There could be an achievable-world-state-conditions on refinements as well, but that has not yet been implemented.)

(Note that a domain achievable-world-state-conditions annotation works, in effect, as a kind of domain use-for-world-state-effects as well.)


   (refinement setup (setup)
       ;; The apple starts as ready: it could be eaten as-is.
       (world-state effect (status apple) = ready))
       ;; Keep this refinement from being used to achieve a condition.
       (use-for-world-state-effects = :none)))

Input and output annotations

Refinements that represent web services, or similar entities, can specify inputs and outputs as annotations. (These are really input and output constraints and will be supported as constraints in some later versions.)

For example, a refinement that represented a service that produced book price information when given a description of a book might be defined like this:

(refinement book-price-service (book-price-service ?book-info to ?book-price)
  (variables ?book-info ?book-price)
    (world-state condition (type ?book-info) = book)
    (world-state effect (type ?book-price) = price))
    (input-objects = ((?book-info book)))
    (output-objects = ((?book-price price)))))

When the planner uses such a refinement to expand an activity, it will generate a symbol to represent each output object. The symbol-generation happens at plan-time. (The objects that correspond to those symbols would, of course, not be produced until the plan was executed using a suitable execution engine.) In effect, the symbols are used to represent which outputs are given to which inputs in the plan. This makes it possible to recover data-flow.

Note that, for now, this happens only in the automatic planner. Input and output annotations are currently ignored when you are working manually in I-Plan or I-P2.

Search preference

 (search-preference = :depth-first))
tells the I-Plan algorithm to pick "choice points" in a depth-first fashion when backtracking. This feature exists mostly for testing, but in some planning domains it helps the planner find solutions more easily.


I-Plan and I-P2 understand a very simple form of "advice" constraint.

Here's an example in LTF syntax:

   (refinement test2 (test2) ; 2 solutions
       (1 (travel edinburgh london)))
       (advice expansion-refinement
               travel (travel-by-train travel-by-air))))
That says: whenever you're expanding an activity that has pattern-verb "travel", you must use one of the listed refinements. And for now at least, it applies to every expansion the planner considers after the constraint has been added.

The example above is potentially misleading, because it can look like the constraint is just to affect the node introduced by that refinement; but it's in fact more general.

For example, for suppose that "rescue" activities had, somewhere in their expansion, activities such as "locate" and "recover". Here's an example refinement for testing in such a domain:

(refinement test1 (test1)
    (1 (rescue UNESCO-Visitors)))
     (advice expansion-refinement locate (locate-air-search))
     (advice expansion-refinement recover
        (recover-unassisted recover-by-civilian-means))))

It is also possible to specify the arity of the verb. For example, if you wanted the advice to apply to patterns of the form (travel ?? ??), but not to cases where "travel" was followed by a different number of arguments, you could do that as follows:

     (advice expansion-refinement
             travel/2 (travel-by-train travel-by-air)))
This is often useful avoid constraining more activities than are intended.

Of course, this is just a very simple form of advice. Even when the aim is just to restrict the choice of refinement, a pattern, rather than just a verb, could be used to say which nodes it applied to, and some kind of "path" spec might also be useful (e.g. to constrain a "move" activity only when it's a subnode of a "recover" activity).

Such things are not yet supported, but a more expressive advice language may be provided in later versions.

Time and resource constraints

I-Plan supports a range of time and resource constraints, and it is possible to add new constraint managers for other constraints that can be handled using the same protocol. (That ability will be extended and documented in later releases.)

It is important to remember that all of the constraints are hard constraints. So if min and max durations are given, for example, the domain modeller should ensure that the values are true minima and maxima.

Each subsection begins with the LTF syntax for the constraints.

Duration constraints

    temporal duration node-ref = time-window

    node-ref = node-id | self

    time-window ::= min-duration .. max-duration

At present, only durations for self are supported. "Self" refers to the node that is being refined by the refinement that contains the constraint.

A duration has ISO 8601 syntax for days, hours, minutes, seconds and milliseconds, for example P1DT2H3M4.567S = 1 day, 2 hours, 3 minutes, 4 seconds, 567 milliseconds. Note that the "P" and the "T" are required. So 1 minute is PT1M.

A variable can appear in place of a min or max duration, so long as other constraints arrange for it to have a value that can be converted into a duration in a straightforward way. Currently, that means the value must be a string or symbol that conforms to the ISO 8601 syntax, or else an integer number of milliseconds. Floating-point numbers (doubles) will be cast to longs, then treated as milliseconds.

The constraint manager for these constraints maintains min and max "start times", relative to a notional time 0, for every "time point" in the plan. The max times can be infinite, meaning that the point can occur arbitrarily late.

Each activity in the plan has a time point that represents the time when the activity begins execution, and another time point that represents when the activity ends. Therefore, the min and max values for those time points correspond to earliest and latest start and finish times for the activities.

(The constraint manager can actually handle a more general form of constraint that specifies a min and max durational delay between any two time points, but that ability has not yet been "connected" into the rest of the system.)

Strictly consumable resources

    resource overall pattern = integer
    resource consume pattern = integer

They are just one of the possible sorts of resource constraints.

The idea, in this case, is that there are "strictly comsumable" resources that exist in some quantity. They can be consumed, but none can be produced in the context of the plan. If an activity uses some of one of these resources, it has a constraint that looks like this:

   resource consume resource = amount

To fit the "generic" constraint syntax, type subtype pattern = value, the constraint looks slightly different from what one probably expects, because of the current restriction that the "pattern" has to be a list. So to "consume" one apple, the constraint is

   resource consume (apple) = 1
(It's the parens around "apple" that may be unexpected but are at present required by the "generic" syntax.)

The default is that such resources are inexhaustible. There's an infinite supply of apples, by default.

However, a constraint on an activity that looks like this

   resource overall resource = value
says that the activity and all of its subactivities (all the way down) collectively comsume the indicated value. Therefore the subactivities cannot (collectively) consume more than that value.

That provides a limit on the availability of the resource.

Those who are familiar with O-Plan will recognise this as a similar to O-Plan's strictly-consumable resource constraints.

"Use" constraints

    resource use pattern = true

The idea behind these constraints is that the pattern names a specific, individual resource that can be used by only one activity at a time. For example, in a block-stacking domain, the robot arm might be such a resource.

By using variables in the pattern, the planner can be told to choose among a number of different named resources, as well as introducing ordering constraints to separate uses of the same resource. For example:

   (refinement move (move ?object to ?place using ?vehicle)
     (variables ?object ?to ?vehicle)
	(world-state condition (type ?vehicle) = vehicle)
	(resource use (?vehicle) = true)))
(See the previous section for an explanation of the parens around "?vehicle".)

Suppose only A and B have type vehicle, that there are two "move" activities in the plan, and that the refinment above is the only one that can be used to refine "move"s. Plans might have the two "move"s in parallel (unordered with respect to each other) if they used different vehicles, or in either order if they used the same one.

(At present, the value side of the pattern = value in the constraint must be "true", however some semantic possibilities for other values are being considered.)

Jeff Dalton <J.Dalton@ed.ac.uk>