200 $\\approx$ 10405\n",
+ "- minimum number of actions 50 x 9 =450 (all cargo located on airport with no planes)\n",
+ "- maximum number of actions 50200 x 9 $\\approx$ 10340 (all cargo and aircrafts in one airport)\n",
+ "\n",
+ "Practically: The number of particles in the universe is about **_1087_**.\n",
+ "\n",
+ "That is where automated planning research comes in to solve such problems using classical planning (or other algorithms)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#####For now we will stick to the example from the book from Fig. 10.1:\n",
+ "\n",
+ "\n",
+ "To define a problem we have to define an initial state (predicates which are true at the beginning of the problem) and a goal state (predicates which are true at the end of the problem). \n",
+ "\n",
+ "\n",
+ "The following code defines the initial state for the problem\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def air_cargo():\n",
+ " init = [expr('At(C1, SFO)'), \n",
+ " expr('At(C2, JFK)'),\n",
+ " expr('At(P1, SFO)'),\n",
+ " expr('At(P2, JFK)'),\n",
+ " expr('Cargo(C1)'),\n",
+ " expr('Cargo(C2)'),\n",
+ " expr('Plane(P1)'),\n",
+ " expr('Plane(P2)'),\n",
+ " expr('Airport(JFK)'),\n",
+ " expr('Airport(SFO)')]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "`init` defines the initial state of the problem.\n",
+ "\n",
+ "**`expr('At(C1, SF0)')`** represents the predicate **Cargo 1 at San Fransisco**\n",
+ "\n",
+ "**`expr('At(P1, SF0)')`** represents the predicate **Plane 1 at San Fransisco** ... and so on.\n",
+ "\n",
+ "\n",
+ "\n",
+ "The following code defines the goal_test() function which tests if the solution achieves goal or not. 'required' states the goal:"
+
"%psource Action"
+
]
},
{
@@ -322,12 +564,424 @@
},
{
"cell_type": "code",
- "execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "execution_count": 3,
+ "metadata": {},
"outputs": [],
- "source": []
+ "source": [
+ "def goal_test(kb):\n",
+ " required = [expr('At(C1 , JFK)'), expr('At(C2 ,SFO)')]\n",
+ " for q in required:\n",
+ " if kb.ask(q) is False:\n",
+ " return False\n",
+ " return True"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "For this problem the Goal is **`(At(C1 , JFK ) ∧ At(C2 , SFO))`** i.e., **Cargo 1 ar JFK and Cargo 2 at San Fransisco** which is written as:\n",
+ "\n",
+ "`required = [expr('At(C1 , JFK)'), expr('At(C2 ,SFO)')]`\n",
+ "\n",
+ "The function `goal_test(kb)` takes a knowledge base as argument, and for every predicate in `required` (goal), it checks the `ask` function from `KB class`. The `ask` function returns value `True` or `False` accordingly if predicate in `required` meets preconditions or not (defined ahead).\n",
+ "\n",
+ "\n",
+ "Actions such as 'load', 'unload' and fly are defined with preconditions and effects accompanying them."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Actions\n",
+ "# Load\n",
+ "precond_pos = [expr(\"At(c, a)\"), expr(\"At(p, a)\"), expr(\"Cargo(c)\"), expr(\"Plane(p)\"), expr(\"Airport(a)\")]\n",
+ "precond_neg = []\n",
+ "effect_add = [expr(\"In(c, p)\")]\n",
+ "effect_rem = [expr(\"At(c, a)\")]\n",
+ "load = Action(expr(\"Load(c, p, a)\"), [precond_pos, precond_neg], [effect_add, effect_rem])\n",
+ "\n",
+ "# Unload\n",
+ "precond_pos = [expr(\"In(c, p)\"), expr(\"At(p, a)\"), expr(\"Cargo(c)\"), expr(\"Plane(p)\"), expr(\"Airport(a)\")]\n",
+ "precond_neg = []\n",
+ "effect_add = [expr(\"At(c, a)\")]\n",
+ "effect_rem = [expr(\"In(c, p)\")]\n",
+ "unload = Action(expr(\"Unload(c, p, a)\"), [precond_pos, precond_neg], [effect_add, effect_rem])\n",
+ "\n",
+ "# Fly\n",
+ "# Used 'f' instead of 'from' because 'from' is a python keyword and expr uses eval() function\n",
+ "precond_pos = [expr(\"At(p, f)\"), expr(\"Plane(p)\"), expr(\"Airport(f)\"), expr(\"Airport(to)\")]\n",
+ "precond_neg = []\n",
+ "effect_add = [expr(\"At(p, to)\")]\n",
+ "effect_rem = [expr(\"At(p, f)\")]\n",
+ "fly = Action(expr(\"Fly(p, f, to)\"), [precond_pos, precond_neg], [effect_add, effect_rem])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "`precond_` is used to denote predicates which must be True **before** the action.\n",
+ "eg: \n",
+ "\n",
+ "`effect_` is used to denote predicates which must be True **after** the action.\n",
+ "\n",
+ "`precon_pos` & `effect_add` are used to denote predicates which must be **True**.\n",
+ "\n",
+ "`precon_neg` & `effect_rem` are used to denote predicates which must be **False**.\n",
+ "\n",
+ "\n",
+ "Eg: in Action `load`\n",
+ "\n",
+ "`precond_pos = [expr(\"At(c, a)\"), expr(\"At(p, a)\"), expr(\"Cargo(c)\"), expr(\"Plane(p)\"), expr(\"Airport(a)\")]` is a precondition which must be **True** denoting predicate _Cargo c at Airport a & Plane p at Airport a_.\n",
+ "\n",
+ "`precond_neg = []` is a precondition which must be **False**. \t\t\t\n",
+ "\n",
+ "`effect_add = [expr(\"In(c, p)\")]` is an effect which must be **True** denoting the predicate _Cargo c in Plane p_.\n",
+ "\n",
+ "`effect_rem = [expr(\"At(c, a)\")]`is an effect which must be **False** denoting the predicate _Cargo c at Airport a_.\n",
+ "\n",
+ "`load = Action(expr(\"Load(c, p, a)\"), [precond_pos, precond_neg], [effect_add, effect_rem])` thus define the action **`Load(c, p, a)** with the preconditions it must follow and the effects it leads to.\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "\n",
+ "Finally, the function returns the defined problem using PDLL.\n",
+ "\n",
+ "`return(PDLL(init, [load, unload, fly], goal_test)`\n",
+ "\n",
+ " which defines the problem as a whole with its initial state (`init`), the actions possible(` [load, unload, fly]`) and the goal(`goal_test`)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "A solution to the air_cargo problem is as follows:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "solution = [expr(\"Load(C1 , P1, SFO)\"),\n",
+ " expr(\"Fly(P1, SFO, JFK)\"),\n",
+ " expr(\"Unload(C1, P1, JFK)\"),\n",
+ " expr(\"Load(C2, P2, JFK)\"),\n",
+ " expr(\"Fly(P2, JFK, SFO)\"),\n",
+ " expr(\"Unload (C2, P2, SFO)\")]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "where `expr(\"Load(C1 , P1, SFO)\")` means _load the Cargo C1 in Plane P1 at San Fransico_. In order for this action to take place the preconditions we specified while defining the action `Load` must be met. The effects from this action are then carried forward i.e., they now are an existing state and it should be sought that these effects do **not** clash with preconditions of actions ahead, otherwise the action can't be completed. \n",
+ "\n",
+ "Following lines describe the _plan_ of the above solution:\n",
+ "\n",
+ "`expr(\"Load(C1 , P1, SFO)\") ` --> _Load Cargo C1 in Plane P1 at San Fransico_\n",
+ "\n",
+ "`expr(\"Fly(P1, SFO, JFK)\")` --> _Fly Plane P1 from San Fransisco to JFK_\n",
+ "\n",
+ "`expr(\"Unload(C1, P1, JFK)\")` --> _Unload Cargo C1 from Plane P1 at JFK_\n",
+ "\n",
+ "`expr(\"Load(C2, P2, JFK)\")` --> _Load Cargo C2 in Plane P2 at JFK_\n",
+ "\n",
+ "`expr(\"Fly(P2, JFK, SFO)\")` --> _Fly Plane P2 from JFK to San Fransisco_\n",
+ "\n",
+ "`expr(\"Unload (C2, P2, SFO)\")` --> _Unload Cargo C2 from Plane P2 at San Fransisco_\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "We then execute the action on the state's kb."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "a = air_cargo()\n",
+ "\n",
+ "for action in solution:\n",
+ " a.act(action)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "where each action is acted upon leading to a state which is tested below to be the goal state or not."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "a.goal_test()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Yes, the solution is correct. You may try any other solution to check if it achieves the goal or not."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Another related example - The Dock-Worker Robots (DWR) Domain\n",
+ "\n",
+ "It is specifically an example of automated planning, with the following scenario:\n",
+ "- harbour with several locations (docs)\n",
+ "- docked ships\n",
+ "- storage area for containers\n",
+ "- parking area for trains, trucks\n",
+ "\n",
+ "- Goal: \n",
+ " \t1. cranes to load and unload ships\n",
+ " \t2. robot carts to move around containers\n",
+ "\n",
+ "Like the air cargo transport problem, the actions can be sought to be **put, take, load, unload, move**.\n",
+ "\n",
+ "The following figure depicts a simple instance of the problem where the initial state is S0 (robot at location 2 and container on pallet in location 1) and the goal state is S5 (container on robot at location 2).
The state transitions are accompanied by the following actions:\n",
+ "\n",
+ "- S0 (robot at location 2 and container on pallet in location 1) -- **initial state**; `At(robot, location2), At(container, location1), At(container, pallet)`\n",
+ "- S1 (robot at location 2 and container on crane in location 1) -- action `take(crane, container)` \n",
+ "- S2 (robot at location 1 and container on pallet in location 1) -- action `move(location2, location1), put(container, pallet)`\n",
+ "- S3 (robot at location 1 and container on crane in location 1) -- action `take(crane, container)`\n",
+ "- S4 (robot at location 1 and container on robot in location 1) -- action `load(robot, container)`\n",
+ "- S5 (robot at location 2 and container on robot in location 2) -- action `move(location1, location2)` ; **goal state**\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# SPARE TIRE PROBLEM from Figure 10.2:\n",
+ "\n",
+ "The Spare Tire problem is to replace a flat tire on axle with a spare one. \n",
+ "\n",
+ "The problem follows the same structure of function as before, only the predicates are changed.\n"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "init = [expr('Tire(Flat)'),\n",
+ " expr('Tire(Spare)'),\n",
+ " expr('At(Flat, Axle)'),\n",
+ " expr('At(Spare, Trunk)')]\n",
+ "\n",
+ "\n",
+ "required = [expr('At(Spare, Axle)'), expr('At(Flat, Ground)')]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "`init ` states the initial state:\n",
+ "\n",
+ "`expr('Tire(Flat)')` --> _Flat Tire_\n",
+ "\n",
+ "`expr('Tire(Spare)')` --> _Spare Tire_\n",
+ "\n",
+ "`expr('At(Flat, Axle)')` --> _Flat Tire on Axle_\n",
+ "\n",
+ "`expr('At(Spare, Trunk)')` --> _Spare Tire in Trunk_\n",
+ "\n",
+ "\n",
+ "`required = [expr('At(Spare, Axle)'), expr('At(Flat, Ground)')]` states the goal i.e., _Spare tire must be on Axle, and Flat tire on Ground_\n",
+ "\n",
+ "Just a sidenote, the action `At()` means same as _on, in, at_ in the problem reference."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "# Actions\n",
+ "\n",
+ "# Remove\n",
+ "precond_pos = [expr(\"At(obj, loc)\")]\n",
+ "precond_neg = []\n",
+ "effect_add = [expr(\"At(obj, Ground)\")]\n",
+ "effect_rem = [expr(\"At(obj, loc)\")]\n",
+ "remove = Action(expr(\"Remove(obj, loc)\"), [precond_pos, precond_neg], [effect_add, effect_rem])\n",
+ "\n",
+ "# PutOn\n",
+ "precond_pos = [expr(\"Tire(t)\"), expr(\"At(t, Ground)\")]\n",
+ "precond_neg = [expr(\"At(Flat, Axle)\")]\n",
+ "effect_add = [expr(\"At(t, Axle)\")]\n",
+ "effect_rem = [expr(\"At(t, Ground)\")]\n",
+ "put_on = Action(expr(\"PutOn(t, Axle)\"), [precond_pos, precond_neg], [effect_add, effect_rem])\n",
+ "\n",
+ "# LeaveOvernight\n",
+ "precond_pos = []\n",
+ "precond_neg = []\n",
+ "effect_add = []\n",
+ "effect_rem = [expr(\"At(Spare, Ground)\"), expr(\"At(Spare, Axle)\"), expr(\"At(Spare, Trunk)\"),\n",
+ " expr(\"At(Flat, Ground)\"), expr(\"At(Flat, Axle)\"), expr(\"At(Flat, Trunk)\")]\n",
+ "leave_overnight = Action(expr(\"LeaveOvernight\"), [precond_pos, precond_neg],\n",
+ " [effect_add, effect_rem])"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The problem involves 3 actions:\n",
+ "\n",
+ "1. `Remove(obj, loc)` --> Remove object _obj_ from location _loc_.\n",
+ "2. `PutOn(t, Axle)` --> Put tire_t_ on _Axle_\n",
+ "3. `Leaveovernight` --> Leave tire overnight _(we assume the neighbourhood is good and we find the tire at the same place the next day)_"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "solution to the spare tire problem from the book is as follows:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "solution = [expr(\"Remove(Flat, Axle)\"),\n",
+ " expr(\"Remove(Spare, Trunk)\"),\n",
+ " expr(\"PutOn(Spare, Axle)\")]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Following lines describe the _plan_ of the above solution:\n",
+ "\n",
+ "`expr(\"Remove(Flat, Axle)\")` --> _Remove Flat tire from Axle_\n",
+ "\n",
+ "`expr(\"Remove(Spare, Trunk)\")` --> _Remove Spare tire from Trunk_\n",
+ "\n",
+ "`expr(\"PutOn(Spare, Axle)\")` --> _Put Spare tire on Axle_\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "let's test it in the same way as before :"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "s = spare_tire()\n",
+ "\n",
+ "for action in solution:\n",
+ " s.act(action)\n",
+ "\n",
+ "s.goal_test()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The solution achieves the goal."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# THE BLOCKS WORLD from Figure 10.3 :"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ " The above image below shows the transitions between different states which are possible for 3 blocks. Watch how the rightmost transition is what we follow in the book.
"
+ ]
}
],
"metadata": {
@@ -339,7 +993,7 @@
"language_info": {
"codemirror_mode": {
"name": "ipython",
- "version": 3
+ "version": 3.0
},
"file_extension": ".py",
"mimetype": "text/x-python",
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy