Excerpted from Prof. Dyer's Partial-Order Planning notes.

Example -- Solving the Sussman Anomaly using the POP Algorithm
In the following plans, links shown as -----> are causal links and are labeled with the open precondition that is solved by this link. Links shown as ++++++> are temporal links, though most of these are not shown in order to keep the figures neater. Of course, for each causal link there should also be a temporal link connecting the same two nodes, but this is not shown.

 

  1. Create initial-plan:
  2. Start +++++++++++++> Finish
    P: none              P: on(A,B)
    E: on(C,A)              on(B,C)
       handempty
       ontable(A)
       ontable(B)
       clear(B)
       clear(C)
  3. Solve open precondition on(A,B) in step Finish by Step Addition using Stack(A,B).

  4. Notes:
    1. Stack is the only operator that can be used to solve this open precondition.
    2. The figure below should include a temporal link from the new step to Finish, but it is not included in order to keep the figure more readable. Also, the temporal link connecting Start to Finish has been omitted for the same reason.
                                         on(A,B)
    Start +++++++++++++> Stack(A,B) ------------> Finish
    P: none              P: holding(A)            P: on(A,B)
    E: on(C,A)              clear(B)                 on(B,C)
       handempty         E: on(A,B)
       ontable(A)           clear(A)
       ontable(B)           handempty
       clear(B)             ~holding(A)
       clear(C)             ~clear(B)
  5. Solve open precondition on(B,C) in step Finish by Step Addition using Stack(B,C).

  6. Notes:
    1. Stack is the only operator applicable here.
    2. The figure below should include temporal links from Start to the new step, as well as from the new step to Finish, but these are not explicitly shown in order to keep the figure more readable.
                                      on(A,B)
    Start +++++++++++++> Stack(A,B) ------------> Finish
    P: none              P: holding(A)          ^ P: on(A,B)
    E: on(C,A)              clear(B)            |    on(B,C)
       handempty         E: on(A,B)             |
       ontable(A)           clear(A)            |
       ontable(B)           handempty           |
       clear(B)             ~holding(A)         |
       clear(C)             ~clear(B)           |
                                                |
                                      on(B,C)   |
                         Stack(B,C) ------------|
                         P: holding(B)
                            clear(C)
                         E: on(B,C)
                            clear(B)
                            handempty
                            ~holding(B)
                            ~clear(C)
  7. Solve open precondition holding(B) in step Stack(B,C) by Step Addition using Pickup(B).

  8. Notes:
    1. There are two possible operators (Pickup and Unstack) that could be used to solve this open precondition, so this is a choice point for the algorithm.
    2. The figure below should include temporal links from Start to the new step, as well as from the new step to Stack(B,C), but these are not explicitly shown in order to keep the figure more readable.
                                      on(A,B)
    Start +++++++++++++> Stack(A,B) ------------> Finish
    P: none              P: holding(A)          ^ P: on(A,B)
    E: on(C,A)              clear(B)            |    on(B,C)
       handempty         E: on(A,B)             |
       ontable(A)           clear(A)            |
       ontable(B)           handempty           |
       clear(B)             ~holding(A)         |on(B,C)
       clear(C)             ~clear(B)           |
                                                |
                                    holding(B)  |
                         Pickup(B) -----------> Stack(B,C)
                         P: ontable(B)          P: holding(B)
                            clear(B)               clear(C)
                            handempty           E: on(B,C)
                         E: holding(B)             clear(B)
                            ~ontable(B)            handempty
                            ~clear(B)              ~holding(B)
                            handempty              ~clear(C)
  9. Solve open precondition holding(A) in step Stack(A,B) by Step Addition using Pickup(A).

  10. Notes:
    1. There are two possible operators (Pickup and Unstack) for solving this open precondition, so this is a choice point for the algorithm.
    2. The figure below should include temporal links from Start to the new step, as well as from the new step to Stack(A,B), but these are not explicitly shown in order to keep the figure more readable.
                              holding(A)             on(A,B)
    Start ++++++++> Pickup(A) ----------> Stack(A,B) --------> Finish
    P: none         P: ontable(A)         P: holding(A)      ^ P: on(A,B)
    E: on(C,A)         clear(A)              clear(B)        |    on(B,C)
       handempty       handempty          E: on(A,B)         |
       ontable(A)   E: holding(A)            clear(A)        |
       ontable(B)      ~clear(A)             handempty       |
       clear(B)        ~ontable(A)           ~holding(A)     |on(B,C)
       clear(C)        ~handempty            ~clear(B)       |
                                                             |
                                                   |---------|
                                   holding(B)      |
                         Pickup(B) -----------> Stack(B,C)
                         P: ontable(B)          P: holding(B)
                            clear(B)               clear(C)
                            handempty           E: on(B,C)
                         E: holding(B)             clear(B)
                            ~ontable(B)            handempty
                            ~clear(B)              ~holding(B)
                            handempty              ~clear(C)
  11. Solve open precondition clear(A) in step Pickup(A) using Step Addition with Unstack(C,A):
  12. Start
    P: none
    E: on(C,A)
       handempty
       ontable(A)
       ontable(B)
       clear(B)
       clear(C)
    
               clear(A)          holding(A)             on(A,B)
    Unstack(C,A) ----> Pickup(A) ----------> Stack(A,B) -------> Finish
    P: clear(C)        P: ontable(A)         P: holding(A)     ^ P: on(A,B)
       on(C,A)            clear(A)              clear(B)       |    on(B,C)
       handempty          handempty          E: on(A,B)        |
    E: holding(C)      E: holding(A)            clear(A)       |
       clear(A)           ~clear(A)             handempty      |
       ~clear(C)          ~ontable(A)           ~holding(A)    |on(B,C)
       ~on(C,A)           ~handempty            ~clear(B)      |
       ~handempty                                              |
                                                   |-----------|
                                   holding(B)      |
                         Pickup(B) -----------> Stack(B,C)
                         P: ontable(B)          P: holding(B)
                            clear(B)               clear(C)
                            handempty           E: on(B,C)
                         E: holding(B)             clear(B)
                            ~ontable(B)            handempty
                            ~clear(B)              ~holding(B)
                            handempty              ~clear(C)
  13. Solve open precondition handempty in Pickup(B) using Step Addition with Putdown(C):
  14. Start
    P: none
    E: on(C,A)
       handempty
       ontable(A)
       ontable(B)
       clear(B)
       clear(C)
    
               clear(A)          holding(A)             on(A,B)
    Unstack(C,A) ----> Pickup(A) ----------> Stack(A,B) -------> Finish
    P: clear(C)        P: ontable(A)         P: holding(A)     ^ P: on(A,B)
       on(C,A)            clear(A)              clear(B)       |    on(B,C)
       handempty          handempty          E: on(A,B)        |
    E: holding(C)      E: holding(A)            clear(A)       |
       clear(A)           ~clear(A)             handempty      |
       ~clear(C)          ~ontable(A)           ~holding(A)    |on(B,C)
       ~on(C,A)           ~handempty            ~clear(B)      |
       ~handempty                                              |
                                                   |-----------|
              handempty            holding(B)      |
    Putdown(C) --------> Pickup(B) -----------> Stack(B,C)
    P: holding(C)        P: ontable(B)          P: holding(B)
    E: ontable(C)           clear(B)               clear(C)
       clear(C)             handempty           E: on(B,C)
       handempty         E: holding(B)             clear(B)
       ~holding(C)          ~ontable(B)            handempty
                            ~clear(B)              ~holding(B)
                            handempty              ~clear(C)
  15. Solve open preconditions using Simple Establishment for each of the following:
  16.  

    Open Precond in Step Solved by Step
    clear(C) Unstack(C,A) Start
    on(C,A) Unstack(C,A) Start
    handempty Unstack(C,A) Start
    For each of the above, add a causal link from Start to Unstack(C,A).
  17. Detect threat ~clear(C) in step Stack(B,C) to causal link from Start to Unstack(C,A). Fix by Promotion: add temporal link from Unstack(C,A) to Stack(B,C) so that Stack(B,C) forced to come after Unstack(C,A).
  18. Start ----------
    P: none        |
    E: on(C,A)     |
       handempty   |clear(C)
       ontable(A)  |on(C,A)
       ontable(B)  |handempty
       clear(B)    |
       clear(C)    |
                   |
        |----------|
        |
        V      clear(A)          holding(A)             on(A,B)
    Unstack(C,A) ----> Pickup(A) ----------> Stack(A,B) -------> Finish
    P: clear(C)  +     P: ontable(A)         P: holding(A)     ^ P: on(A,B)
       on(C,A)    +       clear(A)              clear(B)       |    on(B,C)
       handempty  +       handempty          E: on(A,B)        |
    E: holding(C) +    E: holding(A)            clear(A)       |
       clear(A)   +       ~clear(A)             handempty      |
       ~clear(C)  +       ~ontable(A)           ~holding(A)    |on(B,C)
       ~on(C,A)    ++++   ~handempty            ~clear(B)      |
       ~handempty      ++++++++++++++++++++++++++              |
                                                +  |-----------|
              handempty            holding(B)   v  |
    Putdown(C) --------> Pickup(B) -----------> Stack(B,C)
    P: holding(C)        P: ontable(B)          P: holding(B)
    E: ontable(C)           clear(B)               clear(C)
       clear(C)             handempty           E: on(B,C)
       handempty         E: holding(B)             clear(B)
       ~holding(C)          ~ontable(B)            handempty
                            ~clear(B)              ~holding(B)
                            handempty              ~clear(C)
  19. Solve open preconditions using Simple Establishment for each of the following:
  20.  

    Open Precond in Step Solved by Step
    Holding(C) Putdown(C) Unstack(C,A)
    ontable(B) Pickup(B) Start
    clear(B) Pickup(B) Start
    handempty Pickup(B) Putdown(C)
    For each of the above, add a causal link.
  21. Detect threat ~handempty at step Pickup(A) to causal link from Putdown(C) to Pickup(B). Fix by Promotion: add temporal link from Pickup(B) to Pickup(A).
  22.  Note: This fix means there is no threat at step Stack(A,B) to causal link from Start to Pickup(B) because now Stack(A,B) is after Pickup(A) which is after Pickup(B), so Stack(A,B) must occur after Pickup(B).

    Start ----------
    P: none        |
    E: on(C,A)     |
       handempty   |clear(C)
       ontable(A)  |on(C,A)
       ontable(B)  |handempty
       clear(B)    |
       clear(C)    |
                   |
        |----------|
        |
        V      clear(A)          holding(A)             on(A,B)
    Unstack(C,A) ----> Pickup(A) ----------> Stack(A,B) -------> Finish
    | P:clear(C)  +   ^ P: ontable(A)         P: holding(A)     ^ P: on(A,B)
    |   on(C,A)    +  +    clear(A)              clear(B)       |    on(B,C)
    |   handempty  +  +    handempty          E: on(A,B)        |
    | E:holding(C) +  + E: holding(A)            clear(A)       |
    |   clear(A)   +  +    ~clear(A)             handempty      |
    |   ~clear(C)  +  +    ~ontable(A)           ~holding(A)    |on(B,C)
    |   ~on(C,A)    ++++   ~handempty            ~clear(B)      |
    |   ~handempty    + +++++++++++++++++++++++++               |
    |                 +                         +               |
    |holding(C)       ++++                      +  |------------|
    |                    +                      +  |
    v         handempty  +         holding(B)   v  |
    Putdown(C) --------> Pickup(B) -----------> Stack(B,C)
    P: holding(C)        P: ontable(B)          P: holding(B)
    E: ontable(C)           clear(B)               clear(C)
       clear(C)             handempty           E: on(B,C)
       handempty         E: holding(B)             clear(B)
       ~holding(C)          ~ontable(B)            handempty
                            ~clear(B)              ~holding(B)
                            handempty              ~clear(C)
  23. Solve open preconditions using Simple Establishment for each of the following:
  24.  

    Open Precond in Step Solved by Step
    clear(C) Stack(B,C) Putdown(C)
    ontable(A) Pickup(A) Start
    handempty Pickup(A) Stack(B,C)
    clear(B) Stack(A,B) Stack(B,C)
    For each of the above, add a causal link.
    Start ----------------------
    P: none        |           |
    E: on(C,A)     |           |
       handempty   |clear(C)   |ontable(A)
       ontable(A)  |on(C,A)    |
       ontable(B)  |handempty  |
       clear(B)    |           |
       clear(C)    |           |
                   |    |------|
        |----------|    |
        |               |
        V      clear(A) v        holding(A)             on(A,B)
    Unstack(C,A) ----> Pickup(A) ----------> Stack(A,B) -------> Finish
    | P:clear(C)  +  ^ ^P: ontable(A)       ^ P: holding(A)     ^ P: on(A,B)
    |   on(C,A)    + + |   clear(A)         |    clear(B)       |    on(B,C)
    |   handempty  + + |   handempty        | E: on(A,B)        |
    | E:holding(C) + + |E: holding(A)       |    clear(A)       |
    |   clear(A)   + + |   ~clear(A)        |    handempty      |
    |   ~clear(C)  + + |   ~ontable(A)      |    ~holding(A)    |on(B,C)
    |   ~on(C,A)   + + |   ~handempty       |    ~clear(B)      |
    |   ~handempty + + |------|             |--------|          |
    |              + +        |  handempty           |          |
    |              +++++++++  |--------------------| |          |
    |                +     +                       | |clear(B)  |
    |holding(C)      +++++ ++++++++++++++++++++++  | |          |
    |                    +                      +  | | |--------|
    v         handempty  +         holding(B)   v  | | |
    Putdown(C) --------> Pickup(B) -----------> Stack(B,C)
    P: holding(C) \      P: ontable(B)        ^ P: holding(B)
    E: ontable(C)  \        clear(B)          |    clear(C)
       clear(C)     \       handempty         | E: on(B,C)
       handempty     \   E: holding(B)        |    clear(B)
       ~holding(C)    \     ~ontable(B)       |    handempty
                      |     ~clear(B)         |    ~holding(B)
                      |     handempty         |    ~clear(C)
                      |                       |
                      |         clear(C)      |
                      |------------------------
  25. No open preconditions and no threats, so halt. The only consistent total ordering that is implied from the final complete partial-order plan is: Unstack(C,A), Putdown(C), Pickup(B), Stack(B,C), Pickup(A), Stack(A,B). Notice that this interleaves the steps in the solutions to the two original goals, on(A,B) and on(B,C).

Copyright © 1996-2003 by Charles R. Dyer. All rights reserved.