{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Planning\n",
    "#### Chapters 10-11\n",
    "----"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook serves as supporting material for topics covered in **Chapter 10 - Classical Planning** and **Chapter 11 - Planning and Acting in the Real World** from the book *[Artificial Intelligence: A Modern Approach](http://aima.cs.berkeley.edu)*. \n",
    "This notebook uses implementations from the [planning.py](https://github.com/aimacode/aima-python/blob/master/planning.py) module. \n",
    "See the [intro notebook](https://github.com/aimacode/aima-python/blob/master/intro.ipynb) for instructions.\n",
    "\n",
    "We'll start by looking at `PlanningProblem` and `Action` data types for defining problems and actions. \n",
    "Then, we will see how to use them by trying to plan a trip from *Sibiu* to *Bucharest* across the familiar map of Romania, from [search.ipynb](https://github.com/aimacode/aima-python/blob/master/search.ipynb) \n",
    "followed by some common planning problems and methods of solving them.\n",
    "\n",
    "Let's start by importing everything from the planning module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 79,
   "metadata": {},
   "outputs": [],
   "source": [
    "from planning import *\n",
    "from notebook import psource"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CONTENTS\n",
    "\n",
    "**Classical Planning**\n",
    "- PlanningProblem\n",
    "- Action\n",
    "- Planning Problems\n",
    "    * Air cargo problem\n",
    "    * Spare tire problem\n",
    "    * Three block tower problem\n",
    "    * Shopping Problem\n",
    "    * Socks and shoes problem\n",
    "    * Cake problem\n",
    "- Solving Planning Problems\n",
    "    * GraphPlan\n",
    "    * Linearize\n",
    "    * PartialOrderPlanner\n",
    "<br>\n",
    "\n",
    "**Planning in the real world**\n",
    "- Problem\n",
    "- HLA\n",
    "- Planning Problems\n",
    "    * Job shop problem\n",
    "    * Double tennis problem\n",
    "- Solving Planning Problems\n",
    "    * Hierarchical Search\n",
    "    * Angelic Search"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PlanningProblem\n",
    "\n",
    "PDDL stands for Planning Domain Definition Language.\n",
    "The `PlanningProblem` class is used to represent planning problems in this module. The following attributes are essential to be able to define a problem:\n",
    "* an initial state\n",
    "* a set of goals\n",
    "* a set of viable actions that can be executed in the search space of the problem\n",
    "\n",
    "View the source to see how the Python code tries to realise these."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 80,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">class</span> <span class=\"nc\">PlanningProblem</span><span class=\"p\">:</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    Planning Domain Definition Language (PlanningProblem) used to define a search problem.</span>\n",
       "<span class=\"sd\">    It stores states in a knowledge base consisting of first order logic statements.</span>\n",
       "<span class=\"sd\">    The conjunction of these logical statements completely defines a state.</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">goals</span><span class=\"p\">,</span> <span class=\"n\">actions</span><span class=\"p\">):</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">init</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">convert</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">goals</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">convert</span><span class=\"p\">(</span><span class=\"n\">goals</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">actions</span> <span class=\"o\">=</span> <span class=\"n\">actions</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">convert</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">clauses</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Converts strings into exprs&quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">,</span> <span class=\"n\">Expr</span><span class=\"p\">):</span>\n",
       "            <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">)</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">clauses</span> <span class=\"o\">=</span> <span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">clauses</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"k\">try</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">clauses</span> <span class=\"o\">=</span> <span class=\"n\">conjuncts</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">except</span> <span class=\"ne\">AttributeError</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">clauses</span> <span class=\"o\">=</span> <span class=\"n\">clauses</span>\n",
       "\n",
       "        <span class=\"n\">new_clauses</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">clause</span> <span class=\"ow\">in</span> <span class=\"n\">clauses</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">op</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;~&#39;</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_clauses</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"s1\">&#39;Not&#39;</span> <span class=\"o\">+</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])))</span>\n",
       "            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_clauses</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">clause</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">new_clauses</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">goal_test</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Checks if the goals have been reached&quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">return</span> <span class=\"nb\">all</span><span class=\"p\">(</span><span class=\"n\">goal</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">init</span> <span class=\"k\">for</span> <span class=\"n\">goal</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">goals</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">act</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        Performs the action given as argument.</span>\n",
       "<span class=\"sd\">        Note that action is an Expr like expr(&#39;Remove(Glass, Table)&#39;) or expr(&#39;Eat(Sandwich)&#39;)</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>       \n",
       "        <span class=\"n\">action_name</span> <span class=\"o\">=</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">op</span>\n",
       "        <span class=\"n\">args</span> <span class=\"o\">=</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">args</span>\n",
       "        <span class=\"n\">list_action</span> <span class=\"o\">=</span> <span class=\"n\">first</span><span class=\"p\">(</span><span class=\"n\">a</span> <span class=\"k\">for</span> <span class=\"n\">a</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">actions</span> <span class=\"k\">if</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">==</span> <span class=\"n\">action_name</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">if</span> <span class=\"n\">list_action</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">raise</span> <span class=\"ne\">Exception</span><span class=\"p\">(</span><span class=\"s2\">&quot;Action &#39;{}&#39; not found&quot;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"n\">action_name</span><span class=\"p\">))</span>\n",
       "        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">list_action</span><span class=\"o\">.</span><span class=\"n\">check_precond</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "            <span class=\"k\">raise</span> <span class=\"ne\">Exception</span><span class=\"p\">(</span><span class=\"s2\">&quot;Action &#39;{}&#39; pre-conditions not satisfied&quot;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"p\">))</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">init</span> <span class=\"o\">=</span> <span class=\"n\">list_action</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">clauses</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(PlanningProblem)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `init` attribute is an expression that forms the initial knowledge base for the problem.\n",
    "<br>\n",
    "The `goals` attribute is an expression that indicates the goals to be reached by the problem.\n",
    "<br>\n",
    "Lastly, `actions` contains a list of `Action` objects that may be executed in the search space of the problem.\n",
    "<br>\n",
    "The `goal_test` method checks if the goal has been reached.\n",
    "<br>\n",
    "The `act` method acts out the given action and updates the current state.\n",
    "<br>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## ACTION\n",
    "\n",
    "To be able to model a planning problem properly, it is essential to be able to represent an Action. Each action we model requires at least three things:\n",
    "* preconditions that the action must meet\n",
    "* the effects of executing the action\n",
    "* some expression that represents the action"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The module models actions using the `Action` class"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 81,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">class</span> <span class=\"nc\">Action</span><span class=\"p\">:</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    Defines an action schema using preconditions and effects.</span>\n",
       "<span class=\"sd\">    Use this to describe actions in PlanningProblem.</span>\n",
       "<span class=\"sd\">    action is an Expr where variables are given as arguments(args).</span>\n",
       "<span class=\"sd\">    Precondition and effect are both lists with positive and negative literals.</span>\n",
       "<span class=\"sd\">    Negative preconditions and effects are defined by adding a &#39;Not&#39; before the name of the clause</span>\n",
       "<span class=\"sd\">    Example:</span>\n",
       "<span class=\"sd\">    precond = [expr(&quot;Human(person)&quot;), expr(&quot;Hungry(Person)&quot;), expr(&quot;NotEaten(food)&quot;)]</span>\n",
       "<span class=\"sd\">    effect = [expr(&quot;Eaten(food)&quot;), expr(&quot;Hungry(person)&quot;)]</span>\n",
       "<span class=\"sd\">    eat = Action(expr(&quot;Eat(person, food)&quot;), precond, effect)</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"n\">precond</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"p\">):</span>\n",
       "        <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"nb\">str</span><span class=\"p\">):</span>\n",
       "            <span class=\"n\">action</span> <span class=\"o\">=</span> <span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">op</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">args</span> <span class=\"o\">=</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">args</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">precond</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">convert</span><span class=\"p\">(</span><span class=\"n\">precond</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">effect</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">convert</span><span class=\"p\">(</span><span class=\"n\">effect</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"fm\">__call__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">act</span><span class=\"p\">(</span><span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"fm\">__repr__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"k\">return</span> <span class=\"s1\">&#39;{}({})&#39;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__class__</span><span class=\"o\">.</span><span class=\"vm\">__name__</span><span class=\"p\">,</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">))</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">convert</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">clauses</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Converts strings into Exprs&quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">,</span> <span class=\"n\">Expr</span><span class=\"p\">):</span>\n",
       "            <span class=\"n\">clauses</span> <span class=\"o\">=</span> <span class=\"n\">conjuncts</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">)):</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">clauses</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">op</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;~&#39;</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">clauses</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"s1\">&#39;Not&#39;</span> <span class=\"o\">+</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]))</span>\n",
       "\n",
       "        <span class=\"k\">elif</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">,</span> <span class=\"nb\">str</span><span class=\"p\">):</span>\n",
       "            <span class=\"n\">clauses</span> <span class=\"o\">=</span> <span class=\"n\">clauses</span><span class=\"o\">.</span><span class=\"n\">replace</span><span class=\"p\">(</span><span class=\"s1\">&#39;~&#39;</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Not&#39;</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">)</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">clauses</span> <span class=\"o\">=</span> <span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">)</span>\n",
       "\n",
       "            <span class=\"k\">try</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">clauses</span> <span class=\"o\">=</span> <span class=\"n\">conjuncts</span><span class=\"p\">(</span><span class=\"n\">clauses</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">except</span> <span class=\"ne\">AttributeError</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">pass</span>\n",
       "\n",
       "        <span class=\"k\">return</span> <span class=\"n\">clauses</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">substitute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">e</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Replaces variables in expression with their respective Propositional symbol&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">new_args</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">num</span><span class=\"p\">,</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">_</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "                <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">x</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">new_args</span><span class=\"p\">[</span><span class=\"n\">num</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">args</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"n\">e</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">new_args</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">check_precond</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Checks if the precondition is satisfied in the current state&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"nb\">list</span><span class=\"p\">):</span>\n",
       "            <span class=\"n\">kb</span> <span class=\"o\">=</span> <span class=\"n\">FolKB</span><span class=\"p\">(</span><span class=\"n\">kb</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">clause</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">precond</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">substitute</span><span class=\"p\">(</span><span class=\"n\">clause</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">)</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">kb</span><span class=\"o\">.</span><span class=\"n\">clauses</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">False</span>\n",
       "        <span class=\"k\">return</span> <span class=\"bp\">True</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">act</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Executes the action on the state&#39;s knowledge base&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"nb\">isinstance</span><span class=\"p\">(</span><span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"nb\">list</span><span class=\"p\">):</span>\n",
       "            <span class=\"n\">kb</span> <span class=\"o\">=</span> <span class=\"n\">FolKB</span><span class=\"p\">(</span><span class=\"n\">kb</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">check_precond</span><span class=\"p\">(</span><span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "            <span class=\"k\">raise</span> <span class=\"ne\">Exception</span><span class=\"p\">(</span><span class=\"s1\">&#39;Action pre-conditions not satisfied&#39;</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">clause</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">effect</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">kb</span><span class=\"o\">.</span><span class=\"n\">tell</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">substitute</span><span class=\"p\">(</span><span class=\"n\">clause</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">))</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">[:</span><span class=\"mi\">3</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;Not&#39;</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_clause</span> <span class=\"o\">=</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">[</span><span class=\"mi\">3</span><span class=\"p\">:],</span> <span class=\"o\">*</span><span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)</span>\n",
       "\n",
       "                <span class=\"k\">if</span> <span class=\"n\">kb</span><span class=\"o\">.</span><span class=\"n\">ask</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">substitute</span><span class=\"p\">(</span><span class=\"n\">new_clause</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">))</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">False</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">kb</span><span class=\"o\">.</span><span class=\"n\">retract</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">substitute</span><span class=\"p\">(</span><span class=\"n\">new_clause</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">))</span>\n",
       "            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_clause</span> <span class=\"o\">=</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"s1\">&#39;Not&#39;</span> <span class=\"o\">+</span> <span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)</span>\n",
       "\n",
       "                <span class=\"k\">if</span> <span class=\"n\">kb</span><span class=\"o\">.</span><span class=\"n\">ask</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">substitute</span><span class=\"p\">(</span><span class=\"n\">new_clause</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">))</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">False</span><span class=\"p\">:</span>    \n",
       "                    <span class=\"n\">kb</span><span class=\"o\">.</span><span class=\"n\">retract</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">substitute</span><span class=\"p\">(</span><span class=\"n\">new_clause</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">))</span>\n",
       "\n",
       "        <span class=\"k\">return</span> <span class=\"n\">kb</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(Action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This class represents an action given the expression, the preconditions and its effects. \n",
    "A list `precond` stores the preconditions of the action and a list `effect` stores its effects.\n",
    "Negative preconditions and effects are input using a `~` symbol before the clause, which are internally prefixed with a `Not` to make it easier to work with.\n",
    "For example, the negation of `At(obj, loc)` will be input as `~At(obj, loc)` and internally represented as `NotAt(obj, loc)`. \n",
    "This equivalently creates a new clause for each negative literal, removing the hassle of maintaining two separate knowledge bases.\n",
    "This greatly simplifies algorithms like `GraphPlan` as we will see later.\n",
    "The `convert` method takes an input string, parses it, removes conjunctions if any and returns a list of `Expr` objects.\n",
    "The `check_precond` method checks if the preconditions for that action are valid, given a `kb`.\n",
    "The `act` method carries out the action on the given knowledge base."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now lets try to define a planning problem using these tools. Since we already know about the map of Romania, lets see if we can plan a trip across a simplified map of Romania.\n",
    "\n",
    "Here is our simplified map definition:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {},
   "outputs": [],
   "source": [
    "from utils import *\n",
    "# this imports the required expr so we can create our knowledge base\n",
    "\n",
    "knowledge_base = [\n",
    "    expr(\"Connected(Bucharest,Pitesti)\"),\n",
    "    expr(\"Connected(Pitesti,Rimnicu)\"),\n",
    "    expr(\"Connected(Rimnicu,Sibiu)\"),\n",
    "    expr(\"Connected(Sibiu,Fagaras)\"),\n",
    "    expr(\"Connected(Fagaras,Bucharest)\"),\n",
    "    expr(\"Connected(Pitesti,Craiova)\"),\n",
    "    expr(\"Connected(Craiova,Rimnicu)\")\n",
    "    ]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us add some logic propositions to complete our knowledge about travelling around the map. These are the typical symmetry and transitivity properties of connections on a map. We can now be sure that our `knowledge_base` understands what it truly means for two locations to be connected in the sense usually meant by humans when we use the term.\n",
    "\n",
    "Let's also add our starting location - *Sibiu* to the map."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 83,
   "metadata": {},
   "outputs": [],
   "source": [
    "knowledge_base.extend([\n",
    "     expr(\"Connected(x,y) ==> Connected(y,x)\"),\n",
    "     expr(\"Connected(x,y) & Connected(y,z) ==> Connected(x,z)\"),\n",
    "     expr(\"At(Sibiu)\")\n",
    "    ])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now have a complete knowledge base, which can be seen like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 84,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Connected(Bucharest, Pitesti),\n",
       " Connected(Pitesti, Rimnicu),\n",
       " Connected(Rimnicu, Sibiu),\n",
       " Connected(Sibiu, Fagaras),\n",
       " Connected(Fagaras, Bucharest),\n",
       " Connected(Pitesti, Craiova),\n",
       " Connected(Craiova, Rimnicu),\n",
       " (Connected(x, y) ==> Connected(y, x)),\n",
       " ((Connected(x, y) & Connected(y, z)) ==> Connected(x, z)),\n",
       " At(Sibiu)]"
      ]
     },
     "execution_count": 84,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knowledge_base"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now define possible actions to our problem. We know that we can drive between any connected places. But, as is evident from [this](https://en.wikipedia.org/wiki/List_of_airports_in_Romania) list of Romanian airports, we can also fly directly between Sibiu, Bucharest, and Craiova.\n",
    "\n",
    "We can define these flight actions like this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 85,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Sibiu to Bucharest\n",
    "precond = 'At(Sibiu)'\n",
    "effect = 'At(Bucharest) & ~At(Sibiu)'\n",
    "fly_s_b = Action('Fly(Sibiu, Bucharest)', precond, effect)\n",
    "\n",
    "#Bucharest to Sibiu\n",
    "precond = 'At(Bucharest)'\n",
    "effect = 'At(Sibiu) & ~At(Bucharest)'\n",
    "fly_b_s = Action('Fly(Bucharest, Sibiu)', precond, effect)\n",
    "\n",
    "#Sibiu to Craiova\n",
    "precond = 'At(Sibiu)'\n",
    "effect = 'At(Craiova) & ~At(Sibiu)'\n",
    "fly_s_c = Action('Fly(Sibiu, Craiova)', precond, effect)\n",
    "\n",
    "#Craiova to Sibiu\n",
    "precond = 'At(Craiova)'\n",
    "effect = 'At(Sibiu) & ~At(Craiova)'\n",
    "fly_c_s = Action('Fly(Craiova, Sibiu)', precond, effect)\n",
    "\n",
    "#Bucharest to Craiova\n",
    "precond = 'At(Bucharest)'\n",
    "effect = 'At(Craiova) & ~At(Bucharest)'\n",
    "fly_b_c = Action('Fly(Bucharest, Craiova)', precond, effect)\n",
    "\n",
    "#Craiova to Bucharest\n",
    "precond = 'At(Craiova)'\n",
    "effect = 'At(Bucharest) & ~At(Craiova)'\n",
    "fly_c_b = Action('Fly(Craiova, Bucharest)', precond, effect)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And the drive actions like this."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 86,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Drive\n",
    "precond = 'At(x)'\n",
    "effect = 'At(y) & ~At(x)'\n",
    "drive = Action('Drive(x, y)', precond, effect)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Our goal is defined as"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {},
   "outputs": [],
   "source": [
    "goals = 'At(Bucharest)'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, we can define a a function that will tell us when we have reached our destination, Bucharest."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {},
   "outputs": [],
   "source": [
    "def goal_test(kb):\n",
    "    return kb.ask(expr('At(Bucharest)'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Thus, with all the components in place, we can define the planning problem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {},
   "outputs": [],
   "source": [
    "prob = PlanningProblem(knowledge_base, goals, [fly_s_b, fly_b_s, fly_s_c, fly_c_s, fly_b_c, fly_c_b, drive])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PLANNING PROBLEMS\n",
    "---\n",
    "\n",
    "## Air Cargo Problem"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the Air Cargo problem, we start with cargo at two airports, SFO and JFK. Our goal is to send each cargo to the other airport. We have two airplanes to help us accomplish the task. \n",
    "The problem can be defined with three actions: Load, Unload and Fly. \n",
    "Let us look how the `air_cargo` problem has been defined in the module. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 90,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">air_cargo</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    [Figure 10.1] AIR-CARGO-PROBLEM</span>\n",
       "\n",
       "<span class=\"sd\">    An air-cargo shipment problem for delivering cargo to different locations,</span>\n",
       "<span class=\"sd\">    given the starting location and airplanes.</span>\n",
       "\n",
       "<span class=\"sd\">    Example:</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; from planning import *</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ac = air_cargo()</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ac.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ac.act(expr(&#39;Load(C2, P2, JFK)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ac.act(expr(&#39;Load(C1, P1, SFO)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ac.act(expr(&#39;Fly(P1, SFO, JFK)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ac.act(expr(&#39;Fly(P2, JFK, SFO)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ac.act(expr(&#39;Unload(C2, P2, SFO)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ac.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ac.act(expr(&#39;Unload(C1, P1, JFK)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ac.goal_test()</span>\n",
       "<span class=\"sd\">    True</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt;</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PlanningProblem</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(C1, SFO) &amp; At(C2, JFK) &amp; At(P1, SFO) &amp; At(P2, JFK) &amp; Cargo(C1) &amp; Cargo(C2) &amp; Plane(P1) &amp; Plane(P2) &amp; Airport(SFO) &amp; Airport(JFK)&#39;</span><span class=\"p\">,</span> \n",
       "                <span class=\"n\">goals</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(C1, JFK) &amp; At(C2, SFO)&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">actions</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Load(c, p, a)&#39;</span><span class=\"p\">,</span> \n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(c, a) &amp; At(p, a) &amp; Cargo(c) &amp; Plane(p) &amp; Airport(a)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;In(c, p) &amp; ~At(c, a)&#39;</span><span class=\"p\">),</span>\n",
       "                         <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Unload(c, p, a)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;In(c, p) &amp; At(p, a) &amp; Cargo(c) &amp; Plane(p) &amp; Airport(a)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(c, a) &amp; ~In(c, p)&#39;</span><span class=\"p\">),</span>\n",
       "                         <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Fly(p, f, to)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(p, f) &amp; Plane(p) &amp; Airport(f) &amp; Airport(to)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(p, to) &amp; ~At(p, f)&#39;</span><span class=\"p\">)])</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(air_cargo)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**At(c, a):** The cargo **'c'** is at airport **'a'**.\n",
    "\n",
    "**~At(c, a):** The cargo **'c'** is _not_ at airport **'a'**.\n",
    "\n",
    "**In(c, p):** Cargo **'c'** is in plane **'p'**.\n",
    "\n",
    "**~In(c, p):** Cargo **'c'** is _not_ in plane **'p'**.\n",
    "\n",
    "**Cargo(c):** Declare **'c'** as cargo.\n",
    "\n",
    "**Plane(p):** Declare **'p'** as plane.\n",
    "\n",
    "**Airport(a):** Declare **'a'** as airport.\n",
    "\n",
    "\n",
    "\n",
    "In the `initial_state`, we have cargo C1, plane P1 at airport SFO and cargo C2, plane P2 at airport JFK. \n",
    "Our goal state is to have cargo C1 at airport JFK and cargo C2 at airport SFO. We will discuss on how to achieve this. Let us now define an object of the `air_cargo` problem:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 91,
   "metadata": {},
   "outputs": [],
   "source": [
    "airCargo = air_cargo()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before taking any actions, we will check if `airCargo` has reached its goal:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "print(airCargo.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It returns False because the goal state is not yet reached. Now, we define the sequence of actions that it should take in order to achieve the goal.\n",
    "The actions are then carried out on the `airCargo` PlanningProblem.\n",
    "\n",
    "The actions available to us are the following: Load, Unload, Fly\n",
    "\n",
    "**Load(c, p, a):** Load cargo **'c'** into plane **'p'** from airport **'a'**.\n",
    "\n",
    "**Fly(p, f, t):** Fly the plane **'p'** from airport **'f'** to airport **'t'**.\n",
    "\n",
    "**Unload(c, p, a):** Unload cargo **'c'** from plane **'p'** to airport **'a'**.\n",
    "\n",
    "This problem can have multiple valid solutions.\n",
    "One such solution is shown below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 93,
   "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)\")] \n",
    "\n",
    "for action in solution:\n",
    "    airCargo.act(action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As the `airCargo` has taken all the steps it needed in order to achieve the goal, we can now check if it has acheived its goal:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "print(airCargo.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It has now achieved its goal."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The Spare Tire Problem"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's consider the problem of changing a flat tire of a car. \n",
    "The goal is to mount a spare tire onto the car's axle, given that we have a flat tire on the axle and a spare tire in the trunk. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 95,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">spare_tire</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;[Figure 10.2] SPARE-TIRE-PROBLEM</span>\n",
       "\n",
       "<span class=\"sd\">    A problem involving changing the flat tire of a car</span>\n",
       "<span class=\"sd\">    with a spare tire from the trunk.</span>\n",
       "\n",
       "<span class=\"sd\">    Example:</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; from planning import *</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; st = spare_tire()</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; st.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; st.act(expr(&#39;Remove(Spare, Trunk)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; st.act(expr(&#39;Remove(Flat, Axle)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; st.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; st.act(expr(&#39;PutOn(Spare, Axle)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; st.goal_test()</span>\n",
       "<span class=\"sd\">    True</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt;</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PlanningProblem</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;Tire(Flat) &amp; Tire(Spare) &amp; At(Flat, Axle) &amp; At(Spare, Trunk)&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">goals</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(Spare, Axle) &amp; At(Flat, Ground)&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">actions</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Remove(obj, loc)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(obj, loc)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(obj, Ground) &amp; ~At(obj, loc)&#39;</span><span class=\"p\">),</span>\n",
       "                         <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;PutOn(t, Axle)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;Tire(t) &amp; At(t, Ground) &amp; ~At(Flat, Axle)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(t, Axle) &amp; ~At(t, Ground)&#39;</span><span class=\"p\">),</span>\n",
       "                         <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;LeaveOvernight&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;~At(Spare, Ground) &amp; ~At(Spare, Axle) &amp; ~At(Spare, Trunk) &amp; </span><span class=\"se\">\\</span>\n",
       "<span class=\"s1\">                                        ~At(Flat, Ground) &amp; ~At(Flat, Axle) &amp; ~At(Flat, Trunk)&#39;</span><span class=\"p\">)])</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(spare_tire)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**At(obj, loc):** object **'obj'** is at location **'loc'**.\n",
    "\n",
    "**~At(obj, loc):** object **'obj'** is _not_ at location **'loc'**.\n",
    "\n",
    "**Tire(t):** Declare a tire of type **'t'**.\n",
    "\n",
    "Let us now define an object of `spare_tire` problem:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 96,
   "metadata": {},
   "outputs": [],
   "source": [
    "spareTire = spare_tire()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before taking any actions, we will check if `spare_tire` has reached its goal:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 97,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "print(spareTire.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we can see, it hasn't completed the goal. \n",
    "We now define a possible solution that can help us reach the goal of having a spare tire mounted onto the car's axle. \n",
    "The actions are then carried out on the `spareTire` PlanningProblem.\n",
    "\n",
    "The actions available to us are the following: Remove, PutOn\n",
    "\n",
    "**Remove(obj, loc):** Remove the tire **'obj'** from the location **'loc'**.\n",
    "\n",
    "**PutOn(t, Axle):** Attach the tire **'t'** on the Axle.\n",
    "\n",
    "**LeaveOvernight():** We live in a particularly bad neighborhood and all tires, flat or not, are stolen if we leave them overnight.\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 98,
   "metadata": {},
   "outputs": [],
   "source": [
    "solution = [expr(\"Remove(Flat, Axle)\"),\n",
    "            expr(\"Remove(Spare, Trunk)\"),\n",
    "            expr(\"PutOn(Spare, Axle)\")]\n",
    "\n",
    "for action in solution:\n",
    "    spareTire.act(action)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 99,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "print(spareTire.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is a valid solution.\n",
    "<br>\n",
    "Another possible solution is"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [],
   "source": [
    "spareTire = spare_tire()\n",
    "\n",
    "solution = [expr('Remove(Spare, Trunk)'),\n",
    "            expr('Remove(Flat, Axle)'),\n",
    "            expr('PutOn(Spare, Axle)')]\n",
    "\n",
    "for action in solution:\n",
    "    spareTire.act(action)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "print(spareTire.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Notice that both solutions work, which means that the problem can be solved irrespective of the order in which the `Remove` actions take place, as long as both `Remove` actions take place before the `PutOn` action."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have successfully mounted a spare tire onto the axle."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Three Block Tower Problem"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This problem's domain consists of a set of cube-shaped blocks sitting on a table. \n",
    "The blocks can be stacked, but only one block can fit directly on top of another.\n",
    "A robot arm can pick up a block and move it to another position, either on the table or on top of another block. \n",
    "The arm can pick up only one block at a time, so it cannot pick up a block that has another one on it. \n",
    "The goal will always be to build one or more stacks of blocks. \n",
    "In our case, we consider only three blocks.\n",
    "The particular configuration we will use is called the Sussman anomaly after Prof. Gerry Sussman."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's take a look at the definition of `three_block_tower()` in the module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">three_block_tower</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    [Figure 10.3] THREE-BLOCK-TOWER</span>\n",
       "\n",
       "<span class=\"sd\">    A blocks-world problem of stacking three blocks in a certain configuration,</span>\n",
       "<span class=\"sd\">    also known as the Sussman Anomaly.</span>\n",
       "\n",
       "<span class=\"sd\">    Example:</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; from planning import *</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; tbt = three_block_tower()</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; tbt.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; tbt.act(expr(&#39;MoveToTable(C, A)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; tbt.act(expr(&#39;Move(B, Table, C)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; tbt.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; tbt.act(expr(&#39;Move(A, Table, B)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; tbt.goal_test()</span>\n",
       "<span class=\"sd\">    True</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt;</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PlanningProblem</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;On(A, Table) &amp; On(B, Table) &amp; On(C, A) &amp; Block(A) &amp; Block(B) &amp; Block(C) &amp; Clear(B) &amp; Clear(C)&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">goals</span><span class=\"o\">=</span><span class=\"s1\">&#39;On(A, B) &amp; On(B, C)&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">actions</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Move(b, x, y)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;On(b, x) &amp; Clear(b) &amp; Clear(y) &amp; Block(b) &amp; Block(y)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;On(b, y) &amp; Clear(x) &amp; ~On(b, x) &amp; ~Clear(y)&#39;</span><span class=\"p\">),</span>\n",
       "                         <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;MoveToTable(b, x)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;On(b, x) &amp; Clear(b) &amp; Block(b)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;On(b, Table) &amp; Clear(x) &amp; ~On(b, x)&#39;</span><span class=\"p\">)])</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(three_block_tower)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**On(b, x):** The block **'b'** is on **'x'**. **'x'** can be a table or a block.\n",
    "\n",
    "**~On(b, x):** The block **'b'** is _not_ on **'x'**. **'x'** can be a table or a block.\n",
    "\n",
    "**Block(b):** Declares **'b'** as a block.\n",
    "\n",
    "**Clear(x):** To indicate that there is nothing on **'x'** and it is free to be moved around.\n",
    "\n",
    "**~Clear(x):** To indicate that there is something on **'x'** and it cannot be moved.\n",
    " \n",
    " Let us now define an object of `three_block_tower` problem:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [],
   "source": [
    "threeBlockTower = three_block_tower()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before taking any actions, we will check if `threeBlockTower` has reached its goal:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "print(threeBlockTower.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we can see, it hasn't completed the goal. \n",
    "We now define a sequence of actions that can stack three blocks in the required order. \n",
    "The actions are then carried out on the `threeBlockTower` PlanningProblem.\n",
    "\n",
    "The actions available to us are the following: MoveToTable, Move\n",
    "\n",
    "**MoveToTable(b, x): ** Move box **'b'** stacked on **'x'** to the table, given that box **'b'** is clear.\n",
    "\n",
    "**Move(b, x, y): ** Move box **'b'** stacked on **'x'** to the top of **'y'**, given that both **'b'** and **'y'** are clear.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [],
   "source": [
    "solution = [expr(\"MoveToTable(C, A)\"),\n",
    "            expr(\"Move(B, Table, C)\"),\n",
    "            expr(\"Move(A, Table, B)\")]\n",
    "\n",
    "for action in solution:\n",
    "    threeBlockTower.act(action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As the `three_block_tower` has taken all the steps it needed in order to achieve the goal, we can now check if it has acheived its goal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "print(threeBlockTower.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It has now successfully achieved its goal i.e, to build a stack of three blocks in the specified order."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `three_block_tower` problem can also be defined in simpler terms using just two actions `ToTable(x, y)` and `FromTable(x, y)`.\n",
    "The underlying problem remains the same however, stacking up three blocks in a certain configuration given a particular starting state.\n",
    "Let's have a look at the alternative definition."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">simple_blocks_world</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    SIMPLE-BLOCKS-WORLD</span>\n",
       "\n",
       "<span class=\"sd\">    A simplified definition of the Sussman Anomaly problem.</span>\n",
       "\n",
       "<span class=\"sd\">    Example:</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; from planning import *</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sbw = simple_blocks_world()</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sbw.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sbw.act(expr(&#39;ToTable(A, B)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sbw.act(expr(&#39;FromTable(B, A)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sbw.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sbw.act(expr(&#39;FromTable(C, B)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sbw.goal_test()</span>\n",
       "<span class=\"sd\">    True</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt;</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PlanningProblem</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;On(A, B) &amp; Clear(A) &amp; OnTable(B) &amp; OnTable(C) &amp; Clear(C)&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">goals</span><span class=\"o\">=</span><span class=\"s1\">&#39;On(B, A) &amp; On(C, B)&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">actions</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;ToTable(x, y)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;On(x, y) &amp; Clear(x)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;~On(x, y) &amp; Clear(y) &amp; OnTable(x)&#39;</span><span class=\"p\">),</span>\n",
       "                         <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;FromTable(y, x)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;OnTable(y) &amp; Clear(y) &amp; Clear(x)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;~OnTable(y) &amp; ~Clear(x) &amp; On(y, x)&#39;</span><span class=\"p\">)])</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(simple_blocks_world)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**On(x, y):** The block **'x'** is on **'y'**. Both **'x'** and **'y'** have to be blocks.\n",
    "\n",
    "**~On(x, y):** The block **'x'** is _not_ on **'y'**. Both **'x'** and **'y'** have to be blocks.\n",
    "\n",
    "**OnTable(x):** The block **'x'** is on the table.\n",
    "\n",
    "**~OnTable(x):** The block **'x'** is _not_ on the table.\n",
    "\n",
    "**Clear(x):** To indicate that there is nothing on **'x'** and it is free to be moved around.\n",
    "\n",
    "**~Clear(x):** To indicate that there is something on **'x'** and it cannot be moved.\n",
    "\n",
    "Let's now define a `simple_blocks_world` prolem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {},
   "outputs": [],
   "source": [
    "simpleBlocksWorld = simple_blocks_world()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before taking any actions, we will see if `simple_bw` has reached its goal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 109,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 109,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "simpleBlocksWorld.goal_test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we can see, it hasn't completed the goal. \n",
    "We now define a sequence of actions that can stack three blocks in the required order. \n",
    "The actions are then carried out on the `simple_bw` PlanningProblem.\n",
    "\n",
    "The actions available to us are the following: MoveToTable, Move\n",
    "\n",
    "**ToTable(x, y): ** Move box **'x'** stacked on **'y'** to the table, given that box **'y'** is clear.\n",
    "\n",
    "**FromTable(x, y): ** Move box **'x'** from wherever it is, to the top of **'y'**, given that both **'x'** and **'y'** are clear.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 110,
   "metadata": {},
   "outputs": [],
   "source": [
    "solution = [expr('ToTable(A, B)'),\n",
    "            expr('FromTable(B, A)'),\n",
    "            expr('FromTable(C, B)')]\n",
    "\n",
    "for action in solution:\n",
    "    simpleBlocksWorld.act(action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As the `three_block_tower` has taken all the steps it needed in order to achieve the goal, we can now check if it has acheived its goal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 111,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "print(simpleBlocksWorld.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It has now successfully achieved its goal i.e, to build a stack of three blocks in the specified order."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Shopping Problem"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This problem requires us to acquire a carton of milk, a banana and a drill.\n",
    "Initially, we start from home and it is known to us that milk and bananas are available in the supermarket and the hardware store sells drills.\n",
    "Let's take a look at the definition of the `shopping_problem` in the module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 112,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">shopping_problem</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    SHOPPING-PROBLEM</span>\n",
       "\n",
       "<span class=\"sd\">    A problem of acquiring some items given their availability at certain stores.</span>\n",
       "\n",
       "<span class=\"sd\">    Example:</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; from planning import *</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sp = shopping_problem()</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sp.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sp.act(expr(&#39;Go(Home, HW)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sp.act(expr(&#39;Buy(Drill, HW)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sp.act(expr(&#39;Go(HW, SM)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sp.act(expr(&#39;Buy(Banana, SM)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sp.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sp.act(expr(&#39;Buy(Milk, SM)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; sp.goal_test()</span>\n",
       "<span class=\"sd\">    True</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt;</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PlanningProblem</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(Home) &amp; Sells(SM, Milk) &amp; Sells(SM, Banana) &amp; Sells(HW, Drill)&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">goals</span><span class=\"o\">=</span><span class=\"s1\">&#39;Have(Milk) &amp; Have(Banana) &amp; Have(Drill)&#39;</span><span class=\"p\">,</span> \n",
       "                <span class=\"n\">actions</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Buy(x, store)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(store) &amp; Sells(store, x)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;Have(x)&#39;</span><span class=\"p\">),</span>\n",
       "                         <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Go(x, y)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(x)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(y) &amp; ~At(x)&#39;</span><span class=\"p\">)])</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(shopping_problem)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**At(x):** Indicates that we are currently at **'x'** where **'x'** can be Home, SM (supermarket) or HW (Hardware store).\n",
    "\n",
    "**~At(x):** Indicates that we are currently _not_ at **'x'**.\n",
    "\n",
    "**Sells(s, x):** Indicates that item **'x'** can be bought from store **'s'**.\n",
    "\n",
    "**Have(x):** Indicates that we possess the item **'x'**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {},
   "outputs": [],
   "source": [
    "shoppingProblem = shopping_problem()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's first check whether the goal state Have(Milk), Have(Banana), Have(Drill) is reached or not."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "print(shoppingProblem.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's look at the possible actions\n",
    "\n",
    "**Buy(x, store):** Buy an item **'x'** from a **'store'** given that the **'store'** sells **'x'**.\n",
    "\n",
    "**Go(x, y):** Go to destination **'y'** starting from source **'x'**."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now define a valid solution that will help us reach the goal.\n",
    "The sequence of actions will then be carried out onto the `shoppingProblem` PlanningProblem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 115,
   "metadata": {},
   "outputs": [],
   "source": [
    "solution = [expr('Go(Home, SM)'),\n",
    "            expr('Buy(Milk, SM)'),\n",
    "            expr('Buy(Banana, SM)'),\n",
    "            expr('Go(SM, HW)'),\n",
    "            expr('Buy(Drill, HW)')]\n",
    "\n",
    "for action in solution:\n",
    "    shoppingProblem.act(action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have taken the steps required to acquire all the stuff we need. \n",
    "Let's see if we have reached our goal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 116,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 116,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "shoppingProblem.goal_test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It has now successfully achieved the goal."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Socks and Shoes"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is a simple problem of putting on a pair of socks and shoes.\n",
    "The problem is defined in the module as given below."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">socks_and_shoes</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    SOCKS-AND-SHOES-PROBLEM</span>\n",
       "\n",
       "<span class=\"sd\">    A task of wearing socks and shoes on both feet</span>\n",
       "\n",
       "<span class=\"sd\">    Example:</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; from planning import *</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ss = socks_and_shoes()</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ss.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ss.act(expr(&#39;RightSock&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ss.act(expr(&#39;RightShoe&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ss.act(expr(&#39;LeftSock&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ss.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ss.act(expr(&#39;LeftShoe&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; ss.goal_test()</span>\n",
       "<span class=\"sd\">    True</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt;</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PlanningProblem</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">goals</span><span class=\"o\">=</span><span class=\"s1\">&#39;RightShoeOn &amp; LeftShoeOn&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">actions</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;RightShoe&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;RightSockOn&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;RightShoeOn&#39;</span><span class=\"p\">),</span>\n",
       "                        <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;RightSock&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;RightSockOn&#39;</span><span class=\"p\">),</span>\n",
       "                        <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;LeftShoe&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;LeftSockOn&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;LeftShoeOn&#39;</span><span class=\"p\">),</span>\n",
       "                        <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;LeftSock&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;LeftSockOn&#39;</span><span class=\"p\">)])</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(socks_and_shoes)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**LeftSockOn:** Indicates that we have already put on the left sock.\n",
    "\n",
    "**RightSockOn:** Indicates that we have already put on the right sock.\n",
    "\n",
    "**LeftShoeOn:** Indicates that we have already put on the left shoe.\n",
    "\n",
    "**RightShoeOn:** Indicates that we have already put on the right shoe.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {},
   "outputs": [],
   "source": [
    "socksShoes = socks_and_shoes()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's first check whether the goal state is reached or not."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 119,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 119,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "socksShoes.goal_test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As the goal state isn't reached, we will define a sequence of actions that might help us achieve the goal.\n",
    "These actions will then be acted upon the `socksShoes` PlanningProblem to check if the goal state is reached."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 120,
   "metadata": {},
   "outputs": [],
   "source": [
    "solution = [expr('RightSock'),\n",
    "            expr('RightShoe'),\n",
    "            expr('LeftSock'),\n",
    "            expr('LeftShoe')]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 121,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 121,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "for action in solution:\n",
    "    socksShoes.act(action)\n",
    "    \n",
    "socksShoes.goal_test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have reached our goal."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cake Problem"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This problem requires us to reach the state of having a cake and having eaten a cake simlutaneously, given a single cake.\n",
    "Let's first take a look at the definition of the `have_cake_and_eat_cake_too` problem in the module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 122,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">have_cake_and_eat_cake_too</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    [Figure 10.7] CAKE-PROBLEM</span>\n",
       "\n",
       "<span class=\"sd\">    A problem where we begin with a cake and want to </span>\n",
       "<span class=\"sd\">    reach the state of having a cake and having eaten a cake.</span>\n",
       "<span class=\"sd\">    The possible actions include baking a cake and eating a cake.</span>\n",
       "\n",
       "<span class=\"sd\">    Example:</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; from planning import *</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; cp = have_cake_and_eat_cake_too()</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; cp.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; cp.act(expr(&#39;Eat(Cake)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; cp.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; cp.act(expr(&#39;Bake(Cake)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; cp.goal_test()</span>\n",
       "<span class=\"sd\">    True</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt;</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PlanningProblem</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;Have(Cake)&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">goals</span><span class=\"o\">=</span><span class=\"s1\">&#39;Have(Cake) &amp; Eaten(Cake)&#39;</span><span class=\"p\">,</span>\n",
       "                <span class=\"n\">actions</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Eat(Cake)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;Have(Cake)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;Eaten(Cake) &amp; ~Have(Cake)&#39;</span><span class=\"p\">),</span>\n",
       "                         <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Bake(Cake)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;~Have(Cake)&#39;</span><span class=\"p\">,</span>\n",
       "                                <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;Have(Cake)&#39;</span><span class=\"p\">)])</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(have_cake_and_eat_cake_too)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Since this problem doesn't involve variables, states can be considered similar to symbols in propositional logic.\n",
    "\n",
    "**Have(Cake):** Declares that we have a **'Cake'**.\n",
    "\n",
    "**~Have(Cake):** Declares that we _don't_ have a **'Cake'**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [],
   "source": [
    "cakeProblem = have_cake_and_eat_cake_too()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First let us check whether the goal state 'Have(Cake)' and 'Eaten(Cake)' are reached or not."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 124,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "print(cakeProblem.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let us look at the possible actions.\n",
    "\n",
    "**Bake(x):** To bake **' x '**.\n",
    "\n",
    "**Eat(x):** To eat **' x '**."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now define a valid solution that can help us reach the goal.\n",
    "The sequence of actions will then be acted upon the `cakeProblem` PlanningProblem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 125,
   "metadata": {},
   "outputs": [],
   "source": [
    "solution = [expr(\"Eat(Cake)\"),\n",
    "            expr(\"Bake(Cake)\")]\n",
    "\n",
    "for action in solution:\n",
    "    cakeProblem.act(action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we have made actions to bake the cake and eat the cake. Let us check if we have reached the goal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 126,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "print(cakeProblem.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It has now successfully achieved its goal i.e, to have and eat the cake."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One might wonder if the order of the actions matters for this problem.\n",
    "Let's see for ourselves."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 128,
   "metadata": {},
   "outputs": [
    {
     "ename": "Exception",
     "evalue": "Action 'Bake(Cake)' pre-conditions not satisfied",
     "output_type": "error",
     "traceback": [
      "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[0;31mException\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[0;32m<ipython-input-128-b340f831489f>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m      5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m      6\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0maction\u001b[0m \u001b[0;32min\u001b[0m \u001b[0msolution\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m     \u001b[0mcakeProblem\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mact\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[0;32m~/aima-python/planning.py\u001b[0m in \u001b[0;36mact\u001b[0;34m(self, action)\u001b[0m\n\u001b[1;32m     58\u001b[0m             \u001b[0;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Action '{}' not found\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     59\u001b[0m         \u001b[0;32mif\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0mlist_action\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcheck_precond\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minit\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 60\u001b[0;31m             \u001b[0;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Action '{}' pre-conditions not satisfied\"\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0maction\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m     61\u001b[0m         \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minit\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlist_action\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0minit\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclauses\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m     62\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
      "\u001b[0;31mException\u001b[0m: Action 'Bake(Cake)' pre-conditions not satisfied"
     ]
    }
   ],
   "source": [
    "cakeProblem = have_cake_and_eat_cake_too()\n",
    "\n",
    "solution = [expr('Bake(Cake)'),\n",
    "            expr('Eat(Cake)')]\n",
    "\n",
    "for action in solution:\n",
    "    cakeProblem.act(action)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It raises an exception.\n",
    "Indeed, according to the problem, we cannot bake a cake if we already have one.\n",
    "In planning terms, '~Have(Cake)' is a precondition to the action 'Bake(Cake)'.\n",
    "Hence, this solution is invalid."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PLANNING IN THE REAL WORLD\n",
    "---\n",
    "## PROBLEM\n",
    "The `Problem` class is a wrapper for `PlanningProblem` with some additional functionality and data-structures to handle real-world planning problems that involve time and resource constraints.\n",
    "The `Problem` class includes everything that the `PlanningProblem` class includes.\n",
    "Additionally, it also includes the following attributes essential to define a real-world planning problem:\n",
    "- a list of `jobs` to be done\n",
    "- a dictionary of `resources`\n",
    "\n",
    "It also overloads the `act` method to call the `do_action` method of the `HLA` class, \n",
    "and also includes a new method `refinements` that finds refinements or primitive actions for high level actions.\n",
    "<br>\n",
    "`hierarchical_search` and `angelic_search` are also built into the `Problem` class to solve such planning problems."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">class</span> <span class=\"nc\">Problem</span><span class=\"p\">(</span><span class=\"n\">PlanningProblem</span><span class=\"p\">):</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    Define real-world problems by aggregating resources as numerical quantities instead of</span>\n",
       "<span class=\"sd\">    named entities.</span>\n",
       "\n",
       "<span class=\"sd\">    This class is identical to PDLL, except that it overloads the act function to handle</span>\n",
       "<span class=\"sd\">    resource and ordering conditions imposed by HLA as opposed to Action.</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">goals</span><span class=\"p\">,</span> <span class=\"n\">actions</span><span class=\"p\">,</span> <span class=\"n\">jobs</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">resources</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span>\n",
       "        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">goals</span><span class=\"p\">,</span> <span class=\"n\">actions</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">jobs</span> <span class=\"o\">=</span> <span class=\"n\">jobs</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">resources</span> <span class=\"o\">=</span> <span class=\"n\">resources</span> <span class=\"ow\">or</span> <span class=\"p\">{}</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">act</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        Performs the HLA given as argument.</span>\n",
       "\n",
       "<span class=\"sd\">        Note that this is different from the superclass action - where the parameter was an</span>\n",
       "<span class=\"sd\">        Expression. For real world problems, an Expr object isn&#39;t enough to capture all the</span>\n",
       "<span class=\"sd\">        detail required for executing the action - resources, preconditions, etc need to be</span>\n",
       "<span class=\"sd\">        checked for too.</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"n\">args</span> <span class=\"o\">=</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">args</span>\n",
       "        <span class=\"n\">list_action</span> <span class=\"o\">=</span> <span class=\"n\">first</span><span class=\"p\">(</span><span class=\"n\">a</span> <span class=\"k\">for</span> <span class=\"n\">a</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">actions</span> <span class=\"k\">if</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">name</span> <span class=\"o\">==</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">if</span> <span class=\"n\">list_action</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">raise</span> <span class=\"ne\">Exception</span><span class=\"p\">(</span><span class=\"s2\">&quot;Action &#39;{}&#39; not found&quot;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">))</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">init</span> <span class=\"o\">=</span> <span class=\"n\">list_action</span><span class=\"o\">.</span><span class=\"n\">do_action</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">jobs</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">resources</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">clauses</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">refinements</span><span class=\"p\">(</span><span class=\"n\">hla</span><span class=\"p\">,</span> <span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">library</span><span class=\"p\">):</span>  <span class=\"c1\"># refinements may be (multiple) HLA themselves ...</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        state is a Problem, containing the current state kb</span>\n",
       "<span class=\"sd\">        library is a dictionary containing details for every possible refinement. eg:</span>\n",
       "<span class=\"sd\">        {</span>\n",
       "<span class=\"sd\">        &#39;HLA&#39;: [</span>\n",
       "<span class=\"sd\">            &#39;Go(Home, SFO)&#39;,</span>\n",
       "<span class=\"sd\">            &#39;Go(Home, SFO)&#39;,</span>\n",
       "<span class=\"sd\">            &#39;Drive(Home, SFOLongTermParking)&#39;,</span>\n",
       "<span class=\"sd\">            &#39;Shuttle(SFOLongTermParking, SFO)&#39;,</span>\n",
       "<span class=\"sd\">            &#39;Taxi(Home, SFO)&#39;</span>\n",
       "<span class=\"sd\">            ],</span>\n",
       "<span class=\"sd\">        &#39;steps&#39;: [</span>\n",
       "<span class=\"sd\">            [&#39;Drive(Home, SFOLongTermParking)&#39;, &#39;Shuttle(SFOLongTermParking, SFO)&#39;],</span>\n",
       "<span class=\"sd\">            [&#39;Taxi(Home, SFO)&#39;],</span>\n",
       "<span class=\"sd\">            [],</span>\n",
       "<span class=\"sd\">            [],</span>\n",
       "<span class=\"sd\">            []</span>\n",
       "<span class=\"sd\">            ],</span>\n",
       "<span class=\"sd\">        # empty refinements indicate a primitive action</span>\n",
       "<span class=\"sd\">        &#39;precond&#39;: [</span>\n",
       "<span class=\"sd\">            [&#39;At(Home) &amp; Have(Car)&#39;],</span>\n",
       "<span class=\"sd\">            [&#39;At(Home)&#39;],</span>\n",
       "<span class=\"sd\">            [&#39;At(Home) &amp; Have(Car)&#39;],</span>\n",
       "<span class=\"sd\">            [&#39;At(SFOLongTermParking)&#39;],</span>\n",
       "<span class=\"sd\">            [&#39;At(Home)&#39;]</span>\n",
       "<span class=\"sd\">            ],</span>\n",
       "<span class=\"sd\">        &#39;effect&#39;: [</span>\n",
       "<span class=\"sd\">            [&#39;At(SFO) &amp; ~At(Home)&#39;],</span>\n",
       "<span class=\"sd\">            [&#39;At(SFO) &amp; ~At(Home)&#39;],</span>\n",
       "<span class=\"sd\">            [&#39;At(SFOLongTermParking) &amp; ~At(Home)&#39;],</span>\n",
       "<span class=\"sd\">            [&#39;At(SFO) &amp; ~At(SFOLongTermParking)&#39;],</span>\n",
       "<span class=\"sd\">            [&#39;At(SFO) &amp; ~At(Home)&#39;]</span>\n",
       "<span class=\"sd\">            ]</span>\n",
       "<span class=\"sd\">        }</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"n\">e</span> <span class=\"o\">=</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"n\">hla</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"n\">hla</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)</span>\n",
       "        <span class=\"n\">indices</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">i</span> <span class=\"k\">for</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s1\">&#39;HLA&#39;</span><span class=\"p\">])</span> <span class=\"k\">if</span> <span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">op</span> <span class=\"o\">==</span> <span class=\"n\">hla</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">]</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"n\">indices</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">actions</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">j</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s1\">&#39;steps&#39;</span><span class=\"p\">][</span><span class=\"n\">i</span><span class=\"p\">])):</span>\n",
       "                <span class=\"c1\"># find the index of the step [j]  of the HLA </span>\n",
       "                <span class=\"n\">index_step</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">k</span> <span class=\"k\">for</span> <span class=\"n\">k</span><span class=\"p\">,</span><span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s1\">&#39;HLA&#39;</span><span class=\"p\">])</span> <span class=\"k\">if</span> <span class=\"n\">x</span> <span class=\"o\">==</span> <span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s1\">&#39;steps&#39;</span><span class=\"p\">][</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">]][</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n",
       "                <span class=\"n\">precond</span> <span class=\"o\">=</span> <span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s1\">&#39;precond&#39;</span><span class=\"p\">][</span><span class=\"n\">index_step</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"c1\"># preconditions of step [j]</span>\n",
       "                <span class=\"n\">effect</span> <span class=\"o\">=</span> <span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s1\">&#39;effect&#39;</span><span class=\"p\">][</span><span class=\"n\">index_step</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"c1\"># effect of step [j]</span>\n",
       "                <span class=\"n\">actions</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">HLA</span><span class=\"p\">(</span><span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s1\">&#39;steps&#39;</span><span class=\"p\">][</span><span class=\"n\">i</span><span class=\"p\">][</span><span class=\"n\">j</span><span class=\"p\">],</span> <span class=\"n\">precond</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"p\">))</span>\n",
       "            <span class=\"k\">yield</span> <span class=\"n\">actions</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">hierarchical_search</span><span class=\"p\">(</span><span class=\"n\">problem</span><span class=\"p\">,</span> <span class=\"n\">hierarchy</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        [Figure 11.5] &#39;Hierarchical Search, a Breadth First Search implementation of Hierarchical</span>\n",
       "<span class=\"sd\">        Forward Planning Search&#39;</span>\n",
       "<span class=\"sd\">        The problem is a real-world problem defined by the problem class, and the hierarchy is</span>\n",
       "<span class=\"sd\">        a dictionary of HLA - refinements (see refinements generator for details)</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"n\">act</span> <span class=\"o\">=</span> <span class=\"n\">Node</span><span class=\"p\">(</span><span class=\"n\">problem</span><span class=\"o\">.</span><span class=\"n\">actions</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span>\n",
       "        <span class=\"n\">frontier</span> <span class=\"o\">=</span> <span class=\"n\">deque</span><span class=\"p\">()</span>\n",
       "        <span class=\"n\">frontier</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">act</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">while</span> <span class=\"bp\">True</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">frontier</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">None</span>\n",
       "            <span class=\"n\">plan</span> <span class=\"o\">=</span> <span class=\"n\">frontier</span><span class=\"o\">.</span><span class=\"n\">popleft</span><span class=\"p\">()</span>\n",
       "            <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">state</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">)</span>\n",
       "            <span class=\"n\">hla</span> <span class=\"o\">=</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">state</span>  <span class=\"c1\"># first_or_null(plan)</span>\n",
       "            <span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"bp\">None</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">parent</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">parent</span><span class=\"o\">.</span><span class=\"n\">state</span><span class=\"o\">.</span><span class=\"n\">action</span>  <span class=\"c1\"># prefix, suffix = subseq(plan.state, hla)</span>\n",
       "            <span class=\"n\">outcome</span> <span class=\"o\">=</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">result</span><span class=\"p\">(</span><span class=\"n\">problem</span><span class=\"p\">,</span> <span class=\"n\">prefix</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">hla</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">outcome</span><span class=\"o\">.</span><span class=\"n\">goal_test</span><span class=\"p\">():</span>\n",
       "                    <span class=\"k\">return</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">path</span><span class=\"p\">()</span>\n",
       "            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;else&quot;</span><span class=\"p\">)</span>\n",
       "                <span class=\"k\">for</span> <span class=\"n\">sequence</span> <span class=\"ow\">in</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">refinements</span><span class=\"p\">(</span><span class=\"n\">hla</span><span class=\"p\">,</span> <span class=\"n\">outcome</span><span class=\"p\">,</span> <span class=\"n\">hierarchy</span><span class=\"p\">):</span>\n",
       "                    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;...&quot;</span><span class=\"p\">)</span>\n",
       "                    <span class=\"n\">frontier</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">Node</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">parent</span><span class=\"p\">,</span> <span class=\"n\">sequence</span><span class=\"p\">))</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">result</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">actions</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;The outcome of applying an action to the current problem&quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">a</span> <span class=\"ow\">in</span> <span class=\"n\">actions</span><span class=\"p\">:</span> \n",
       "            <span class=\"k\">if</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">check_precond</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "                <span class=\"n\">state</span> <span class=\"o\">=</span> <span class=\"n\">a</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">clauses</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">state</span>\n",
       "    \n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">angelic_search</span><span class=\"p\">(</span><span class=\"n\">problem</span><span class=\"p\">,</span> <span class=\"n\">hierarchy</span><span class=\"p\">,</span> <span class=\"n\">initialPlan</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">\t[Figure 11.8] A hierarchical planning algorithm that uses angelic semantics to identify and</span>\n",
       "<span class=\"sd\">\tcommit to high-level plans that work while avoiding high-level plans that don’t. </span>\n",
       "<span class=\"sd\">\tThe predicate MAKING-PROGRESS checks to make sure that we aren’t stuck in an infinite regression</span>\n",
       "<span class=\"sd\">\tof refinements. </span>\n",
       "<span class=\"sd\">\tAt top level, call ANGELIC -SEARCH with [Act ] as the initialPlan .</span>\n",
       "\n",
       "<span class=\"sd\">        initialPlan contains a sequence of HLA&#39;s with angelic semantics </span>\n",
       "\n",
       "<span class=\"sd\">        The possible effects of an angelic HLA in initialPlan are : </span>\n",
       "<span class=\"sd\">        ~ : effect remove</span>\n",
       "<span class=\"sd\">        $+: effect possibly add</span>\n",
       "<span class=\"sd\">        $-: effect possibly remove</span>\n",
       "<span class=\"sd\">        $$: possibly add or remove</span>\n",
       "<span class=\"sd\">\t&quot;&quot;&quot;</span>\n",
       "        <span class=\"n\">frontier</span> <span class=\"o\">=</span> <span class=\"n\">deque</span><span class=\"p\">(</span><span class=\"n\">initialPlan</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">while</span> <span class=\"bp\">True</span><span class=\"p\">:</span> \n",
       "            <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">frontier</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">None</span>\n",
       "            <span class=\"n\">plan</span> <span class=\"o\">=</span> <span class=\"n\">frontier</span><span class=\"o\">.</span><span class=\"n\">popleft</span><span class=\"p\">()</span> <span class=\"c1\"># sequence of HLA/Angelic HLA&#39;s </span>\n",
       "            <span class=\"n\">opt_reachable_set</span> <span class=\"o\">=</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">reach_opt</span><span class=\"p\">(</span><span class=\"n\">problem</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"p\">)</span>\n",
       "            <span class=\"n\">pes_reachable_set</span> <span class=\"o\">=</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">reach_pes</span><span class=\"p\">(</span><span class=\"n\">problem</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">problem</span><span class=\"o\">.</span><span class=\"n\">intersects_goal</span><span class=\"p\">(</span><span class=\"n\">opt_reachable_set</span><span class=\"p\">):</span> \n",
       "                <span class=\"k\">if</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">is_primitive</span><span class=\"p\">(</span> <span class=\"n\">plan</span><span class=\"p\">,</span> <span class=\"n\">hierarchy</span> <span class=\"p\">):</span> \n",
       "                    <span class=\"k\">return</span> <span class=\"p\">([</span><span class=\"n\">x</span> <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span><span class=\"p\">])</span>\n",
       "                <span class=\"n\">guaranteed</span> <span class=\"o\">=</span> <span class=\"n\">problem</span><span class=\"o\">.</span><span class=\"n\">intersects_goal</span><span class=\"p\">(</span><span class=\"n\">pes_reachable_set</span><span class=\"p\">)</span> \n",
       "                <span class=\"k\">if</span> <span class=\"n\">guaranteed</span> <span class=\"ow\">and</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">making_progress</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"p\">):</span>\n",
       "                    <span class=\"n\">final_state</span> <span class=\"o\">=</span> <span class=\"n\">guaranteed</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"c1\"># any element of guaranteed </span>\n",
       "                    <span class=\"c1\">#print(&#39;decompose&#39;)</span>\n",
       "                    <span class=\"k\">return</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">decompose</span><span class=\"p\">(</span><span class=\"n\">hierarchy</span><span class=\"p\">,</span> <span class=\"n\">problem</span><span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"p\">,</span> <span class=\"n\">final_state</span><span class=\"p\">,</span> <span class=\"n\">pes_reachable_set</span><span class=\"p\">)</span>\n",
       "                <span class=\"p\">(</span><span class=\"n\">hla</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">)</span> <span class=\"o\">=</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">find_hla</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"p\">,</span> <span class=\"n\">hierarchy</span><span class=\"p\">)</span> <span class=\"c1\"># there should be at least one HLA/Angelic_HLA, otherwise plan would be primitive.</span>\n",
       "                <span class=\"n\">prefix</span> <span class=\"o\">=</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span><span class=\"p\">[:</span><span class=\"n\">index</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n",
       "                <span class=\"n\">suffix</span> <span class=\"o\">=</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">:]</span>\n",
       "                <span class=\"n\">outcome</span> <span class=\"o\">=</span> <span class=\"n\">Problem</span><span class=\"p\">(</span><span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">result</span><span class=\"p\">(</span><span class=\"n\">problem</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">prefix</span><span class=\"p\">),</span> <span class=\"n\">problem</span><span class=\"o\">.</span><span class=\"n\">goals</span> <span class=\"p\">,</span> <span class=\"n\">problem</span><span class=\"o\">.</span><span class=\"n\">actions</span> <span class=\"p\">)</span>\n",
       "                <span class=\"k\">for</span> <span class=\"n\">sequence</span> <span class=\"ow\">in</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">refinements</span><span class=\"p\">(</span><span class=\"n\">hla</span><span class=\"p\">,</span> <span class=\"n\">outcome</span><span class=\"p\">,</span> <span class=\"n\">hierarchy</span><span class=\"p\">):</span> <span class=\"c1\"># find refinements</span>\n",
       "                    <span class=\"n\">frontier</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">Angelic_Node</span><span class=\"p\">(</span><span class=\"n\">outcome</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"p\">,</span> <span class=\"n\">prefix</span> <span class=\"o\">+</span> <span class=\"n\">sequence</span><span class=\"o\">+</span> <span class=\"n\">suffix</span><span class=\"p\">,</span> <span class=\"n\">prefix</span><span class=\"o\">+</span><span class=\"n\">sequence</span><span class=\"o\">+</span><span class=\"n\">suffix</span><span class=\"p\">))</span>\n",
       "\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">intersects_goal</span><span class=\"p\">(</span><span class=\"n\">problem</span><span class=\"p\">,</span> <span class=\"n\">reachable_set</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        Find the intersection of the reachable states and the goal</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">return</span> <span class=\"p\">[</span><span class=\"n\">y</span> <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">reachable_set</span><span class=\"o\">.</span><span class=\"n\">keys</span><span class=\"p\">())</span> <span class=\"k\">for</span> <span class=\"n\">y</span> <span class=\"ow\">in</span> <span class=\"n\">reachable_set</span><span class=\"p\">[</span><span class=\"n\">x</span><span class=\"p\">]</span> <span class=\"k\">if</span> <span class=\"nb\">all</span><span class=\"p\">(</span><span class=\"n\">goal</span> <span class=\"ow\">in</span> <span class=\"n\">y</span> <span class=\"k\">for</span> <span class=\"n\">goal</span> <span class=\"ow\">in</span> <span class=\"n\">problem</span><span class=\"o\">.</span><span class=\"n\">goals</span><span class=\"p\">)]</span> \n",
       "\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">is_primitive</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"p\">,</span>  <span class=\"n\">library</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        checks if the hla is primitive action </span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">hla</span> <span class=\"ow\">in</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span><span class=\"p\">:</span> \n",
       "            <span class=\"n\">indices</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">i</span> <span class=\"k\">for</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s1\">&#39;HLA&#39;</span><span class=\"p\">])</span> <span class=\"k\">if</span> <span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"n\">x</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">op</span> <span class=\"o\">==</span> <span class=\"n\">hla</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">]</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"n\">indices</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s2\">&quot;steps&quot;</span><span class=\"p\">][</span><span class=\"n\">i</span><span class=\"p\">]:</span> \n",
       "                    <span class=\"k\">return</span> <span class=\"bp\">False</span>\n",
       "        <span class=\"k\">return</span> <span class=\"bp\">True</span>\n",
       "             \n",
       "\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">reach_opt</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"p\">):</span> \n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        Finds the optimistic reachable set of the sequence of actions in plan </span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"n\">reachable_set</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"n\">init</span><span class=\"p\">]}</span>\n",
       "        <span class=\"n\">optimistic_description</span> <span class=\"o\">=</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span> <span class=\"c1\">#list of angelic actions with optimistic description</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">find_reachable_set</span><span class=\"p\">(</span><span class=\"n\">reachable_set</span><span class=\"p\">,</span> <span class=\"n\">optimistic_description</span><span class=\"p\">)</span>\n",
       " \n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">reach_pes</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"p\">):</span> \n",
       "        <span class=\"sd\">&quot;&quot;&quot; </span>\n",
       "<span class=\"sd\">        Finds the pessimistic reachable set of the sequence of actions in plan</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"n\">reachable_set</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"mi\">0</span><span class=\"p\">:</span> <span class=\"p\">[</span><span class=\"n\">init</span><span class=\"p\">]}</span>\n",
       "        <span class=\"n\">pessimistic_description</span> <span class=\"o\">=</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action_pes</span> <span class=\"c1\"># list of angelic actions with pessimistic description</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">find_reachable_set</span><span class=\"p\">(</span><span class=\"n\">reachable_set</span><span class=\"p\">,</span> <span class=\"n\">pessimistic_description</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">find_reachable_set</span><span class=\"p\">(</span><span class=\"n\">reachable_set</span><span class=\"p\">,</span> <span class=\"n\">action_description</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">\tFinds the reachable states of the action_description when applied in each state of reachable set.</span>\n",
       "<span class=\"sd\">\t&quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">action_description</span><span class=\"p\">)):</span>\n",
       "            <span class=\"n\">reachable_set</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">=</span><span class=\"p\">[]</span>\n",
       "            <span class=\"k\">if</span> <span class=\"nb\">type</span><span class=\"p\">(</span><span class=\"n\">action_description</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">])</span> <span class=\"ow\">is</span> <span class=\"n\">Angelic_HLA</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">possible_actions</span> <span class=\"o\">=</span> <span class=\"n\">action_description</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">angelic_action</span><span class=\"p\">()</span>\n",
       "            <span class=\"k\">else</span><span class=\"p\">:</span> \n",
       "                <span class=\"n\">possible_actions</span> <span class=\"o\">=</span> <span class=\"n\">action_description</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">action</span> <span class=\"ow\">in</span> <span class=\"n\">possible_actions</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">for</span> <span class=\"n\">state</span> <span class=\"ow\">in</span> <span class=\"n\">reachable_set</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]:</span>\n",
       "                    <span class=\"k\">if</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">check_precond</span><span class=\"p\">(</span><span class=\"n\">state</span> <span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)</span> <span class=\"p\">:</span>\n",
       "                        <span class=\"k\">if</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">effect</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"p\">:</span>\n",
       "                            <span class=\"n\">new_state</span> <span class=\"o\">=</span> <span class=\"n\">action</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">clauses</span>\n",
       "                            <span class=\"n\">reachable_set</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_state</span><span class=\"p\">)</span>\n",
       "                        <span class=\"k\">else</span><span class=\"p\">:</span> \n",
       "                            <span class=\"n\">reachable_set</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"o\">+</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">reachable_set</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">find_hla</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"p\">,</span> <span class=\"n\">hierarchy</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        Finds the the first HLA action in plan.action, which is not primitive</span>\n",
       "<span class=\"sd\">        and its corresponding index in plan.action</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"n\">hla</span> <span class=\"o\">=</span> <span class=\"bp\">None</span>\n",
       "        <span class=\"n\">index</span> <span class=\"o\">=</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">i</span> <span class=\"ow\">in</span> <span class=\"nb\">range</span><span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span><span class=\"p\">)):</span> <span class=\"c1\"># find the first HLA in plan, that is not primitive</span>\n",
       "            <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">is_primitive</span><span class=\"p\">(</span><span class=\"n\">Node</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">parent</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]]),</span> <span class=\"n\">hierarchy</span><span class=\"p\">):</span>\n",
       "                <span class=\"n\">hla</span> <span class=\"o\">=</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"p\">]</span> \n",
       "                <span class=\"n\">index</span> <span class=\"o\">=</span> <span class=\"n\">i</span>\n",
       "                <span class=\"k\">break</span>\n",
       "        <span class=\"k\">return</span> <span class=\"p\">(</span><span class=\"n\">hla</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">)</span>\n",
       "\t\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">making_progress</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"p\">,</span> <span class=\"n\">initialPlan</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot; </span>\n",
       "<span class=\"sd\">        Not correct</span>\n",
       "\n",
       "<span class=\"sd\">        Normally should from infinite regression of refinements </span>\n",
       "<span class=\"sd\">        </span>\n",
       "<span class=\"sd\">        Only case covered: when plan contains one action (then there is no regression to be done)  </span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span><span class=\"p\">)</span><span class=\"o\">==</span><span class=\"mi\">1</span><span class=\"p\">):</span>\n",
       "            <span class=\"k\">return</span> <span class=\"bp\">False</span>\n",
       "        <span class=\"k\">return</span> <span class=\"bp\">True</span> \n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">decompose</span><span class=\"p\">(</span><span class=\"n\">hierarchy</span><span class=\"p\">,</span> <span class=\"n\">s_0</span><span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"p\">,</span> <span class=\"n\">s_f</span><span class=\"p\">,</span> <span class=\"n\">reachable_set</span><span class=\"p\">):</span>\n",
       "        <span class=\"n\">solution</span> <span class=\"o\">=</span> <span class=\"p\">[]</span> \n",
       "        <span class=\"k\">while</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action_pes</span><span class=\"p\">:</span> \n",
       "            <span class=\"n\">action</span> <span class=\"o\">=</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action_pes</span><span class=\"o\">.</span><span class=\"n\">pop</span><span class=\"p\">()</span>\n",
       "            <span class=\"n\">i</span> <span class=\"o\">=</span> <span class=\"nb\">max</span><span class=\"p\">(</span><span class=\"n\">reachable_set</span><span class=\"o\">.</span><span class=\"n\">keys</span><span class=\"p\">())</span>\n",
       "            <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">i</span><span class=\"o\">==</span><span class=\"mi\">0</span><span class=\"p\">):</span> \n",
       "                <span class=\"k\">return</span> <span class=\"n\">solution</span>\n",
       "            <span class=\"n\">s_i</span> <span class=\"o\">=</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">find_previous_state</span><span class=\"p\">(</span><span class=\"n\">s_f</span><span class=\"p\">,</span> <span class=\"n\">reachable_set</span><span class=\"p\">,</span><span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"p\">)</span> \n",
       "            <span class=\"n\">problem</span> <span class=\"o\">=</span> <span class=\"n\">Problem</span><span class=\"p\">(</span><span class=\"n\">s_i</span><span class=\"p\">,</span> <span class=\"n\">s_f</span> <span class=\"p\">,</span> <span class=\"n\">plan</span><span class=\"o\">.</span><span class=\"n\">action</span><span class=\"p\">)</span>\n",
       "            <span class=\"n\">j</span><span class=\"o\">=</span><span class=\"mi\">0</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">angelic_search</span><span class=\"p\">(</span><span class=\"n\">problem</span><span class=\"p\">,</span> <span class=\"n\">hierarchy</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">Angelic_Node</span><span class=\"p\">(</span><span class=\"n\">s_i</span><span class=\"p\">,</span> <span class=\"n\">Node</span><span class=\"p\">(</span><span class=\"bp\">None</span><span class=\"p\">),</span> <span class=\"p\">[</span><span class=\"n\">action</span><span class=\"p\">],[</span><span class=\"n\">action</span><span class=\"p\">])]):</span>\n",
       "                <span class=\"n\">solution</span><span class=\"o\">.</span><span class=\"n\">insert</span><span class=\"p\">(</span><span class=\"n\">j</span><span class=\"p\">,</span><span class=\"n\">x</span><span class=\"p\">)</span>\n",
       "                <span class=\"n\">j</span><span class=\"o\">+=</span><span class=\"mi\">1</span>\n",
       "            <span class=\"n\">s_f</span> <span class=\"o\">=</span> <span class=\"n\">s_i</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">solution</span>\n",
       "\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">find_previous_state</span><span class=\"p\">(</span><span class=\"n\">s_f</span><span class=\"p\">,</span> <span class=\"n\">reachable_set</span><span class=\"p\">,</span> <span class=\"n\">i</span><span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        Given a final state s_f and an action finds a state s_i in reachable_set </span>\n",
       "<span class=\"sd\">        such that when action is applied to state s_i returns s_f.  </span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"n\">s_i</span> <span class=\"o\">=</span> <span class=\"n\">reachable_set</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">][</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">state</span> <span class=\"ow\">in</span> <span class=\"n\">reachable_set</span><span class=\"p\">[</span><span class=\"n\">i</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">s_f</span> <span class=\"ow\">in</span> <span class=\"p\">[</span><span class=\"n\">x</span> <span class=\"k\">for</span> <span class=\"n\">x</span> <span class=\"ow\">in</span> <span class=\"n\">Problem</span><span class=\"o\">.</span><span class=\"n\">reach_pes</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"n\">Angelic_Node</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"p\">[</span><span class=\"n\">action</span><span class=\"p\">],[</span><span class=\"n\">action</span><span class=\"p\">]))[</span><span class=\"mi\">1</span><span class=\"p\">]]:</span>\n",
       "                <span class=\"n\">s_i</span> <span class=\"o\">=</span><span class=\"n\">state</span>\n",
       "                <span class=\"k\">break</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">s_i</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(Problem)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## HLA\n",
    "To be able to model a real-world planning problem properly, it is  essential to be able to represent a _high-level action (HLA)_ that can be hierarchically reduced to primitive actions."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 130,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">class</span> <span class=\"nc\">HLA</span><span class=\"p\">(</span><span class=\"n\">Action</span><span class=\"p\">):</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    Define Actions for the real-world (that may be refined further), and satisfy resource</span>\n",
       "<span class=\"sd\">    constraints.</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "    <span class=\"n\">unique_group</span> <span class=\"o\">=</span> <span class=\"mi\">1</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">duration</span><span class=\"o\">=</span><span class=\"mi\">0</span><span class=\"p\">,</span>\n",
       "                 <span class=\"n\">consume</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"n\">use</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        As opposed to actions, to define HLA, we have added constraints.</span>\n",
       "<span class=\"sd\">        duration holds the amount of time required to execute the task</span>\n",
       "<span class=\"sd\">        consumes holds a dictionary representing the resources the task consumes</span>\n",
       "<span class=\"sd\">        uses holds a dictionary representing the resources the task uses</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"n\">precond</span> <span class=\"o\">=</span> <span class=\"n\">precond</span> <span class=\"ow\">or</span> <span class=\"p\">[</span><span class=\"bp\">None</span><span class=\"p\">]</span>\n",
       "        <span class=\"n\">effect</span> <span class=\"o\">=</span> <span class=\"n\">effect</span> <span class=\"ow\">or</span> <span class=\"p\">[</span><span class=\"bp\">None</span><span class=\"p\">]</span>\n",
       "        <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"n\">precond</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">duration</span> <span class=\"o\">=</span> <span class=\"n\">duration</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">consumes</span> <span class=\"o\">=</span> <span class=\"n\">consume</span> <span class=\"ow\">or</span> <span class=\"p\">{}</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">uses</span> <span class=\"o\">=</span> <span class=\"n\">use</span> <span class=\"ow\">or</span> <span class=\"p\">{}</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">completed</span> <span class=\"o\">=</span> <span class=\"bp\">False</span>\n",
       "        <span class=\"c1\"># self.priority = -1 #  must be assigned in relation to other HLAs</span>\n",
       "        <span class=\"c1\"># self.job_group = -1 #  must be assigned in relation to other HLAs</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">do_action</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">job_order</span><span class=\"p\">,</span> <span class=\"n\">available_resources</span><span class=\"p\">,</span> <span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        An HLA based version of act - along with knowledge base updation, it handles</span>\n",
       "<span class=\"sd\">        resource checks, and ensures the actions are executed in the correct order.</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"c1\"># print(self.name)</span>\n",
       "        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">has_usable_resource</span><span class=\"p\">(</span><span class=\"n\">available_resources</span><span class=\"p\">):</span>\n",
       "            <span class=\"k\">raise</span> <span class=\"ne\">Exception</span><span class=\"p\">(</span><span class=\"s1\">&#39;Not enough usable resources to execute {}&#39;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">))</span>\n",
       "        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">has_consumable_resource</span><span class=\"p\">(</span><span class=\"n\">available_resources</span><span class=\"p\">):</span>\n",
       "            <span class=\"k\">raise</span> <span class=\"ne\">Exception</span><span class=\"p\">(</span><span class=\"s1\">&#39;Not enough consumable resources to execute {}&#39;</span><span class=\"o\">.</span><span class=\"n\">format</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">))</span>\n",
       "        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">inorder</span><span class=\"p\">(</span><span class=\"n\">job_order</span><span class=\"p\">):</span>\n",
       "            <span class=\"k\">raise</span> <span class=\"ne\">Exception</span><span class=\"p\">(</span><span class=\"s2\">&quot;Can&#39;t execute {} - execute prerequisite actions first&quot;</span><span class=\"o\">.</span>\n",
       "                            <span class=\"n\">format</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">))</span>\n",
       "        <span class=\"n\">kb</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">act</span><span class=\"p\">(</span><span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"n\">args</span><span class=\"p\">)</span>  <span class=\"c1\"># update knowledge base</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">resource</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">consumes</span><span class=\"p\">:</span>  <span class=\"c1\"># remove consumed resources</span>\n",
       "            <span class=\"n\">available_resources</span><span class=\"p\">[</span><span class=\"n\">resource</span><span class=\"p\">]</span> <span class=\"o\">-=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">consumes</span><span class=\"p\">[</span><span class=\"n\">resource</span><span class=\"p\">]</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">completed</span> <span class=\"o\">=</span> <span class=\"bp\">True</span>  <span class=\"c1\"># set the task status to complete</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">kb</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">has_consumable_resource</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">available_resources</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        Ensure there are enough consumable resources for this action to execute.</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">resource</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">consumes</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">available_resources</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">resource</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">False</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">available_resources</span><span class=\"p\">[</span><span class=\"n\">resource</span><span class=\"p\">]</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">consumes</span><span class=\"p\">[</span><span class=\"n\">resource</span><span class=\"p\">]:</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">False</span>\n",
       "        <span class=\"k\">return</span> <span class=\"bp\">True</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">has_usable_resource</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">available_resources</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        Ensure there are enough usable resources for this action to execute.</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">resource</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">uses</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">available_resources</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">resource</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">False</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">available_resources</span><span class=\"p\">[</span><span class=\"n\">resource</span><span class=\"p\">]</span> <span class=\"o\">&lt;</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">uses</span><span class=\"p\">[</span><span class=\"n\">resource</span><span class=\"p\">]:</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">False</span>\n",
       "        <span class=\"k\">return</span> <span class=\"bp\">True</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">inorder</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">job_order</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">        Ensure that all the jobs that had to be executed before the current one have been</span>\n",
       "<span class=\"sd\">        successfully executed.</span>\n",
       "<span class=\"sd\">        &quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">jobs</span> <span class=\"ow\">in</span> <span class=\"n\">job_order</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"bp\">self</span> <span class=\"ow\">in</span> <span class=\"n\">jobs</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">for</span> <span class=\"n\">job</span> <span class=\"ow\">in</span> <span class=\"n\">jobs</span><span class=\"p\">:</span>\n",
       "                    <span class=\"k\">if</span> <span class=\"n\">job</span> <span class=\"ow\">is</span> <span class=\"bp\">self</span><span class=\"p\">:</span>\n",
       "                        <span class=\"k\">return</span> <span class=\"bp\">True</span>\n",
       "                    <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">job</span><span class=\"o\">.</span><span class=\"n\">completed</span><span class=\"p\">:</span>\n",
       "                        <span class=\"k\">return</span> <span class=\"bp\">False</span>\n",
       "        <span class=\"k\">return</span> <span class=\"bp\">True</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(HLA)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In addition to preconditions and effects, an object of the `HLA` class also stores:\n",
    "- the `duration` of the HLA\n",
    "- the quantity of consumption of _consumable_ resources\n",
    "- the quantity of _reusable_ resources used\n",
    "- a bool `completed` denoting if the `HLA` has been completed\n",
    "\n",
    "The class also has some useful helper methods:\n",
    "- `do_action`: checks if required consumable and reusable resources are available and if so, executes the action.\n",
    "- `has_consumable_resource`: checks if there exists sufficient quantity of the required consumable resource.\n",
    "- `has_usable_resource`: checks if reusable resources are available and not already engaged.\n",
    "- `inorder`: ensures that all the jobs that had to be executed before the current one have been successfully executed."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PLANNING PROBLEMS\n",
    "---\n",
    "## Job-shop Problem\n",
    "This is a simple problem involving the assembly of two cars simultaneously.\n",
    "The problem consists of two jobs, each of the form [`AddEngine`, `AddWheels`, `Inspect`] to be performed on two cars with different requirements and availability of resources.\n",
    "<br>\n",
    "Let's look at how the `job_shop_problem` has been defined on the  module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 138,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">job_shop_problem</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    [Figure 11.1] JOB-SHOP-PROBLEM</span>\n",
       "\n",
       "<span class=\"sd\">    A job-shop scheduling problem for assembling two cars,</span>\n",
       "<span class=\"sd\">    with resource and ordering constraints.</span>\n",
       "\n",
       "<span class=\"sd\">    Example:</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; from planning import *</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; p = job_shop_problem()</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; p.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; p.act(p.jobs[1][0])</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; p.act(p.jobs[1][1])</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; p.act(p.jobs[1][2])</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; p.act(p.jobs[0][0])</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; p.act(p.jobs[0][1])</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; p.goal_test()</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; p.act(p.jobs[0][2])</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; p.goal_test()</span>\n",
       "<span class=\"sd\">    True</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt;</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "    <span class=\"n\">resources</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s1\">&#39;EngineHoists&#39;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">,</span> <span class=\"s1\">&#39;WheelStations&#39;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"s1\">&#39;Inspectors&#39;</span><span class=\"p\">:</span> <span class=\"mi\">2</span><span class=\"p\">,</span> <span class=\"s1\">&#39;LugNuts&#39;</span><span class=\"p\">:</span> <span class=\"mi\">500</span><span class=\"p\">}</span>\n",
       "\n",
       "    <span class=\"n\">add_engine1</span> <span class=\"o\">=</span> <span class=\"n\">HLA</span><span class=\"p\">(</span><span class=\"s1\">&#39;AddEngine1&#39;</span><span class=\"p\">,</span> <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;~Has(C1, E1)&#39;</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;Has(C1, E1)&#39;</span><span class=\"p\">,</span> <span class=\"n\">duration</span><span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"n\">use</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;EngineHoists&#39;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">})</span>\n",
       "    <span class=\"n\">add_engine2</span> <span class=\"o\">=</span> <span class=\"n\">HLA</span><span class=\"p\">(</span><span class=\"s1\">&#39;AddEngine2&#39;</span><span class=\"p\">,</span> <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;~Has(C2, E2)&#39;</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;Has(C2, E2)&#39;</span><span class=\"p\">,</span> <span class=\"n\">duration</span><span class=\"o\">=</span><span class=\"mi\">60</span><span class=\"p\">,</span> <span class=\"n\">use</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;EngineHoists&#39;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">})</span>\n",
       "    <span class=\"n\">add_wheels1</span> <span class=\"o\">=</span> <span class=\"n\">HLA</span><span class=\"p\">(</span><span class=\"s1\">&#39;AddWheels1&#39;</span><span class=\"p\">,</span> <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;~Has(C1, W1)&#39;</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;Has(C1, W1)&#39;</span><span class=\"p\">,</span> <span class=\"n\">duration</span><span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">,</span> <span class=\"n\">use</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;WheelStations&#39;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">},</span> <span class=\"n\">consume</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;LugNuts&#39;</span><span class=\"p\">:</span> <span class=\"mi\">20</span><span class=\"p\">})</span>\n",
       "    <span class=\"n\">add_wheels2</span> <span class=\"o\">=</span> <span class=\"n\">HLA</span><span class=\"p\">(</span><span class=\"s1\">&#39;AddWheels2&#39;</span><span class=\"p\">,</span> <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;~Has(C2, W2)&#39;</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;Has(C2, W2)&#39;</span><span class=\"p\">,</span> <span class=\"n\">duration</span><span class=\"o\">=</span><span class=\"mi\">15</span><span class=\"p\">,</span> <span class=\"n\">use</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;WheelStations&#39;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">},</span> <span class=\"n\">consume</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;LugNuts&#39;</span><span class=\"p\">:</span> <span class=\"mi\">20</span><span class=\"p\">})</span>\n",
       "    <span class=\"n\">inspect1</span> <span class=\"o\">=</span> <span class=\"n\">HLA</span><span class=\"p\">(</span><span class=\"s1\">&#39;Inspect1&#39;</span><span class=\"p\">,</span> <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;~Inspected(C1)&#39;</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;Inspected(C1)&#39;</span><span class=\"p\">,</span> <span class=\"n\">duration</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"n\">use</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;Inspectors&#39;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">})</span>\n",
       "    <span class=\"n\">inspect2</span> <span class=\"o\">=</span> <span class=\"n\">HLA</span><span class=\"p\">(</span><span class=\"s1\">&#39;Inspect2&#39;</span><span class=\"p\">,</span> <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;~Inspected(C2)&#39;</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;Inspected(C2)&#39;</span><span class=\"p\">,</span> <span class=\"n\">duration</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">,</span> <span class=\"n\">use</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s1\">&#39;Inspectors&#39;</span><span class=\"p\">:</span> <span class=\"mi\">1</span><span class=\"p\">})</span>\n",
       "\n",
       "    <span class=\"n\">actions</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">add_engine1</span><span class=\"p\">,</span> <span class=\"n\">add_engine2</span><span class=\"p\">,</span> <span class=\"n\">add_wheels1</span><span class=\"p\">,</span> <span class=\"n\">add_wheels2</span><span class=\"p\">,</span> <span class=\"n\">inspect1</span><span class=\"p\">,</span> <span class=\"n\">inspect2</span><span class=\"p\">]</span>\n",
       "\n",
       "    <span class=\"n\">job_group1</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">add_engine1</span><span class=\"p\">,</span> <span class=\"n\">add_wheels1</span><span class=\"p\">,</span> <span class=\"n\">inspect1</span><span class=\"p\">]</span>\n",
       "    <span class=\"n\">job_group2</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">add_engine2</span><span class=\"p\">,</span> <span class=\"n\">add_wheels2</span><span class=\"p\">,</span> <span class=\"n\">inspect2</span><span class=\"p\">]</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">Problem</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;Car(C1) &amp; Car(C2) &amp; Wheels(W1) &amp; Wheels(W2) &amp; Engine(E2) &amp; Engine(E2) &amp; ~Has(C1, E1) &amp; ~Has(C2, E2) &amp; ~Has(C1, W1) &amp; ~Has(C2, W2) &amp; ~Inspected(C1) &amp; ~Inspected(C2)&#39;</span><span class=\"p\">,</span>\n",
       "                   <span class=\"n\">goals</span><span class=\"o\">=</span><span class=\"s1\">&#39;Has(C1, W1) &amp; Has(C1, E1) &amp; Inspected(C1) &amp; Has(C2, W2) &amp; Has(C2, E2) &amp; Inspected(C2)&#39;</span><span class=\"p\">,</span>\n",
       "                   <span class=\"n\">actions</span><span class=\"o\">=</span><span class=\"n\">actions</span><span class=\"p\">,</span>\n",
       "                   <span class=\"n\">jobs</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">job_group1</span><span class=\"p\">,</span> <span class=\"n\">job_group2</span><span class=\"p\">],</span>\n",
       "                   <span class=\"n\">resources</span><span class=\"o\">=</span><span class=\"n\">resources</span><span class=\"p\">)</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(job_shop_problem)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The states of this problem are:\n",
    "<br>\n",
    "<br>\n",
    "**Has(x, y)**: Car **'x'** _has_ **'y'** where **'y'** can be an Engine or a Wheel.\n",
    "\n",
    "**~Has(x, y)**: Car **'x'** does _not have_ **'y'** where **'y'** can be an Engine or a Wheel.\n",
    "\n",
    "**Inspected(c)**: Car **'c'** has been _inspected_.\n",
    "\n",
    "**~Inspected(c)**: Car **'c'** has _not_ been inspected.\n",
    "\n",
    "In the initial state, `C1` and `C2` are cars and neither have an engine or wheels and haven't been inspected.\n",
    "`E1` and `E2` are engines.\n",
    "`W1` and `W2` are wheels.\n",
    "<br>\n",
    "Our goal is to have engines and wheels on both cars and to get them inspected. We will discuss how to achieve this.\n",
    "<br>\n",
    "Let's define an object of the `job_shop_problem`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 139,
   "metadata": {},
   "outputs": [],
   "source": [
    "jobShopProblem = job_shop_problem()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before taking any actions, we will check if `jobShopProblem` has reached its goal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 140,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "print(jobShopProblem.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We now define a possible solution that can help us reach the goal. \n",
    "The actions are then carried out on the `jobShopProblem` object."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The following actions are available to us:\n",
    "\n",
    "**AddEngine1**: Adds an engine to the car C1. Takes 30 minutes to complete and uses an engine hoist.\n",
    " \n",
    "**AddEngine2**: Adds an engine to the car C2. Takes 60 minutes to complete and uses an engine hoist.\n",
    "\n",
    "**AddWheels1**: Adds wheels to car C1. Takes 30 minutes to complete. Uses a wheel station and consumes 20 lug nuts.\n",
    "\n",
    "**AddWheels2**: Adds wheels to car C2. Takes 15 minutes to complete. Uses a wheel station and consumes 20 lug nuts as well.\n",
    "\n",
    "**Inspect1**: Gets car C1 inspected. Requires 10 minutes of inspection by one inspector.\n",
    "\n",
    "**Inspect2**: Gets car C2 inspected. Requires 10 minutes of inspection by one inspector."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 141,
   "metadata": {},
   "outputs": [],
   "source": [
    "solution = [jobShopProblem.jobs[1][0],\n",
    "            jobShopProblem.jobs[1][1],\n",
    "            jobShopProblem.jobs[1][2],\n",
    "            jobShopProblem.jobs[0][0],\n",
    "            jobShopProblem.jobs[0][1],\n",
    "            jobShopProblem.jobs[0][2]]\n",
    "\n",
    "for action in solution:\n",
    "    jobShopProblem.act(action)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 142,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
   "source": [
    "print(jobShopProblem.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is a valid solution and one of many correct ways to solve this problem."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Double tennis problem\n",
    "This problem is a simple case of a multiactor planning problem, where two agents act at once and can simultaneously change the current state of the problem. \n",
    "A correct plan is one that, if executed by the actors, achieves the goal.\n",
    "In the true multiagent setting, of course, the agents may not agree to execute any particular plan, but atleast they will know what plans _would_ work if they _did_ agree to execute them.\n",
    "<br>\n",
    "In the double tennis problem, two actors A and B are playing together and can be in one of four locations: `LeftBaseLine`, `RightBaseLine`, `LeftNet` and `RightNet`.\n",
    "The ball can be returned only if a player is in the right place.\n",
    "Each action must include the actor as an argument.\n",
    "<br>\n",
    "Let's first look at the definition of the `double_tennis_problem` in the module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 172,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\"\n",
       "   \"http://www.w3.org/TR/html4/strict.dtd\">\n",
       "\n",
       "<html>\n",
       "<head>\n",
       "  <title></title>\n",
       "  <meta http-equiv=\"content-type\" content=\"text/html; charset=None\">\n",
       "  <style type=\"text/css\">\n",
       "td.linenos { background-color: #f0f0f0; padding-right: 10px; }\n",
       "span.lineno { background-color: #f0f0f0; padding: 0 5px 0 5px; }\n",
       "pre { line-height: 125%; }\n",
       "body .hll { background-color: #ffffcc }\n",
       "body  { background: #f8f8f8; }\n",
       "body .c { color: #408080; font-style: italic } /* Comment */\n",
       "body .err { border: 1px solid #FF0000 } /* Error */\n",
       "body .k { color: #008000; font-weight: bold } /* Keyword */\n",
       "body .o { color: #666666 } /* Operator */\n",
       "body .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       "body .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       "body .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       "body .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       "body .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       "body .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       "body .gd { color: #A00000 } /* Generic.Deleted */\n",
       "body .ge { font-style: italic } /* Generic.Emph */\n",
       "body .gr { color: #FF0000 } /* Generic.Error */\n",
       "body .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       "body .gi { color: #00A000 } /* Generic.Inserted */\n",
       "body .go { color: #888888 } /* Generic.Output */\n",
       "body .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       "body .gs { font-weight: bold } /* Generic.Strong */\n",
       "body .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       "body .gt { color: #0044DD } /* Generic.Traceback */\n",
       "body .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       "body .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       "body .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       "body .kp { color: #008000 } /* Keyword.Pseudo */\n",
       "body .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       "body .kt { color: #B00040 } /* Keyword.Type */\n",
       "body .m { color: #666666 } /* Literal.Number */\n",
       "body .s { color: #BA2121 } /* Literal.String */\n",
       "body .na { color: #7D9029 } /* Name.Attribute */\n",
       "body .nb { color: #008000 } /* Name.Builtin */\n",
       "body .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       "body .no { color: #880000 } /* Name.Constant */\n",
       "body .nd { color: #AA22FF } /* Name.Decorator */\n",
       "body .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       "body .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       "body .nf { color: #0000FF } /* Name.Function */\n",
       "body .nl { color: #A0A000 } /* Name.Label */\n",
       "body .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       "body .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       "body .nv { color: #19177C } /* Name.Variable */\n",
       "body .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       "body .w { color: #bbbbbb } /* Text.Whitespace */\n",
       "body .mb { color: #666666 } /* Literal.Number.Bin */\n",
       "body .mf { color: #666666 } /* Literal.Number.Float */\n",
       "body .mh { color: #666666 } /* Literal.Number.Hex */\n",
       "body .mi { color: #666666 } /* Literal.Number.Integer */\n",
       "body .mo { color: #666666 } /* Literal.Number.Oct */\n",
       "body .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       "body .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       "body .sc { color: #BA2121 } /* Literal.String.Char */\n",
       "body .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       "body .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       "body .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       "body .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       "body .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       "body .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       "body .sx { color: #008000 } /* Literal.String.Other */\n",
       "body .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       "body .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       "body .ss { color: #19177C } /* Literal.String.Symbol */\n",
       "body .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       "body .fm { color: #0000FF } /* Name.Function.Magic */\n",
       "body .vc { color: #19177C } /* Name.Variable.Class */\n",
       "body .vg { color: #19177C } /* Name.Variable.Global */\n",
       "body .vi { color: #19177C } /* Name.Variable.Instance */\n",
       "body .vm { color: #19177C } /* Name.Variable.Magic */\n",
       "body .il { color: #666666 } /* Literal.Number.Integer.Long */\n",
       "\n",
       "  </style>\n",
       "</head>\n",
       "<body>\n",
       "<h2></h2>\n",
       "\n",
       "<div class=\"highlight\"><pre><span></span><span class=\"k\">def</span> <span class=\"nf\">double_tennis_problem</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    [Figure 11.10] DOUBLE-TENNIS-PROBLEM</span>\n",
       "\n",
       "<span class=\"sd\">    A multiagent planning problem involving two partner tennis players</span>\n",
       "<span class=\"sd\">    trying to return an approaching ball and repositioning around in the court.</span>\n",
       "\n",
       "<span class=\"sd\">    Example:</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; from planning import *</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; dtp = double_tennis_problem()</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; goal_test(dtp.goals, dtp.init)</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; dtp.act(expr(&#39;Go(A, RightBaseLine, LeftBaseLine)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; dtp.act(expr(&#39;Hit(A, Ball, RightBaseLine)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; goal_test(dtp.goals, dtp.init)</span>\n",
       "<span class=\"sd\">    False</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; dtp.act(expr(&#39;Go(A, LeftNet, RightBaseLine)&#39;))</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt; goal_test(dtp.goals, dtp.init)</span>\n",
       "<span class=\"sd\">    True</span>\n",
       "<span class=\"sd\">    &gt;&gt;&gt;</span>\n",
       "<span class=\"sd\">    &quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PlanningProblem</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(A, LeftBaseLine) &amp; At(B, RightNet) &amp; Approaching(Ball, RightBaseLine) &amp; Partner(A, B) &amp; Partner(B, A)&#39;</span><span class=\"p\">,</span>\n",
       "                             <span class=\"n\">goals</span><span class=\"o\">=</span><span class=\"s1\">&#39;Returned(Ball) &amp; At(a, LeftNet) &amp; At(a, RightNet)&#39;</span><span class=\"p\">,</span>\n",
       "                             <span class=\"n\">actions</span><span class=\"o\">=</span><span class=\"p\">[</span><span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Hit(actor, Ball, loc)&#39;</span><span class=\"p\">,</span>\n",
       "                                             <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;Approaching(Ball, loc) &amp; At(actor, loc)&#39;</span><span class=\"p\">,</span>\n",
       "                                             <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;Returned(Ball)&#39;</span><span class=\"p\">),</span>\n",
       "                                      <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Go(actor, to, loc)&#39;</span><span class=\"p\">,</span> \n",
       "                                             <span class=\"n\">precond</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(actor, loc)&#39;</span><span class=\"p\">,</span>\n",
       "                                             <span class=\"n\">effect</span><span class=\"o\">=</span><span class=\"s1\">&#39;At(actor, to) &amp; ~At(actor, loc)&#39;</span><span class=\"p\">)])</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(double_tennis_problem)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The states of this problem are:\n",
    "\n",
    "**Approaching(Ball, loc)**: The `Ball` is approaching the location `loc`.\n",
    "\n",
    "**Returned(Ball)**: One of the actors successfully hit the approaching ball from the correct location which caused it to return to the other side.\n",
    "\n",
    "**At(actor, loc)**: `actor` is at location `loc`.\n",
    "\n",
    "**~At(actor, loc)**: `actor` is _not_ at location `loc`.\n",
    "\n",
    "Let's now define an object of `double_tennis_problem`.\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 173,
   "metadata": {},
   "outputs": [],
   "source": [
    "doubleTennisProblem = double_tennis_problem()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Before taking any actions, we will check if `doubleTennisProblem` has reached the goal."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 174,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
   "source": [
    "print(doubleTennisProblem.goal_test())"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we can see, the goal hasn't been reached. \n",
    "We now define a possible solution that can help us reach the goal of having the ball returned.\n",
    "The actions will then be carried out on the `doubleTennisProblem` object."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The actions available to us are the following:\n",
    "\n",
    "**Hit(actor, ball, loc)**: returns an approaching ball if `actor` is present at the `loc` that the ball is approaching.\n",
    "\n",
    "**Go(actor, to, loc)**: moves an `actor` from location `loc` to location `to`.\n",
    "\n",
    "We notice something different in this problem though, \n",
    "which is quite unlike any other problem we have seen so far. \n",
    "The goal state of the problem contains a variable `a`.\n",
    "This happens sometimes in multiagent planning problems \n",
    "and it means that it doesn't matter _which_ actor is at the `LeftNet` or the `RightNet`, as long as there is atleast one actor at either `LeftNet` or `RightNet`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 175,
   "metadata": {},
   "outputs": [],
   "source": [
    "solution = [expr('Go(A, RightBaseLine, LeftBaseLine)'),\n",
    "            expr('Hit(A, Ball, RightBaseLine)'),\n",
    "            expr('Go(A, LeftNet, RightBaseLine)')]\n",
    "\n",
    "for action in solution:\n",
    "    doubleTennisProblem.act(action)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 178,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 178,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "doubleTennisProblem.goal_test()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It has now successfully reached its goal, ie, to return the approaching ball."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.5.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
