In the following example, loading a truck always consumes one unit of space.

\#operator **load-truck**(obj, truck, loc) :at s
:precond [s] at(obj, loc) ∧ at(truck, loc)
:effects [s+1] at(obj, loc) := false, [s+1] in(obj, truck) := true
:resources [s+1] :consume space(truck) :amount 1 Unlike ordinary fluents, a resource res **has multiple aspects that can be queried and used in**
formulas such as operator preconditions or control rules. At any timepoint, there is an initial amount available, $init(res)**. A certain amount may be consumed during this time**
step ($consumed(res)**), produced (**$produced(res)**), borrowed exclusively (**$borrowed(res)) and borrowed non-exclusively ($borrowed-nonex(res)**). This results in a remaining amount** available ($available(res)**), which must be between the minimum (**$minimum(res)**) and the**
maximum ($maximum(res)**) allowed. The ability to refer to these aspects directly allows**
the user to specify more complex resource constraints than a **simple minimum or maximum value for a resource, such as a control rule defining a maximum amount that may be**
consumed per time step.

This concludes the description of planning domain definitions in TAL. The following sections will show the structure of TALplanner's forward-chaining search tree and how the search process is constrained using control rules.

## 3. Search And Control Rules

Like any forward-chaining planner, TALplanner searches for a plan in a tree where the root corresponds to the initial state and where each outgoing edge corresponds to one of the operators applicable in its source node. Two trivial examples are shown in Figure 2, where the notation [s,t] A means that the action A is executed between time s and time t**. For** sequential planning (Figure 2a), a new action is always added at the time step where the previous action ended. For concurrent planning (Figure 2b), TALplanner still adds a single action at a time to the plan, but the constraint on the time where the action is executed is relaxed: The action must not start before the start of an existing action in the current plan prefix or after the end of an existing action. When searching the tree, preference is given to actions invoked at earlier timepoints. In other words, TALplanner tries to add as many applicable actions as possible at the same timepoint **before stepping to the next** timepoint, so in Figure 2b the subtree starting in [0,4] A3, executing the action A3 **between** time 0 and time 4**, would have been explored before backtracking to the subtree starting** with [2,5] A3, where A3 **happens to take slightly less time to execute due to differences in** the state where the action is invoked. The search process ends as soon as the planner has found a plan ending in a state satisfying the goal. The exact definition of the search tree is available in Kvarnstr¨om and Doherty (2000) for sequential TALplanner and Kvarnstr¨om et al. (2000) for concurrent TALplanner.

Although it is common to view each node in a search tree as consisting of a single state, and an operator as a function from states to states, this is not sufficient for TALplanner, for several reasons: A single operator may generate multiple new states, the evaluation of a temporally extended goal or domain-dependent control rule may require access to the entire state history beginning in the initial state, and during concurrent planning a future