In this homework assignment, you will translate a wikiHow article into the Planning Domain Definition Language (PDDL) format that we explored in our in-class activity on planning and PDDL. We’ll also ask you to write your thoughts about how large LMs could be used to automatically generate plans from wikiHow-style instructions.
Here’s an overview of what you’ll do:
We’ll use create our PDDL files from a wikiHow article. The goal for this is to start from something that describes proceedures and actions and is written in natural language, and then to manually translate it into the description language used for automated planning.
Here are a few wikiHow articles that I thought might be interesting since they had some elements that could make for interesting interactive fiction. It’s fine to pick your own article. We won’t translate the whole article, just a few steps, so you can pick out the parts that you think are most relevant / easiest to create action schema from.
As an example, I’ll pick the How to Survive in the Woods article, and work on translating Part 1, Step 1 into PDDL. Here is step 1 from that article:
Finding Drinking Water
Search for a source of fresh water. The first thing that you’ll need in order to survive in the woods is water that you can drink. Look for signs of fresh water nearby like areas of green foliage that indicate water is nearby, low-lying areas where water could be collected, and signs of wildlife like animal tracks. It could mean that a creek, stream, or pond is nearby. While finding water is important for survival, be aware some water sources will not be safe - if possible treat all drinking water before using it.  If there are mountains nearby, look for water collected at the foot of the cliffs.
- The presence of insects like mosquitoes and flies means that water is nearby.
- Water from heavily oxygenated water (such as from a big waterfall or rapids) typically is safer than that from a slow or still water source.
- Freshwater springs are typically safer water sources, although these can be contaminated by mineral or bacteria as well.
- Remember that all untreated water must be considered risky unless treated. Even crystal clear water can harbor diseases and be dangerous if consumed.
You should create PDDL files for:
domain.pddlfile which defines the domain, including the types, predicates and action schemata that are relevant to your wikiHow article.
The name of your domain should be the aricle title. I have started defining a domain for
(define (domain survive_in_the_woods) (:requirements :strips :typing) ...
I’ll create a problem file for Step 1 in the article. I’ll name the problem
collect_water and I’ll define the goal as
(:goal (and (inventory npc water)) where the player (or an AI-controled non-playable character, abbreviated as NPC) needs to add water to their inventory.
Here’s what the start and end of the problem PDDL file would look like:
(define (problem collect_water) (:domain survive_in_the_woods) ... (:goal (and (inventory npc water)))
You should specify what the
types are in your domain. They should be the things that are relevant to solving the problem that you’re tackling. It’s sometimes also useful to create subtypes. Which you can do like this:
(:types water - item player direction location )
By default all types are subtypes of
object. The line
water - item
allows us to define
water as a subtype of
item is also introduced as a type in this same line). Having
water as a subtype allows us to restrict some action schemas to only operate on that type.
Here’s an example of an action schema for getting items:
(:action get :parameters (?item - item ?p - player ?l1 - location) :precondition (and (at ?p ?l1) (at ?item ?l1)) :effect (and (inventory ?p ?item) (not (at ?item ?l1))) )
It has the effect or removing the item from the current location and putting it into the player’s inventory.
We might add a seperate action for getting water, since when our player gets some water from a lake, the water shouldn’t be removed from that location. Here’s one way to write it:
(:action get_water :parameters (?p - player ?loc - location ?water - water) :precondition (and (at ?p ?loc) (has_water_source ?loc)) :effect (and (inventory ?p ?water) (not (treated ?water))) )
(We might also consider adding some additional preconditions, like that the player has a container to store their water in).
In your PDDL domain file, please define your predicates like this:
(:predicates (has_water_source ?loc - location) ; this location has a source of fresh water. (treated ?water - water) ; True if the water has been decontaimated by boiling it ... )
You should give the type of each predicate’s arguments, and a comment about what the predicate means (everything after the
; is a comment).
Here’s an example of how I started the
(define (domain survive_in_the_woods) (:requirements :strips :typing) (:types water - item player direction location ) (:predicates (has_water_source ?loc - location) ; this location has a source of fresh water. (treated ?water - water) ; True if the water has been decontaimated by boiling it (at ?obj - object ?loc - location) ; an object is at a location (inventory ?player ?item) ; an item is in the player's inventory (connected ?loc1 - location ?dir - direction ?loc2 - location) ; location 1 is connected to location 2 in the direction (blocked ?loc1 - location ?dir - direction ?loc2 - location) ; the connection between location 1 and 2 in currently blocked ) (:action go ; navigate to an adjacent location :parameters (?dir - direction ?p - player ?l1 - location ?l2 - location) :precondition (and (at ?p ?l1) (connected ?l1 ?dir ?l2) (not (blocked ?l1 ?dir ?l2))) :effect (and (at ?p ?l2) (not (at ?p ?l1))) ) (:action get ; pick up an item and put it in the inventory :parameters (?item - item ?p - player ?l1 - location) :precondition (and (at ?p ?l1) (at ?item ?l1)) :effect (and (inventory ?p ?item) (not (at ?item ?l1))) ) (:action get_water ; get water from a location that has a water source like a lake. :parameters (?p - player ?loc - location ?water - water) :precondition (and (at ?p ?loc) (has_water_source ?loc)) :effect (and (inventory ?p ?water) (not (treated ?water))) ) )
Here’s how I specified the problem of collecting water from a source like a waterfall.
I instantiated several objects, and specified an initial state with a goal of of
(inventory npc water).
(define (problem collect_water) (:domain survive_in_the_woods) (:objects npc - player waterfall camp path cliff - location in out north south east west up down - direction water - water ) (:init (connected camp west path) (connected path east camp) (connected path west cliff) (connected cliff east path) (connected cliff up waterfall) (connected waterfall down cliff) (at npc camp) (at canteen camp) (has_water_source waterfall) ) (:goal (and (inventory npc water))) )
Here’s a sequence of actions that reaches the goal:
go west npc camp path go west npc path cliff go up npc cliff waterfall get_water npc waterfall water
If the player wants to survive in the woods, other problems remain. For starters, their water still isn’t safe to drink! To fix that problem we could implement Step 6 of How to Survive in the Woods:
Purify any water that you find.
It’s extremely important that you purify any water that you collect, including rainwater, dew, and ice or snow, so you don’t consume bacteria that could make you ill or even kill you. Use a piece of cloth or clothing to strain the water to remove large particles, then boil the water for 10 minutes to kill any contaminants.
- If you don’t have a container to boil water in, you can fill a clear plastic bottle with water, seal the lid, and place the bottle on its side in direct sunlight for 6 hours to purify it.
- In the event that you have no containers and no way to purify water, you can dig a deep hole, let it fill with groundwater, and wait for the particles to settle at the bottom and the water is clear before you drink it. You should only do this if you have no other option.
I won’t give the details of how to implement this, but you can imagine extending our
survive_in_the_woods domain to add action schema for
purify_in_sunlight, and to create a new PDDL problem for
purify_water with the goal
(:goal (and (inventory npc water) (treated water))).
That in turn might require us to solve a problem like
create_a_fire in order to boil the water.
As a final step, you will annotate data and save a JSON file that links the phrases in the wikiHow article that you selected with the different elements of your PDDL elements.
If anyone is interested in doing a term project focused on automatically converting wikiHow to PDDL, then we’ll share this JSON data with your classmates.
You should submit the following:
Submissions should be done on Gradescope.