diff --git a/images/blocks_world.png b/images/blocks_world.png
new file mode 100644
index 000000000..cc772ae36
Binary files /dev/null and b/images/blocks_world.png differ
diff --git a/learning.ipynb b/learning.ipynb
index 78ff4f0e3..32a8c64ca 100644
--- a/learning.ipynb
+++ b/learning.ipynb
@@ -1168,7 +1168,7 @@
"cell_type": "code",
"execution_count": 13,
"metadata": {
- "collapsed": false,
+ "collapsed": true,
"deletable": true,
"editable": true
},
@@ -1518,7 +1518,7 @@
"language_info": {
"codemirror_mode": {
"name": "ipython",
- "version": 3
+ "version": 3.0
},
"file_extension": ".py",
"mimetype": "text/x-python",
@@ -1529,5 +1529,5 @@
}
},
"nbformat": 4,
- "nbformat_minor": 2
-}
+ "nbformat_minor": 0
+}
\ No newline at end of file
diff --git a/logic.ipynb b/logic.ipynb
index 079f1170b..7c12d7c66 100644
--- a/logic.ipynb
+++ b/logic.ipynb
@@ -306,11 +306,11 @@
"|--------------------------|----------------------|-------------------------|---|---|\n",
"| Negation | ¬ P | `~P` | `~P` | `Expr('~', P)`\n",
"| And | P ∧ Q | `P & Q` | `P & Q` | `Expr('&', P, Q)`\n",
- "| Or | P ∨ Q | `P` | `Q`| `P` | `Q` | `Expr('`|`', P, Q)`\n",
+ "| Or | P ∨ Q | `P` | `Q`| `P` | `Q` | `Expr('`|`', P, Q)\n",
"| Inequality (Xor) | P ≠ Q | `P ^ Q` | `P ^ Q` | `Expr('^', P, Q)`\n",
"| Implication | P → Q | `P` |`'==>'`| `Q` | `P ==> Q` | `Expr('==>', P, Q)`\n",
"| Reverse Implication | Q ← P | `Q` |`'<=='`| `P` |`Q <== P` | `Expr('<==', Q, P)`\n",
- "| Equivalence | P ↔ Q | `P` |`'<=>'`| `Q` |`P <=> Q` | `Expr('<=>', P, Q)`\n",
+ "| Equivalence | P ↔ Q | `P` |`'<=>'`| `Q` |`P ==> Q` | `Expr('==>', P, Q)`\n",
"\n",
"Here's an example of defining a sentence with an implication arrow:"
]
@@ -412,6 +412,7 @@
"\n",
"The class `PropKB` can be used to represent a knowledge base of propositional logic sentences.\n",
"\n",
+ "\n",
"We see that the class `KB` has four methods, apart from `__init__`. A point to note here: the `ask` method simply calls the `ask_generator` method. Thus, this one has already been implemented and what you'll have to actually implement when you create your own knowledge base class (if you want to, though I doubt you'll ever need to; just use the ones we've created for you), will be the `ask_generator` function and not the `ask` function itself.\n",
"\n",
"The class `PropKB` now.\n",
@@ -425,67 +426,367 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "# TODO: More on KBs, plus what was promised in Intro Section\n",
+ "The following gives an idea how the python code works in logic.py:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "KB = PropKB()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "creates an empty knowledge base"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 16,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "KB.tell(A & C)\n",
+ "KB.ask(A) == KB.ask(C) == {}"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "adds sentence and checks if KB entails the query."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "False"
+ ]
+ },
+ "execution_count": 17,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "KB.ask(E)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "{}"
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "KB.tell(E)\n",
+ "KB.ask(E)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "False"
+ ]
+ },
+ "execution_count": 19,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "KB.retract(C)\n",
+ "KB.ask(C)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "removes all clauses of 'C' from the sentence."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
"\n",
- "TODO: fill in here ..."
+ "# The truth table enumeration algorithm from Figure 7.10:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def tt_entails(kb, alpha):\n",
+ " \n",
+ " assert not variables(alpha)\n",
+ " return tt_check_all(kb, alpha, prop_symbols(kb & alpha), {})"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "## Appendix: The Implementation of `|'==>'|`\n",
+ "Example:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 21,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tt_entails(expr('P & Q'), expr('Q'))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The tt_entail algorithm makes use of the tt_check_all() function, which gives results in the following manner. "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 22,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "tt_check_all(expr('P & Q'), expr('Q'), prop_symbols(expr('Q')), {})"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "prop_symbols() is used to give the function argument in the form of symbols."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Example of the DPLL algorithm from Figure 7.17:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{B: True, A: True}\n{P: True}\n{P: True}\n{P: False}\n"
+ ]
+ }
+ ],
+ "source": [
+ "print (dpll_satisfiable(expr('A & B')))\n",
"\n",
- "Consider the `Expr` formed by this syntax:"
+ "print (dpll_satisfiable(expr('P | Q')))\n",
+ "\n",
+ "print (dpll_satisfiable(expr('P | ~Q')))\n",
+ "\n",
+ "print (dpll_satisfiable(expr('~P | Q')))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Example of the WalkSAT algorithm from Figure 7.18:"
]
},
{
"cell_type": "code",
- "execution_count": 15,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 24,
+ "metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "(P ==> ~Q)"
+ "{C: True, B: True, A: True}"
]
},
- "execution_count": 15,
+ "execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
- "P |'==>'| ~Q"
+ "WalkSAT([A & B, A & C], 0.5, 100 )"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
- "What is the funny `|'==>'|` syntax? The trick is that \"`|`\" is just the regular Python or-operator, and so is exactly equivalent to this: "
+ "# Example of the SATplan algorithm from Figure 7.22:"
]
},
{
"cell_type": "code",
- "execution_count": 16,
- "metadata": {
- "collapsed": false
- },
+ "execution_count": 25,
+ "metadata": {},
"outputs": [
{
"data": {
"text/plain": [
- "(P ==> ~Q)"
+ "['Left', 'Left']"
]
},
- "execution_count": 16,
+ "execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
+ "source": [
+ "transition = {'A': {'Left': 'A', 'Right': 'B'},\n",
+ " 'B': {'Left': 'A', 'Right': 'C'},\n",
+ " 'C': {'Left': 'B', 'Right': 'C'}}\n",
+ "\n",
+ "SAT_plan('C', transition, 'A', 3)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# unify() algorithm from Figure 9.1:\n",
+ "\n",
+ " Returns a substitution to make the first 2 arguments identical, and the third argument is the substitution built up so far."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "{x: 2}\n"
+ ]
+ }
+ ],
+ "source": [
+ "print(unify(x, 2, {}))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# TODO: More on KBs, plus what was promised in Intro Section\n",
+ "\n",
+ "TODO: fill in here ..."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Appendix: The Implementation of `|'==>'|`\n",
+ "\n",
+ "Consider the `Expr` formed by this syntax:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 27,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
+ "source": [
+ "P |'==>'| ~Q"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "What is the funny `|'==>'|` syntax? The trick is that \"`|`\" is just the regular Python or-operator, and so is exactly equivalent to this: "
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 28,
+ "metadata": {
+ "collapsed": false
+ },
+ "outputs": [],
"source": [
"(P | '==>') | ~Q"
]
@@ -499,7 +800,7 @@
},
{
"cell_type": "code",
- "execution_count": 17,
+ "execution_count": 29,
"metadata": {
"collapsed": false
},
@@ -510,7 +811,7 @@
"PartialExpr('==>', P)"
]
},
- "execution_count": 17,
+ "execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
@@ -530,7 +831,7 @@
},
{
"cell_type": "code",
- "execution_count": 18,
+ "execution_count": 30,
"metadata": {
"collapsed": false
},
@@ -541,7 +842,7 @@
"(P ==> ~Q)"
]
},
- "execution_count": 18,
+ "execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
@@ -571,7 +872,7 @@
},
{
"cell_type": "code",
- "execution_count": 19,
+ "execution_count": 31,
"metadata": {
"collapsed": false
},
@@ -582,7 +883,7 @@
"(~(P & Q) ==> (~P | ~Q))"
]
},
- "execution_count": 19,
+ "execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
@@ -600,7 +901,7 @@
},
{
"cell_type": "code",
- "execution_count": 20,
+ "execution_count": 32,
"metadata": {
"collapsed": false
},
@@ -611,7 +912,7 @@
"(~(P & Q) ==> (~P | ~Q))"
]
},
- "execution_count": 20,
+ "execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
@@ -630,7 +931,7 @@
},
{
"cell_type": "code",
- "execution_count": 21,
+ "execution_count": 33,
"metadata": {
"collapsed": false
},
@@ -641,7 +942,7 @@
"(((P & Q) ==> P) | Q)"
]
},
- "execution_count": 21,
+ "execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
@@ -659,7 +960,7 @@
},
{
"cell_type": "code",
- "execution_count": 22,
+ "execution_count": 34,
"metadata": {
"collapsed": false
},
@@ -670,7 +971,7 @@
"((P & Q) ==> (P | Q))"
]
},
- "execution_count": 22,
+ "execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
@@ -701,16 +1002,16 @@
"language_info": {
"codemirror_mode": {
"name": "ipython",
- "version": 3
+ "version": 3.0
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.4.3"
+ "version": "3.5.1"
}
},
"nbformat": 4,
"nbformat_minor": 0
-}
+}
\ No newline at end of file
diff --git a/logic.py b/logic.py
index 68d996c14..ff5e6f09b 100644
--- a/logic.py
+++ b/logic.py
@@ -847,20 +847,22 @@ def subst(s, x):
def fol_fc_ask(KB, alpha):
"""A simple forward-chaining algorithm. [Figure 9.3]"""
- while new is not None:
+ while True:
new = []
- for rule in KB:
+ for rule in KB.clauses:
p, q = parse_definite_clause(standardize_variables(rule))
- for p_ in random.KB.clauses:
+ for p_ in KB.clauses:
if p != p_:
for theta in (subst(theta, p) == subst(theta, p_)):
q_ = subst(theta, q)
- if not unify(q_,KB.sentence in KB) or not unify(q_, new):
+ if not unify(q_,KB.sentence in KB) or not unify(q_, new):
new.append(q_)
phi = unify(q_,alpha)
if phi is not None:
return phi
KB.tell(new)
+ if new is None:
+ break
return None
diff --git a/planning.ipynb b/planning.ipynb
index d5a5eb25d..091a1c916 100644
--- a/planning.ipynb
+++ b/planning.ipynb
@@ -1,24 +1,504 @@
{
"cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## PLANNING"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "This notebook describes the planning.py module, which covers Classical Planning from Chapter 10 & Planning & Acting in Real World Chapter 11."
+ ]
+ },
{
"cell_type": "code",
- "execution_count": null,
+ "execution_count": 1,
"metadata": {
"collapsed": false
},
"outputs": [],
"source": [
- "import planning"
+ "from planning import *\n",
+ "from utils import expr"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#PDDL \n",
+ "The PDDL (Planning Domain Definition Language) allows us to express all actions with one action schema,\n",
+ "\n",
+ "The `PDDL class` include:"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "1. **`init(self, initial_state, actions, goal_test)`**: the constructor creates a knowledge base with initial state, initialises actions and `goal_test_func` function with `goal_test`.\n",
+ "2. **`goal_test(self)`**: initialises `goal_test` with `kb`.\n",
+ "3. **`act(self, action)`**: performs the action given as argument, along with checks preformed on pre-conditions."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "PDDL is a domain definition language. It is used to define the properties of a domain, the predicates which are used and the action definition. A predicate defines the property of an object which can be true or false, e.g. yellow t-shirt. Yellow is the property and t-shirt is the object. "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#ACTIONS\n",
+ "Actions are described by a set of action schemas that implicitly define the class Actions:\n",
+ "Actions consists of a precondition(positive and negative) and effect(positive and negative). It consists of following "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Each problem described in chapter 10 has:\n",
+ "- an initial state\n",
+ "- a goal\n",
+ "- actions with preconditions and effects (these action are split into _pos (positive conditions) and _neg (negative conditions))\n",
+ "Each problem thus requires a solution which is satisfied by some initial conditions and solved using actions which meet the preconditions and effects.\n",
+ " "
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# AIR CARGO PROBLEM from Figure 10.1\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"
+ ]
+ },
+ {
+ "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"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "The following code defines the goal_test() function which tests if the solution achieves goal or not. 'required' states the goal:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [],
+ "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)."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "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": [
+ "\n",
+ "`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"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "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_."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "`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."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Finally, the function returns the defined problem using PDLL."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "`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"
+ ]
+ },
+ {
+ "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": [
+ ""
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# SPARE TIRE PROBLEM from Figure 10.2:\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": "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": [
+ "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": [
+ "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.\n",
+ "\n",
+ ""
]
},
{
"cell_type": "code",
"execution_count": null,
- "metadata": {
- "collapsed": true
- },
+ "metadata": {},
"outputs": [],
- "source": []
+ "source": [
+ ""
+ ]
}
],
"metadata": {
@@ -30,7 +510,7 @@
"language_info": {
"codemirror_mode": {
"name": "ipython",
- "version": 3
+ "version": 3.0
},
"file_extension": ".py",
"mimetype": "text/x-python",
@@ -42,4 +522,4 @@
},
"nbformat": 4,
"nbformat_minor": 0
-}
+}
\ No newline at end of file
diff --git a/planning.py b/planning.py
index b92cb6eaa..5c0215cc5 100644
--- a/planning.py
+++ b/planning.py
@@ -557,12 +557,11 @@ def goal_test(kb):
return False
return True
- # Actions
-
- # Hit
- precond_pos = [expr("Approaching(Ball,loc)"), expr("At(actor,loc)")]
- precond_neg = []
- effect_add = [expr("Returned(Ball)")]
+ ##actions
+ #hit
+ precond_pos=[expr("Approaching(Ball, loc)"), expr("At(actor, loc)")]
+ precond_neg=[]
+ effect_add=[expr("Returned(Ball)")]
effect_rem = []
hit = Action(expr("Hit(actor, Ball)"), [precond_pos, precond_neg], [effect_add, effect_rem])
@@ -573,4 +572,4 @@ def goal_test(kb):
effect_rem = [expr("At(actor, loc)")]
go = Action(expr("Go(actor, to)"), [precond_pos, precond_neg], [effect_add, effect_rem])
- return PDLL(init, [hit, go], goal_test)
+ return PDLL(init, [hit, go], goal_test)
\ No newline at end of file