I know this is an old post, but I bashed my head against this wall for a long time and hope what I learned will save someone else the time.
In broad strokes, an HTN solves a problem using a very human planning approach that centers on abstraction and alternatives.
Alternatives: Let’s use a travel example from the famous SHOP HTN Planner (http://www.cs.umd.edu/projects/shop/description.html). Imagine you asked me how to get from downtown to the park. I might say, “Well, it is 2Km away but, if it is nice out, I would just walk it. However, if it is raining and you’ve got taxi fare, I’d take the taxi. Otherwise, if you have bus fare, just take a bus.” A abstract thing you accomplish like “travelling from one place to another” is known in HTNs as a “Task”. The 3 alternatives I gave for accomplishing it are known as “Methods” in HTNs. Note that each Method had a “Condition” that went with it: walk if it is nice out, take a taxi if you have the fare, etc.
Abstraction: Note that these 3 Methods are at a pretty high level of abstraction. You might further ask me how to accomplish the “TakeABus” Method. I’d say something like, “Well, wait for the #1 bus at the ‘Downtown’ bus stop, pay the driver $1, and ride it to the ‘Park’ stop.” These three tasks are known in HTNs as “Subtasks” of the “TakeABus” Method. In HTNs, Methods do what they do by decomposing into Subtasks. Now, this is a pretty complete answer for a human but maybe not if we were talking to a robot. In that case we might need to further decompose the task of “PayTheDriver$1” into something like “Reach into your pocket, grab a $1 bill, hand to driver”. Each of those could further be decomposed until we finally have something a robot could do. The final step of an HTN, the part that actually gets done, is called an “Operator”. How detailed you need to get before you are done (and have an Operator) depends on the kind of system you are building. A big part of designing an HTN model is getting your head around what the right abstractions are.
So, HTNs have these parts:
State of the world: You are downtown. Taxi fare is $2. Bus fare is $1. Distance from downtown to park is 2Km.
Tasks: What can be done abstractly in the world (there may be several ways to do it!): Travel from A to B. Walk from A to B. Pay a Driver X$. Wait for bus A at stop B.
Operators: How to accomplish abstract Tasks when they can “just be done” without further explanation. They actually modify the State of the world. If you are human these might be Operators: Pay the driver $1, Ride #1 bus to the 'Park' stop. If you are a robot, these might be: Move stepper motor forward by 100 steps, turn on spotlight
Methods: How to accomplish abstract Tasks when they involve several steps or more detailed plans. They have a Condition for when they can be used and a set of Subtasks for how to accomplish them: METHOD: "Travel from A to B" CONDITION: the weather is bad and you have bus fare, SUBTASKS: Wait for the bus at the bus stop, pay the driver, and ride it to the stop
The algorithm itself is pretty simple. You start with a Task or Goal list like Go from downtown to the park and an empty Plan list:
- Remove and start with the first goal in the Goal List
- See if there is an Operator that knows how to do it. If so, add the Operator to the end of the Plan List (since Operators can “just be done”) and continue at #1
- See if there are Methods that know how to do it. If so, add their Subtasks to the front of our Goal List and continue at #1 If there are multiple Methods, duplicate the current state of the world and run the algorithm with each, independently. Each that completes successfully will be a different solution
- Repeat until the Goal List is empty
- When done, what you have in the Plan List is the solution
I've got a blog series that goes over this in pretty good detail including source code and more examples if you want more detail: https://blog.inductorsoftware.com/blog/htnoverview