planning.ipynb 397 ko
Newer Older
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "# Planning\n",
    "#### Chapters 10-11\n",
    "----"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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",
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
    "\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",
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
    "\n",
    "Let's start by importing everything from the planning module."
jeff3456's avatar
jeff3456 a validé
  {
   "cell_type": "code",
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "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": 2,
   "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": 3,
   "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",
       "        <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",
       "            <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",
       "        <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": 4,
   "metadata": {
    "collapsed": true
   },
   "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": 5,
   "metadata": {
    "collapsed": true
   },
   "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": 6,
   "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": 6,
     "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": 7,
   "metadata": {
    "collapsed": true
   },
   "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": 8,
   "metadata": {
    "collapsed": true
   },
   "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": 9,
   "metadata": {
    "collapsed": true
   },
   "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": 10,
   "metadata": {
    "collapsed": true
   },
   "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": 11,
   "metadata": {
    "collapsed": true
   },
   "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": 12,
   "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",
       "    <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": 13,
   "metadata": {
    "collapsed": true
   },
   "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": 14,
   "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": 15,
   "metadata": {
    "collapsed": true
   },
   "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": 16,
   "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": 17,
   "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",
       "    <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": 18,
   "metadata": {
    "collapsed": true
   },
   "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": 19,
   "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": 20,
   "metadata": {
    "collapsed": true
   },
   "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": 21,
   "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": 22,
   "metadata": {
    "collapsed": true
   },
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "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": 23,
   "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": 24,
   "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",
       "<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)"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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": 25,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "source": [
    "threeBlockTower = three_block_tower()"
   "cell_type": "markdown",
   "metadata": {},
jeff3456's avatar
jeff3456 a validé
   "source": [
    "Before taking any actions, we will check if `threeBlockTower` has reached its goal:"
   "cell_type": "code",
   "execution_count": 26,
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    }
   ],
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "source": [
    "print(threeBlockTower.goal_test())"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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",
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
    "\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"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {
    "collapsed": true
   },
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "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)"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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."
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    }
   ],
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "source": [
    "print(threeBlockTower.goal_test())"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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": {},
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "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."
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "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",
       "<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"
      ],
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
      "text/plain": [
       "<IPython.core.display.HTML object>"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
      ]
     },
     "metadata": {},
     "output_type": "display_data"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
    }
   ],
   "source": [
    "psource(simple_blocks_world)"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**On(x, y):** The block **'x'** is on **'y'**. Both **'x'** and **'y'** have to be blocks.\n",
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
    "\n",
    "**~On(x, y):** The block **'x'** is _not_ on **'y'**. Both **'x'** and **'y'** have to be blocks.\n",
    "**OnTable(x):** The block **'x'** is on the table.\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."
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {
    "collapsed": true
   },
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "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": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    "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",
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
    "\n",
    "The actions available to us are the following: MoveToTable, Move\n",
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
    "\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"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": true
   },
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "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)"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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."
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "source": [
    "print(simpleBlocksWorld.goal_test())"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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."
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
  {
   "cell_type": "code",
   "execution_count": 34,
   "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",
       "<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",
    "**~At(x):** Indicates that we are currently _not_ at **'x'**.\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": 35,
   "metadata": {
    "collapsed": true
   },
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "outputs": [],
    "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": 36,
   "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",
    "**Buy(x, store):** Buy an item **'x'** from a **'store'** given that the **'store'** sells **'x'**.\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": 37,
   "metadata": {
    "collapsed": true
   },
   "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": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    "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": 39,
   "metadata": {},
2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482 2483 2484 2485 2486 2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 2522 2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 2596 2597 2598 2599 2600 2601 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729 2730 2731 2732 2733 2734 2735 2736 2737 2738 2739 2740 2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753
   "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": 40,
   "metadata": {
    "collapsed": true
   },
   "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": 41,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 41,
     "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": 42,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "solution = [expr('RightSock'),\n",
    "            expr('RightShoe'),\n",
    "            expr('LeftSock'),\n",
    "            expr('LeftShoe')]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 43,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 43,
     "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": 44,
   "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": 45,
   "metadata": {
    "collapsed": true
   },
   "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": 46,
   "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": 47,
   "metadata": {
    "collapsed": true
   },
   "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": 48,
   "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": 49,
   "metadata": {},
   "outputs": [
    {
     "ename": "Exception",
     "evalue": "Action 'Bake(Cake)' pre-conditions not satisfied",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mException\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-49-b340f831489f>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m()\u001b[0m\n\u001b[0;32m      5\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      6\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0maction\u001b[0m \u001b[1;32min\u001b[0m \u001b[0msolution\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 7\u001b[1;33m     \u001b[0mcakeProblem\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mact\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0maction\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;32m~\\Documents\\Python\\Data Science\\Machine Learning\\Aima\\planning.py\u001b[0m in \u001b[0;36mact\u001b[1;34m(self, action)\u001b[0m\n\u001b[0;32m     58\u001b[0m             \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Action '{}' not found\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0maction_name\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     59\u001b[0m         \u001b[1;32mif\u001b[0m \u001b[1;32mnot\u001b[0m \u001b[0mlist_action\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcheck_precond\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0minit\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 60\u001b[1;33m             \u001b[1;32mraise\u001b[0m \u001b[0mException\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;34m\"Action '{}' pre-conditions not satisfied\"\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mformat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0maction\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     61\u001b[0m         \u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0minit\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlist_action\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mself\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0minit\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0margs\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mclauses\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     62\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;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": [
    "## SOLVING PLANNING PROBLEMS\n",
    "----\n",
    "### GRAPHPLAN\n",
    "<br>\n",
    "The GraphPlan algorithm is a popular method of solving classical planning problems.\n",
    "Before we get into the details of the algorithm, let's look at a special data structure called **planning graph**, used to give better heuristic estimates and plays a key role in the GraphPlan algorithm."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Planning Graph\n",
    "A planning graph is a directed graph organized into levels. \n",
    "Each level contains information about the current state of the knowledge base and the possible state-action links to and from that level.\n",
    "The first level contains the initial state with nodes representing each fluent that holds in that level.\n",
    "This level has state-action links linking each state to valid actions in that state.\n",
    "Each action is linked to all its preconditions and its effect states.\n",
    "Based on these effects, the next level is constructed.\n",
    "The next level contains similarly structured information about the next state.\n",
    "In this way, the graph is expanded using state-action links till we reach a state where all the required goals hold true simultaneously.\n",
    "We can say that we have reached our goal if none of the goal states in the current level are mutually exclusive.\n",
    "This will be explained in detail later.\n",
    "<br>\n",
    "Planning graphs only work for propositional planning problems, hence we need to eliminate all variables by generating all possible substitutions.\n",
    "<br>\n",
    "For example, the planning graph of the `have_cake_and_eat_cake_too` problem might look like this\n",
    "![title](images/cake_graph.jpg)\n",
    "<br>\n",
    "The black lines indicate links between states and actions.\n",
    "<br>\n",
2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836 2837 2838 2839 2840 2841 2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901 2902 2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560
    "In every planning problem, we are allowed to carry out the `no-op` action, ie, we can choose no action for a particular state.\n",
    "These are called 'Persistence' actions and are represented in the graph by the small square boxes.\n",
    "In technical terms, a persistence action has effects same as its preconditions.\n",
    "This enables us to carry a state to the next level.\n",
    "<br>\n",
    "<br>\n",
    "The gray lines indicate mutual exclusivity.\n",
    "This means that the actions connected bya gray line cannot be taken together.\n",
    "Mutual exclusivity (mutex) occurs in the following cases:\n",
    "1. **Inconsistent effects**: One action negates the effect of the other. For example, _Eat(Cake)_ and the persistence of _Have(Cake)_ have inconsistent effects because they disagree on the effect _Have(Cake)_\n",
    "2. **Interference**: One of the effects of an action is the negation of a precondition of the other. For example, _Eat(Cake)_ interferes with the persistence of _Have(Cake)_ by negating its precondition.\n",
    "3. **Competing needs**: One of the preconditions of one action is mutually exclusive with a precondition of the other. For example, _Bake(Cake)_ and _Eat(Cake)_ are mutex because they compete on the value of the _Have(Cake)_ precondition."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the module, planning graphs have been implemented using two classes, `Level` which stores data for a particular level and `Graph` which connects multiple levels together.\n",
    "Let's look at the `Level` class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "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\">Level</span><span class=\"p\">:</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    Contains the state of the planning problem</span>\n",
       "<span class=\"sd\">    and exhaustive list of actions which use the</span>\n",
       "<span class=\"sd\">    states as pre-condition.</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\">kb</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Initializes variables to hold state and action details of a level&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kb</span> <span class=\"o\">=</span> <span class=\"n\">kb</span>\n",
       "        <span class=\"c1\"># current state</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_state</span> <span class=\"o\">=</span> <span class=\"n\">kb</span><span class=\"o\">.</span><span class=\"n\">clauses</span>\n",
       "        <span class=\"c1\"># current action to state link</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_action_links</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n",
       "        <span class=\"c1\"># current state to action link</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_state_links</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n",
       "        <span class=\"c1\"># current action to next state link</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_action_links</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n",
       "        <span class=\"c1\"># next state to current action link</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_state_links</span> <span class=\"o\">=</span> <span class=\"p\">{}</span>\n",
       "        <span class=\"c1\"># mutually exclusive actions</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mutex</span> <span class=\"o\">=</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\">actions</span><span class=\"p\">,</span> <span class=\"n\">objects</span><span class=\"p\">):</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">build</span><span class=\"p\">(</span><span class=\"n\">actions</span><span class=\"p\">,</span> <span class=\"n\">objects</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">find_mutex</span><span class=\"p\">()</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">separate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">e</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Separates an iterable of elements into positive and negative parts&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">positive</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"n\">negative</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\">e</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\">negative</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\">else</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">positive</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\">positive</span><span class=\"p\">,</span> <span class=\"n\">negative</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">find_mutex</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Finds mutually exclusive actions&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"c1\"># Inconsistent effects</span>\n",
       "        <span class=\"n\">pos_nsl</span><span class=\"p\">,</span> <span class=\"n\">neg_nsl</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">separate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_state_links</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"k\">for</span> <span class=\"n\">negeff</span> <span class=\"ow\">in</span> <span class=\"n\">neg_nsl</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">new_negeff</span> <span class=\"o\">=</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"n\">negeff</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\">negeff</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">poseff</span> <span class=\"ow\">in</span> <span class=\"n\">pos_nsl</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">new_negeff</span> <span class=\"o\">==</span> <span class=\"n\">poseff</span><span class=\"p\">:</span>\n",
       "                    <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\">next_state_links</span><span class=\"p\">[</span><span class=\"n\">poseff</span><span class=\"p\">]:</span>\n",
       "                        <span class=\"k\">for</span> <span class=\"n\">b</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_state_links</span><span class=\"p\">[</span><span class=\"n\">negeff</span><span class=\"p\">]:</span>\n",
       "                            <span class=\"k\">if</span> <span class=\"p\">{</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">}</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mutex</span><span class=\"p\">:</span>\n",
       "                                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mutex</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">({</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">})</span>\n",
       "\n",
       "        <span class=\"c1\"># Interference will be calculated with the last step</span>\n",
       "        <span class=\"n\">pos_csl</span><span class=\"p\">,</span> <span class=\"n\">neg_csl</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">separate</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_state_links</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"c1\"># Competing needs</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">posprecond</span> <span class=\"ow\">in</span> <span class=\"n\">pos_csl</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">negprecond</span> <span class=\"ow\">in</span> <span class=\"n\">neg_csl</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_negprecond</span> <span class=\"o\">=</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"n\">negprecond</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\">negprecond</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">new_negprecond</span> <span class=\"o\">==</span> <span class=\"n\">posprecond</span><span class=\"p\">:</span>\n",
       "                    <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\">current_state_links</span><span class=\"p\">[</span><span class=\"n\">posprecond</span><span class=\"p\">]:</span>\n",
       "                        <span class=\"k\">for</span> <span class=\"n\">b</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_state_links</span><span class=\"p\">[</span><span class=\"n\">negprecond</span><span class=\"p\">]:</span>\n",
       "                            <span class=\"k\">if</span> <span class=\"p\">{</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">}</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mutex</span><span class=\"p\">:</span>\n",
       "                                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mutex</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">({</span><span class=\"n\">a</span><span class=\"p\">,</span> <span class=\"n\">b</span><span class=\"p\">})</span>\n",
       "\n",
       "        <span class=\"c1\"># Inconsistent support</span>\n",
       "        <span class=\"n\">state_mutex</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">pair</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mutex</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">next_state_0</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_action_links</span><span class=\"p\">[</span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">pair</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">]]</span>\n",
       "            <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">pair</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">2</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">next_state_1</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_action_links</span><span class=\"p\">[</span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">pair</span><span class=\"p\">)[</span><span class=\"mi\">1</span><span class=\"p\">]]</span>\n",
       "            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">next_state_1</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_action_links</span><span class=\"p\">[</span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">pair</span><span class=\"p\">)[</span><span class=\"mi\">0</span><span class=\"p\">]]</span>\n",
       "            <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">next_state_0</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"p\">(</span><span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">next_state_1</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">1</span><span class=\"p\">):</span>\n",
       "                <span class=\"n\">state_mutex</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">({</span><span class=\"n\">next_state_0</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">next_state_1</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]})</span>\n",
       "        \n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mutex</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">mutex</span> <span class=\"o\">+</span> <span class=\"n\">state_mutex</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">build</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">actions</span><span class=\"p\">,</span> <span class=\"n\">objects</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Populates the lists and dictionaries containing the state action dependencies&quot;&quot;&quot;</span>\n",
       "\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\">current_state</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">p_expr</span> <span class=\"o\">=</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"s1\">&#39;P&#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",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_action_links</span><span class=\"p\">[</span><span class=\"n\">p_expr</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">clause</span><span class=\"p\">]</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_action_links</span><span class=\"p\">[</span><span class=\"n\">p_expr</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">clause</span><span class=\"p\">]</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_state_links</span><span class=\"p\">[</span><span class=\"n\">clause</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">p_expr</span><span class=\"p\">]</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_state_links</span><span class=\"p\">[</span><span class=\"n\">clause</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">p_expr</span><span class=\"p\">]</span>\n",
       "\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=\"n\">num_args</span> <span class=\"o\">=</span> <span class=\"nb\">len</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\">possible_args</span> <span class=\"o\">=</span> <span class=\"nb\">tuple</span><span class=\"p\">(</span><span class=\"n\">itertools</span><span class=\"o\">.</span><span class=\"n\">permutations</span><span class=\"p\">(</span><span class=\"n\">objects</span><span class=\"p\">,</span> <span class=\"n\">num_args</span><span class=\"p\">))</span>\n",
       "\n",
       "            <span class=\"k\">for</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">possible_args</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=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"n\">arg</span><span class=\"p\">):</span>\n",
       "                    <span class=\"k\">for</span> <span class=\"n\">num</span><span class=\"p\">,</span> <span class=\"n\">symbol</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</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=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">symbol</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"o\">.</span><span class=\"n\">islower</span><span class=\"p\">():</span>\n",
       "                            <span class=\"n\">arg</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">arg</span><span class=\"p\">)</span>\n",
       "                            <span class=\"n\">arg</span><span class=\"p\">[</span><span class=\"n\">num</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">symbol</span>\n",
       "                            <span class=\"n\">arg</span> <span class=\"o\">=</span> <span class=\"nb\">tuple</span><span class=\"p\">(</span><span class=\"n\">arg</span><span class=\"p\">)</span>\n",
       "\n",
       "                    <span class=\"n\">new_action</span> <span class=\"o\">=</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">substitute</span><span class=\"p\">(</span><span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">),</span> <span class=\"n\">arg</span><span class=\"p\">)</span>\n",
       "                    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_action_links</span><span class=\"p\">[</span><span class=\"n\">new_action</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "\n",
       "                    <span class=\"k\">for</span> <span class=\"n\">clause</span> <span class=\"ow\">in</span> <span class=\"n\">a</span><span class=\"o\">.</span><span class=\"n\">precond</span><span class=\"p\">:</span>\n",
       "                        <span class=\"n\">new_clause</span> <span class=\"o\">=</span> <span class=\"n\">a</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\">arg</span><span class=\"p\">)</span>\n",
       "                        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_action_links</span><span class=\"p\">[</span><span class=\"n\">new_action</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_clause</span><span class=\"p\">)</span>\n",
       "                        <span class=\"k\">if</span> <span class=\"n\">new_clause</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_state_links</span><span class=\"p\">:</span>\n",
       "                            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_state_links</span><span class=\"p\">[</span><span class=\"n\">new_clause</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_action</span><span class=\"p\">)</span>\n",
       "                        <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">current_state_links</span><span class=\"p\">[</span><span class=\"n\">new_clause</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">new_action</span><span class=\"p\">]</span>\n",
       "                   \n",
       "                    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_action_links</span><span class=\"p\">[</span><span class=\"n\">new_action</span><span class=\"p\">]</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\">a</span><span class=\"o\">.</span><span class=\"n\">effect</span><span class=\"p\">:</span>\n",
       "                        <span class=\"n\">new_clause</span> <span class=\"o\">=</span> <span class=\"n\">a</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\">arg</span><span class=\"p\">)</span>\n",
       "\n",
       "                        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_action_links</span><span class=\"p\">[</span><span class=\"n\">new_action</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_clause</span><span class=\"p\">)</span>\n",
       "                        <span class=\"k\">if</span> <span class=\"n\">new_clause</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_state_links</span><span class=\"p\">:</span>\n",
       "                            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_state_links</span><span class=\"p\">[</span><span class=\"n\">new_clause</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_action</span><span class=\"p\">)</span>\n",
       "                        <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_state_links</span><span class=\"p\">[</span><span class=\"n\">new_clause</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">new_action</span><span class=\"p\">]</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">perform_actions</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Performs the necessary actions and returns a new Level&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">new_kb</span> <span class=\"o\">=</span> <span class=\"n\">FolKB</span><span class=\"p\">(</span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">next_state_links</span><span class=\"o\">.</span><span class=\"n\">keys</span><span class=\"p\">())))</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">Level</span><span class=\"p\">(</span><span class=\"n\">new_kb</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(Level)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each level stores the following data\n",
    "1. The current state of the level in `current_state`\n",
    "2. Links from an action to its preconditions in `current_action_links`\n",
    "3. Links from a state to the possible actions in that state in `current_state_links`\n",
    "4. Links from each action to its effects in `next_action_links`\n",
    "5. Links from each possible next state from each action in `next_state_links`. This stores the same information as the `current_action_links` of the next level.\n",
    "6. Mutex links in `mutex`.\n",
    "<br>\n",
    "<br>\n",
    "The `find_mutex` method finds the mutex links according to the points given above.\n",
    "<br>\n",
    "The `build` method populates the data structures storing the state and action information.\n",
    "Persistence actions for each clause in the current state are also defined here. \n",
    "The newly created persistence action has the same name as its state, prefixed with a 'P'."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's now look at the `Graph` class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "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\">Graph</span><span class=\"p\">:</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    Contains levels of state and actions</span>\n",
       "<span class=\"sd\">    Used in graph planning algorithm to extract a solution</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\">pddl</span><span class=\"p\">):</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span> <span class=\"o\">=</span> <span class=\"n\">pddl</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kb</span> <span class=\"o\">=</span> <span class=\"n\">FolKB</span><span class=\"p\">(</span><span class=\"n\">pddl</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">levels</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">Level</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kb</span><span class=\"p\">)]</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">arg</span> <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\">kb</span><span class=\"o\">.</span><span class=\"n\">clauses</span> <span class=\"k\">for</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">args</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>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expand_graph</span><span class=\"p\">()</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">expand_graph</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Expands the graph by a level&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">last_level</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">levels</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n",
       "        <span class=\"n\">last_level</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span><span class=\"o\">.</span><span class=\"n\">actions</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">levels</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">last_level</span><span class=\"o\">.</span><span class=\"n\">perform_actions</span><span class=\"p\">())</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">non_mutex_goals</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">goals</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Checks whether the goals are mutually exclusive&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">goal_perm</span> <span class=\"o\">=</span> <span class=\"n\">itertools</span><span class=\"o\">.</span><span class=\"n\">combinations</span><span class=\"p\">(</span><span class=\"n\">goals</span><span class=\"p\">,</span> <span class=\"mi\">2</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">g</span> <span class=\"ow\">in</span> <span class=\"n\">goal_perm</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">g</span><span class=\"p\">)</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">levels</span><span class=\"p\">[</span><span class=\"n\">index</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">mutex</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(Graph)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The class stores a problem definition in `pddl`, \n",
    "a knowledge base in `kb`, \n",
    "a list of `Level` objects in `levels` and \n",
    "all the possible arguments found in the initial state of the problem in `objects`.\n",
    "<br>\n",
    "The `expand_graph` method generates a new level of the graph.\n",
    "This method is invoked when the goal conditions haven't been met in the current level or the actions that lead to it are mutually exclusive.\n",
    "The `non_mutex_goals` method checks whether the goals in the current state are mutually exclusive.\n",
    "<br>\n",
    "<br>\n",
    "Using these two classes, we can define a planning graph which can either be used to provide reliable heuristics for planning problems or used in the `GraphPlan` algorithm.\n",
    "<br>\n",
    "Let's have a look at the `GraphPlan` class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "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\">GraphPlan</span><span class=\"p\">:</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    Class for formulation GraphPlan algorithm</span>\n",
       "<span class=\"sd\">    Constructs a graph of state and action space</span>\n",
       "<span class=\"sd\">    Returns solution for the planning problem</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\">pddl</span><span class=\"p\">):</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span> <span class=\"o\">=</span> <span class=\"n\">Graph</span><span class=\"p\">(</span><span class=\"n\">pddl</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">nogoods</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">solution</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">check_leveloff</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Checks if the graph has levelled off&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">check</span> <span class=\"o\">=</span> <span class=\"p\">(</span><span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">levels</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">current_state</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">levels</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">current_state</span><span class=\"p\">))</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"n\">check</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">return</span> <span class=\"bp\">True</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">extract_solution</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">goals</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Extracts the solution&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">level</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">levels</span><span class=\"p\">[</span><span class=\"n\">index</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\">graph</span><span class=\"o\">.</span><span class=\"n\">non_mutex_goals</span><span class=\"p\">(</span><span class=\"n\">goals</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">):</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">nogoods</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">((</span><span class=\"n\">level</span><span class=\"p\">,</span> <span class=\"n\">goals</span><span class=\"p\">))</span>\n",
       "            <span class=\"k\">return</span>\n",
       "\n",
       "        <span class=\"n\">level</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">levels</span><span class=\"p\">[</span><span class=\"n\">index</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">]</span>    \n",
       "\n",
       "        <span class=\"c1\"># Create all combinations of actions that satisfy the goal    </span>\n",
       "        <span class=\"n\">actions</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">goal</span> <span class=\"ow\">in</span> <span class=\"n\">goals</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">actions</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">level</span><span class=\"o\">.</span><span class=\"n\">next_state_links</span><span class=\"p\">[</span><span class=\"n\">goal</span><span class=\"p\">])</span>    \n",
       "\n",
       "        <span class=\"n\">all_actions</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">itertools</span><span class=\"o\">.</span><span class=\"n\">product</span><span class=\"p\">(</span><span class=\"o\">*</span><span class=\"n\">actions</span><span class=\"p\">))</span>    \n",
       "\n",
       "        <span class=\"c1\"># Filter out non-mutex actions</span>\n",
       "        <span class=\"n\">non_mutex_actions</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>    \n",
       "        <span class=\"k\">for</span> <span class=\"n\">action_tuple</span> <span class=\"ow\">in</span> <span class=\"n\">all_actions</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">action_pairs</span> <span class=\"o\">=</span> <span class=\"n\">itertools</span><span class=\"o\">.</span><span class=\"n\">combinations</span><span class=\"p\">(</span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">action_tuple</span><span class=\"p\">)),</span> <span class=\"mi\">2</span><span class=\"p\">)</span>        \n",
       "            <span class=\"n\">non_mutex_actions</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">action_tuple</span><span class=\"p\">)))</span>        \n",
       "            <span class=\"k\">for</span> <span class=\"n\">pair</span> <span class=\"ow\">in</span> <span class=\"n\">action_pairs</span><span class=\"p\">:</span>            \n",
       "                <span class=\"k\">if</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">pair</span><span class=\"p\">)</span> <span class=\"ow\">in</span> <span class=\"n\">level</span><span class=\"o\">.</span><span class=\"n\">mutex</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">non_mutex_actions</span><span class=\"o\">.</span><span class=\"n\">pop</span><span class=\"p\">(</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n",
       "                    <span class=\"k\">break</span>\n",
       "    \n",
       "\n",
       "        <span class=\"c1\"># Recursion</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">action_list</span> <span class=\"ow\">in</span> <span class=\"n\">non_mutex_actions</span><span class=\"p\">:</span>        \n",
       "            <span class=\"k\">if</span> <span class=\"p\">[</span><span class=\"n\">action_list</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">]</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">solution</span><span class=\"p\">:</span>\n",
       "                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">solution</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">([</span><span class=\"n\">action_list</span><span class=\"p\">,</span> <span class=\"n\">index</span><span class=\"p\">])</span>\n",
       "\n",
       "                <span class=\"n\">new_goals</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "                <span class=\"k\">for</span> <span class=\"n\">act</span> <span class=\"ow\">in</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">action_list</span><span class=\"p\">):</span>                \n",
       "                    <span class=\"k\">if</span> <span class=\"n\">act</span> <span class=\"ow\">in</span> <span class=\"n\">level</span><span class=\"o\">.</span><span class=\"n\">current_action_links</span><span class=\"p\">:</span>\n",
       "                        <span class=\"n\">new_goals</span> <span class=\"o\">=</span> <span class=\"n\">new_goals</span> <span class=\"o\">+</span> <span class=\"n\">level</span><span class=\"o\">.</span><span class=\"n\">current_action_links</span><span class=\"p\">[</span><span class=\"n\">act</span><span class=\"p\">]</span>\n",
       "\n",
       "                <span class=\"k\">if</span> <span class=\"nb\">abs</span><span class=\"p\">(</span><span class=\"n\">index</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"o\">==</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">levels</span><span class=\"p\">):</span>\n",
       "                    <span class=\"k\">return</span>\n",
       "                <span class=\"k\">elif</span> <span class=\"p\">(</span><span class=\"n\">level</span><span class=\"p\">,</span> <span class=\"n\">new_goals</span><span class=\"p\">)</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">nogoods</span><span class=\"p\">:</span>\n",
       "                    <span class=\"k\">return</span>\n",
       "                <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                    <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">extract_solution</span><span class=\"p\">(</span><span class=\"n\">new_goals</span><span class=\"p\">,</span> <span class=\"n\">index</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"c1\"># Level-Order multiple solutions</span>\n",
       "        <span class=\"n\">solution</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">item</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">solution</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">item</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">solution</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">([])</span>\n",
       "                <span class=\"n\">solution</span><span class=\"p\">[</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\">item</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\">solution</span><span class=\"p\">[</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\">item</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span>\n",
       "\n",
       "        <span class=\"k\">for</span> <span class=\"n\">num</span><span class=\"p\">,</span> <span class=\"n\">item</span> <span class=\"ow\">in</span> <span class=\"nb\">enumerate</span><span class=\"p\">(</span><span class=\"n\">solution</span><span class=\"p\">):</span>\n",
       "            <span class=\"n\">item</span><span class=\"o\">.</span><span class=\"n\">reverse</span><span class=\"p\">()</span>\n",
       "            <span class=\"n\">solution</span><span class=\"p\">[</span><span class=\"n\">num</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">item</span>\n",
       "\n",
       "        <span class=\"k\">return</span> <span class=\"n\">solution</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> <span class=\"n\">kb</span><span class=\"p\">):</span>\n",
       "        <span class=\"k\">return</span> <span class=\"nb\">all</span><span class=\"p\">(</span><span class=\"n\">kb</span><span class=\"o\">.</span><span class=\"n\">ask</span><span class=\"p\">(</span><span class=\"n\">q</span><span class=\"p\">)</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">False</span> <span class=\"k\">for</span> <span class=\"n\">q</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">pddl</span><span class=\"o\">.</span><span class=\"n\">goals</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Executes the GraphPlan algorithm for the given problem&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"k\">while</span> <span class=\"bp\">True</span><span class=\"p\">:</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">expand_graph</span><span class=\"p\">()</span>\n",
       "            <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">goal_test</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">levels</span><span class=\"p\">[</span><span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">kb</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">non_mutex_goals</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">pddl</span><span class=\"o\">.</span><span class=\"n\">goals</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)):</span>\n",
       "                <span class=\"n\">solution</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">extract_solution</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">pddl</span><span class=\"o\">.</span><span class=\"n\">goals</span><span class=\"p\">,</span> <span class=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">solution</span><span class=\"p\">:</span>\n",
       "                    <span class=\"k\">return</span> <span class=\"n\">solution</span>\n",
       "            \n",
       "            <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">levels</span><span class=\"p\">)</span> <span class=\"o\">&gt;=</span> <span class=\"mi\">2</span> <span class=\"ow\">and</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">check_leveloff</span><span class=\"p\">():</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">None</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(GraphPlan)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Given a planning problem defined as a PlanningProblem, `GraphPlan` creates a planning graph stored in `graph` and expands it till it reaches a state where all its required goals are present simultaneously without mutual exclusivity.\n",
    "<br>\n",
    "Once a goal is found, `extract_solution` is called.\n",
    "This method recursively finds the path to a solution given a planning graph.\n",
    "In the case where `extract_solution` fails to find a solution for a set of goals as a given level, we record the `(level, goals)` pair as a **no-good**.\n",
    "Whenever `extract_solution` is called again with the same level and goals, we can find the recorded no-good and immediately return failure rather than searching again. \n",
    "No-goods are also used in the termination test.\n",
    "<br>\n",
    "The `check_leveloff` method checks if the planning graph for the problem has **levelled-off**, ie, it has the same states, actions and mutex pairs as the previous level.\n",
    "If the graph has already levelled off and we haven't found a solution, there is no point expanding the graph, as it won't lead to anything new.\n",
    "In such a case, we can declare that the planning problem is unsolvable with the given constraints.\n",
    "<br>\n",
    "<br>\n",
    "To summarize, the `GraphPlan` algorithm calls `expand_graph` and tests whether it has reached the goal and if the goals are non-mutex.\n",
    "<br>\n",
    "If so, `extract_solution` is invoked which recursively reconstructs the solution from the planning graph.\n",
    "<br>\n",
    "If not, then we check if our graph has levelled off and continue if it hasn't."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's solve a few planning problems that we had defined earlier."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Air cargo problem\n",
    "In accordance with the summary above, we have defined a helper function to carry out `GraphPlan` on the `air_cargo` problem.\n",
    "The function is pretty straightforward.\n",
    "Let's have a look."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "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_graphplan</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;Solves the air cargo problem using GraphPlan&quot;&quot;&quot;</span>\n",
       "    <span class=\"k\">return</span> <span class=\"n\">GraphPlan</span><span class=\"p\">(</span><span class=\"n\">air_cargo</span><span class=\"p\">())</span><span class=\"o\">.</span><span class=\"n\">execute</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_graphplan)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's instantiate the problem and find a solution using this helper function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[[Load(C2, P2, JFK),\n",
       "   Fly(P2, JFK, SFO),\n",
       "   Load(C1, P1, SFO),\n",
       "   Fly(P1, SFO, JFK),\n",
       "   PCargo(C1),\n",
       "   PAirport(JFK),\n",
       "   PPlane(P2),\n",
       "   PAirport(SFO),\n",
       "   PPlane(P1),\n",
       "   PCargo(C2)],\n",
       "  [Unload(C2, P2, SFO), Unload(C1, P1, JFK)]]]"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "airCargoG = air_cargo_graphplan()\n",
    "airCargoG"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each element in the solution is a valid action.\n",
    "The solution is separated into lists for each level.\n",
    "The actions prefixed with a 'P' are persistence actions and can be ignored.\n",
    "They simply carry certain states forward.\n",
    "We have another helper function `linearize` that presents the solution in a more readable format, much like a total-order planner, but it is _not_ a total-order planner."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 55,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Load(C2, P2, JFK),\n",
       " Fly(P2, JFK, SFO),\n",
       " Load(C1, P1, SFO),\n",
       " Fly(P1, SFO, JFK),\n",
       " Unload(C2, P2, SFO),\n",
       " Unload(C1, P1, JFK)]"
      ]
     },
     "execution_count": 55,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "linearize(airCargoG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Indeed, this is a correct solution.\n",
    "<br>\n",
    "There are similar helper functions for some other planning problems.\n",
    "<br>\n",
    "Lets' try solving the spare tire problem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Remove(Flat, Axle), Remove(Spare, Trunk), PutOn(Spare, Axle)]"
      ]
     },
     "execution_count": 56,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "spareTireG = spare_tire_graphplan()\n",
    "linearize(spareTireG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution for the cake problem"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Eat(Cake), Bake(Cake)]"
      ]
     },
     "execution_count": 57,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "cakeProblemG = have_cake_and_eat_cake_too_graphplan()\n",
    "linearize(cakeProblemG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution for the Sussman's Anomaly configuration of three blocks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]"
      ]
     },
     "execution_count": 58,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sussmanAnomalyG = three_block_tower_graphplan()\n",
    "linearize(sussmanAnomalyG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution of the socks and shoes problem"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[LeftSock, RightSock, LeftShoe, RightShoe]"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "socksShoesG = socks_and_shoes_graphplan()\n",
    "linearize(socksShoesG)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### TOTAL ORDER PLANNER\n",
    "\n",
    "In mathematical terminology, **total order**, **linear order** or **simple order** refers to a set *X* which is said to be totally ordered under &le; if the following statements hold for all *a*, *b* and *c* in *X*:\n",
    "<br>\n",
    "If *a* &le; *b* and *b* &le; *a*, then *a* = *b* (antisymmetry).\n",
    "<br>\n",
    "If *a* &le; *b* and *b* &le; *c*, then *a* &le; *c* (transitivity).\n",
    "<br>\n",
    "*a* &le; *b* or *b* &le; *a* (connex relation).\n",
    "\n",
    "<br>\n",
    "In simpler terms, a total order plan is a linear ordering of actions to be taken to reach the goal state.\n",
    "There may be several different total-order plans for a particular goal depending on the problem.\n",
    "<br>\n",
    "<br>\n",
    "In the module, the `Linearize` class solves problems using this paradigm.\n",
    "At its core, the `Linearize` uses a solved planning graph from `GraphPlan` and finds a valid total-order solution for it.\n",
    "Let's have a look at the class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "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\">Linearize</span><span class=\"p\">:</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\">pddl</span><span class=\"p\">):</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span> <span class=\"o\">=</span> <span class=\"n\">pddl</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">filter</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">solution</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Filter out persistence actions from a solution&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">new_solution</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">section</span> <span class=\"ow\">in</span> <span class=\"n\">solution</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span>\n",
       "            <span class=\"n\">new_section</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">operation</span> <span class=\"ow\">in</span> <span class=\"n\">section</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"p\">(</span><span class=\"n\">operation</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;P&#39;</span> <span class=\"ow\">and</span> <span class=\"n\">operation</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">isupper</span><span class=\"p\">()):</span>\n",
       "                    <span class=\"n\">new_section</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">operation</span><span class=\"p\">)</span>\n",
       "            <span class=\"n\">new_solution</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_section</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">new_solution</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">orderlevel</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">level</span><span class=\"p\">,</span> <span class=\"n\">pddl</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Return valid linear order of actions for a given level&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"k\">for</span> <span class=\"n\">permutation</span> <span class=\"ow\">in</span> <span class=\"n\">itertools</span><span class=\"o\">.</span><span class=\"n\">permutations</span><span class=\"p\">(</span><span class=\"n\">level</span><span class=\"p\">):</span>\n",
       "            <span class=\"n\">temp</span> <span class=\"o\">=</span> <span class=\"n\">copy</span><span class=\"o\">.</span><span class=\"n\">deepcopy</span><span class=\"p\">(</span><span class=\"n\">pddl</span><span class=\"p\">)</span>\n",
       "            <span class=\"n\">count</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">action</span> <span class=\"ow\">in</span> <span class=\"n\">permutation</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">try</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">temp</span><span class=\"o\">.</span><span class=\"n\">act</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"p\">)</span>\n",
       "                    <span class=\"n\">count</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span>\n",
       "                <span class=\"k\">except</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">count</span> <span class=\"o\">=</span> <span class=\"mi\">0</span>\n",
       "                    <span class=\"n\">temp</span> <span class=\"o\">=</span> <span class=\"n\">copy</span><span class=\"o\">.</span><span class=\"n\">deepcopy</span><span class=\"p\">(</span><span class=\"n\">pddl</span><span class=\"p\">)</span>\n",
       "                    <span class=\"k\">break</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">count</span> <span class=\"o\">==</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">permutation</span><span class=\"p\">):</span>\n",
       "                <span class=\"k\">return</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"n\">permutation</span><span class=\"p\">),</span> <span class=\"n\">temp</span>\n",
       "        <span class=\"k\">return</span> <span class=\"bp\">None</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Finds total-order solution for a planning graph&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">graphplan_solution</span> <span class=\"o\">=</span> <span class=\"n\">GraphPlan</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span><span class=\"p\">)</span><span class=\"o\">.</span><span class=\"n\">execute</span><span class=\"p\">()</span>\n",
       "        <span class=\"n\">filtered_solution</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">graphplan_solution</span><span class=\"p\">)</span>\n",
       "        <span class=\"n\">ordered_solution</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"n\">pddl</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">level</span> <span class=\"ow\">in</span> <span class=\"n\">filtered_solution</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">level_solution</span><span class=\"p\">,</span> <span class=\"n\">pddl</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">orderlevel</span><span class=\"p\">(</span><span class=\"n\">level</span><span class=\"p\">,</span> <span class=\"n\">pddl</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">element</span> <span class=\"ow\">in</span> <span class=\"n\">level_solution</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">ordered_solution</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">element</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"k\">return</span> <span class=\"n\">ordered_solution</span>\n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(Linearize)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `filter` method removes the persistence actions (if any) from the planning graph representation.\n",
    "<br>\n",
    "The `orderlevel` method finds a valid total-ordering of a specified level of the planning-graph, given the state of the graph after the previous level.\n",
    "<br>\n",
    "The `execute` method sequentially calls `orderlevel` for all the levels in the planning-graph and returns the final total-order solution.\n",
    "<br>\n",
    "<br>\n",
    "Let's look at some examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Load(C2, P2, JFK),\n",
       " Fly(P2, JFK, SFO),\n",
       " Load(C1, P1, SFO),\n",
       " Fly(P1, SFO, JFK),\n",
       " Unload(C2, P2, SFO),\n",
       " Unload(C1, P1, JFK)]"
      ]
     },
     "execution_count": 61,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# total-order solution for air_cargo problem\n",
    "Linearize(air_cargo()).execute()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Remove(Flat, Axle), Remove(Spare, Trunk), PutOn(Spare, Axle)]"
      ]
     },
     "execution_count": 62,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# total-order solution for spare_tire problem\n",
    "Linearize(spare_tire()).execute()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]"
      ]
     },
     "execution_count": 63,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# total-order solution for three_block_tower problem\n",
    "Linearize(three_block_tower()).execute()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 64,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[ToTable(A, B), FromTable(B, A), FromTable(C, B)]"
      ]
     },
     "execution_count": 64,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# total-order solution for simple_blocks_world problem\n",
    "Linearize(simple_blocks_world()).execute()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[LeftSock, RightSock, LeftShoe, RightShoe]"
      ]
     },
     "execution_count": 65,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# total-order solution for socks_and_shoes problem\n",
    "Linearize(socks_and_shoes()).execute()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### PARTIAL ORDER  PLANNER\n",
    "A partial-order planning algorithm is significantly different from a total-order planner.\n",
    "The way a partial-order plan works enables it to take advantage of _problem decomposition_ and work on each subproblem separately.\n",
    "It works on several subgoals independently, solves them with several subplans, and then combines the plan.\n",
    "<br>\n",
    "A partial-order planner also follows the **least commitment** strategy, where it delays making choices for as long as possible.\n",
    "Variables are not bound unless it is absolutely necessary and new actions are chosen only if the existing actions cannot fulfil the required precondition.\n",
    "<br>\n",
    "Any planning algorithm that can place two actions into a plan without specifying which comes first is called a **partial-order planner**.\n",
    "A partial-order planner searches through the space of plans rather than the space of states, which makes it perform better for certain problems.\n",
    "<br>\n",
    "<br>\n",
    "Let's have a look at the `PartialOrderPlanner` class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "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\">PartialOrderPlanner</span><span class=\"p\">:</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\">pddl</span><span class=\"p\">):</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span> <span class=\"o\">=</span> <span class=\"n\">pddl</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">initialize</span><span class=\"p\">()</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">initialize</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Initialize all variables&quot;&quot;&quot;</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">causal_links</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">start</span> <span class=\"o\">=</span> <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Start&#39;</span><span class=\"p\">,</span> <span class=\"p\">[],</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">finish</span> <span class=\"o\">=</span> <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"s1\">&#39;Finish&#39;</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span><span class=\"o\">.</span><span class=\"n\">goals</span><span class=\"p\">,</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=\"nb\">set</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\">add</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">start</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\">add</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">finish</span><span class=\"p\">)</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">()</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">start</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">finish</span><span class=\"p\">))</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">agenda</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">()</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">precond</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">finish</span><span class=\"o\">.</span><span class=\"n\">precond</span><span class=\"p\">:</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">agenda</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">((</span><span class=\"n\">precond</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">finish</span><span class=\"p\">))</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expanded_actions</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expand_actions</span><span class=\"p\">()</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">expand_actions</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"bp\">None</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Generate all possible actions with variable bindings for precondition selection heuristic&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">objects</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">arg</span> <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\">pddl</span><span class=\"o\">.</span><span class=\"n\">init</span> <span class=\"k\">for</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)</span>\n",
       "        <span class=\"n\">expansions</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"n\">action_list</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"k\">if</span> <span class=\"n\">name</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">action</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span><span class=\"o\">.</span><span class=\"n\">actions</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">if</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"n\">name</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">action_list</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">action_list</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span><span class=\"o\">.</span><span class=\"n\">actions</span>\n",
       "\n",
       "        <span class=\"k\">for</span> <span class=\"n\">action</span> <span class=\"ow\">in</span> <span class=\"n\">action_list</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">permutation</span> <span class=\"ow\">in</span> <span class=\"n\">itertools</span><span class=\"o\">.</span><span class=\"n\">permutations</span><span class=\"p\">(</span><span class=\"n\">objects</span><span class=\"p\">,</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">)):</span>\n",
       "                <span class=\"n\">bindings</span> <span class=\"o\">=</span> <span class=\"n\">unify</span><span class=\"p\">(</span><span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">),</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">,</span> <span class=\"o\">*</span><span class=\"n\">permutation</span><span class=\"p\">))</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">bindings</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">new_args</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "                    <span class=\"k\">for</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">:</span>\n",
       "                        <span class=\"k\">if</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">bindings</span><span class=\"p\">:</span>\n",
       "                            <span class=\"n\">new_args</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">bindings</span><span class=\"p\">[</span><span class=\"n\">arg</span><span class=\"p\">])</span>\n",
       "                        <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                            <span class=\"n\">new_args</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">arg</span><span class=\"p\">)</span>\n",
       "                    <span class=\"n\">new_expr</span> <span class=\"o\">=</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">),</span> <span class=\"o\">*</span><span class=\"n\">new_args</span><span class=\"p\">)</span>\n",
       "                    <span class=\"n\">new_preconds</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "                    <span class=\"k\">for</span> <span class=\"n\">precond</span> <span class=\"ow\">in</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">precond</span><span class=\"p\">:</span>\n",
       "                        <span class=\"n\">new_precond_args</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "                        <span class=\"k\">for</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">precond</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">:</span>\n",
       "                            <span class=\"k\">if</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">bindings</span><span class=\"p\">:</span>\n",
       "                                <span class=\"n\">new_precond_args</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">bindings</span><span class=\"p\">[</span><span class=\"n\">arg</span><span class=\"p\">])</span>\n",
       "                            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                                <span class=\"n\">new_precond_args</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">arg</span><span class=\"p\">)</span>\n",
       "                        <span class=\"n\">new_precond</span> <span class=\"o\">=</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">precond</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">),</span> <span class=\"o\">*</span><span class=\"n\">new_precond_args</span><span class=\"p\">)</span>\n",
       "                        <span class=\"n\">new_preconds</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_precond</span><span class=\"p\">)</span>\n",
       "                    <span class=\"n\">new_effects</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "                    <span class=\"k\">for</span> <span class=\"n\">effect</span> <span class=\"ow\">in</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">effect</span><span class=\"p\">:</span>\n",
       "                        <span class=\"n\">new_effect_args</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "                        <span class=\"k\">for</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">effect</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">:</span>\n",
       "                            <span class=\"k\">if</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">bindings</span><span class=\"p\">:</span>\n",
       "                                <span class=\"n\">new_effect_args</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">bindings</span><span class=\"p\">[</span><span class=\"n\">arg</span><span class=\"p\">])</span>\n",
       "                            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                                <span class=\"n\">new_effect_args</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">arg</span><span class=\"p\">)</span>\n",
       "                        <span class=\"n\">new_effect</span> <span class=\"o\">=</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">effect</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">),</span> <span class=\"o\">*</span><span class=\"n\">new_effect_args</span><span class=\"p\">)</span>\n",
       "                        <span class=\"n\">new_effects</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_effect</span><span class=\"p\">)</span>\n",
       "                    <span class=\"n\">expansions</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"n\">new_expr</span><span class=\"p\">,</span> <span class=\"n\">new_preconds</span><span class=\"p\">,</span> <span class=\"n\">new_effects</span><span class=\"p\">))</span>\n",
       "\n",
       "        <span class=\"k\">return</span> <span class=\"n\">expansions</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">find_open_precondition</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Find open precondition with the least number of possible actions&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">number_of_ways</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">()</span>\n",
       "        <span class=\"n\">actions_for_precondition</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">()</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">element</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">agenda</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">open_precondition</span> <span class=\"o\">=</span> <span class=\"n\">element</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n",
       "            <span class=\"n\">possible_actions</span> <span class=\"o\">=</span> <span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">actions</span><span class=\"p\">)</span> <span class=\"o\">+</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expanded_actions</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\">effect</span> <span class=\"ow\">in</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">effect</span><span class=\"p\">:</span>\n",
       "                    <span class=\"k\">if</span> <span class=\"n\">effect</span> <span class=\"o\">==</span> <span class=\"n\">open_precondition</span><span class=\"p\">:</span>\n",
       "                        <span class=\"k\">if</span> <span class=\"n\">open_precondition</span> <span class=\"ow\">in</span> <span class=\"n\">number_of_ways</span><span class=\"p\">:</span>\n",
       "                            <span class=\"n\">number_of_ways</span><span class=\"p\">[</span><span class=\"n\">open_precondition</span><span class=\"p\">]</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span>\n",
       "                            <span class=\"n\">actions_for_precondition</span><span class=\"p\">[</span><span class=\"n\">open_precondition</span><span class=\"p\">]</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"p\">)</span>\n",
       "                        <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                            <span class=\"n\">number_of_ways</span><span class=\"p\">[</span><span class=\"n\">open_precondition</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"mi\">1</span>\n",
       "                            <span class=\"n\">actions_for_precondition</span><span class=\"p\">[</span><span class=\"n\">open_precondition</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">action</span><span class=\"p\">]</span>\n",
       "\n",
       "        <span class=\"n\">number</span> <span class=\"o\">=</span> <span class=\"nb\">sorted</span><span class=\"p\">(</span><span class=\"n\">number_of_ways</span><span class=\"p\">,</span> <span class=\"n\">key</span><span class=\"o\">=</span><span class=\"n\">number_of_ways</span><span class=\"o\">.</span><span class=\"fm\">__getitem__</span><span class=\"p\">)</span>\n",
       "        \n",
       "        <span class=\"k\">for</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">v</span> <span class=\"ow\">in</span> <span class=\"n\">number_of_ways</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">v</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"bp\">None</span>\n",
       "\n",
       "        <span class=\"n\">act1</span> <span class=\"o\">=</span> <span class=\"bp\">None</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">element</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">agenda</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">element</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"n\">number</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]:</span>\n",
       "                <span class=\"n\">act1</span> <span class=\"o\">=</span> <span class=\"n\">element</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span>\n",
       "                <span class=\"k\">break</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"n\">number</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expanded_actions</span><span class=\"p\">:</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">expanded_actions</span><span class=\"o\">.</span><span class=\"n\">remove</span><span class=\"p\">(</span><span class=\"n\">number</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">])</span>\n",
       "\n",
       "        <span class=\"k\">return</span> <span class=\"n\">number</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"n\">act1</span><span class=\"p\">,</span> <span class=\"n\">actions_for_precondition</span><span class=\"p\">[</span><span class=\"n\">number</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">find_action_for_precondition</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">oprec</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Find action for a given precondition&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"c1\"># either</span>\n",
       "        <span class=\"c1\">#   choose act0 E Actions such that act0 achieves G</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">action</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">actions</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">effect</span> <span class=\"ow\">in</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">effect</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">effect</span> <span class=\"o\">==</span> <span class=\"n\">oprec</span><span class=\"p\">:</span>\n",
       "                    <span class=\"k\">return</span> <span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"mi\">0</span>\n",
       "\n",
       "        <span class=\"c1\"># or</span>\n",
       "        <span class=\"c1\">#   choose act0 E Actions such that act0 achieves G</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">action</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">pddl</span><span class=\"o\">.</span><span class=\"n\">actions</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">effect</span> <span class=\"ow\">in</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">effect</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">effect</span><span class=\"o\">.</span><span class=\"n\">op</span> <span class=\"o\">==</span> <span class=\"n\">oprec</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">bindings</span> <span class=\"o\">=</span> <span class=\"n\">unify</span><span class=\"p\">(</span><span class=\"n\">effect</span><span class=\"p\">,</span> <span class=\"n\">oprec</span><span class=\"p\">)</span>\n",
       "                    <span class=\"k\">if</span> <span class=\"n\">bindings</span> <span class=\"ow\">is</span> <span class=\"bp\">None</span><span class=\"p\">:</span>\n",
       "                        <span class=\"k\">break</span>\n",
       "                    <span class=\"k\">return</span> <span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"n\">bindings</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">generate_expr</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">clause</span><span class=\"p\">,</span> <span class=\"n\">bindings</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Generate atomic expression from generic expression given variable bindings&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">new_args</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">arg</span> <span class=\"ow\">in</span> <span class=\"n\">bindings</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_args</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">bindings</span><span class=\"p\">[</span><span class=\"n\">arg</span><span class=\"p\">])</span>\n",
       "            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_args</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">arg</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"k\">try</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">return</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">clause</span><span class=\"o\">.</span><span class=\"n\">name</span><span class=\"p\">),</span> <span class=\"o\">*</span><span class=\"n\">new_args</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">except</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">return</span> <span class=\"n\">Expr</span><span class=\"p\">(</span><span class=\"nb\">str</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=\"o\">*</span><span class=\"n\">new_args</span><span class=\"p\">)</span>\n",
       "        \n",
       "    <span class=\"k\">def</span> <span class=\"nf\">generate_action_object</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\">bindings</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Generate action object given a generic action andvariable bindings&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"c1\"># if bindings is 0, it means the action already exists in self.actions</span>\n",
       "        <span class=\"k\">if</span> <span class=\"n\">bindings</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">return</span> <span class=\"n\">action</span>\n",
       "\n",
       "        <span class=\"c1\"># bindings cannot be None</span>\n",
       "        <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">new_expr</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">generate_expr</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"n\">bindings</span><span class=\"p\">)</span>\n",
       "            <span class=\"n\">new_preconds</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">precond</span> <span class=\"ow\">in</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">precond</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_precond</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">generate_expr</span><span class=\"p\">(</span><span class=\"n\">precond</span><span class=\"p\">,</span> <span class=\"n\">bindings</span><span class=\"p\">)</span>\n",
       "                <span class=\"n\">new_preconds</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_precond</span><span class=\"p\">)</span>\n",
       "            <span class=\"n\">new_effects</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">effect</span> <span class=\"ow\">in</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">effect</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_effect</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">generate_expr</span><span class=\"p\">(</span><span class=\"n\">effect</span><span class=\"p\">,</span> <span class=\"n\">bindings</span><span class=\"p\">)</span>\n",
       "                <span class=\"n\">new_effects</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">new_effect</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">return</span> <span class=\"n\">Action</span><span class=\"p\">(</span><span class=\"n\">new_expr</span><span class=\"p\">,</span> <span class=\"n\">new_preconds</span><span class=\"p\">,</span> <span class=\"n\">new_effects</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">cyclic</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">graph</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Check cyclicity of a directed graph&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">new_graph</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">()</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">element</span> <span class=\"ow\">in</span> <span class=\"n\">graph</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">element</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"n\">new_graph</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_graph</span><span class=\"p\">[</span><span class=\"n\">element</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">(</span><span class=\"n\">element</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n",
       "            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">new_graph</span><span class=\"p\">[</span><span class=\"n\">element</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">element</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]]</span>\n",
       "\n",
       "        <span class=\"n\">path</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">()</span>\n",
       "\n",
       "        <span class=\"k\">def</span> <span class=\"nf\">visit</span><span class=\"p\">(</span><span class=\"n\">vertex</span><span class=\"p\">):</span>\n",
       "            <span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">vertex</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">neighbor</span> <span class=\"ow\">in</span> <span class=\"n\">new_graph</span><span class=\"o\">.</span><span class=\"n\">get</span><span class=\"p\">(</span><span class=\"n\">vertex</span><span class=\"p\">,</span> <span class=\"p\">()):</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">neighbor</span> <span class=\"ow\">in</span> <span class=\"n\">path</span> <span class=\"ow\">or</span> <span class=\"n\">visit</span><span class=\"p\">(</span><span class=\"n\">neighbor</span><span class=\"p\">):</span>\n",
       "                    <span class=\"k\">return</span> <span class=\"bp\">True</span>\n",
       "            <span class=\"n\">path</span><span class=\"o\">.</span><span class=\"n\">remove</span><span class=\"p\">(</span><span class=\"n\">vertex</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">return</span> <span class=\"bp\">False</span>\n",
       "\n",
       "        <span class=\"n\">value</span> <span class=\"o\">=</span> <span class=\"nb\">any</span><span class=\"p\">(</span><span class=\"n\">visit</span><span class=\"p\">(</span><span class=\"n\">v</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">v</span> <span class=\"ow\">in</span> <span class=\"n\">new_graph</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">value</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">add_const</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">constraint</span><span class=\"p\">,</span> <span class=\"n\">constraints</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Add the constraint to constraints if the resulting graph is acyclic&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"n\">constraint</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">finish</span> <span class=\"ow\">or</span> <span class=\"n\">constraint</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">start</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">return</span> <span class=\"n\">constraints</span>\n",
       "\n",
       "        <span class=\"n\">new_constraints</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">constraints</span><span class=\"p\">)</span>\n",
       "        <span class=\"n\">new_constraints</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">constraint</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">cyclic</span><span class=\"p\">(</span><span class=\"n\">new_constraints</span><span class=\"p\">):</span>\n",
       "            <span class=\"k\">return</span> <span class=\"n\">constraints</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">new_constraints</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">is_a_threat</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">precondition</span><span class=\"p\">,</span> <span class=\"n\">effect</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Check if effect is a threat to precondition&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">effect</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;Not&#39;</span> <span class=\"o\">+</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">precondition</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">))</span> <span class=\"ow\">or</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\">effect</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"nb\">str</span><span class=\"p\">(</span><span class=\"n\">precondition</span><span class=\"o\">.</span><span class=\"n\">op</span><span class=\"p\">)):</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">effect</span><span class=\"o\">.</span><span class=\"n\">args</span> <span class=\"o\">==</span> <span class=\"n\">precondition</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">True</span>\n",
       "        <span class=\"k\">return</span> <span class=\"bp\">False</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">protect</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">causal_link</span><span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"n\">constraints</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Check and resolve threats by promotion or demotion&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">threat</span> <span class=\"o\">=</span> <span class=\"bp\">False</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">effect</span> <span class=\"ow\">in</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">effect</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">is_a_threat</span><span class=\"p\">(</span><span class=\"n\">causal_link</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">],</span> <span class=\"n\">effect</span><span class=\"p\">):</span>\n",
       "                <span class=\"n\">threat</span> <span class=\"o\">=</span> <span class=\"bp\">True</span>\n",
       "                <span class=\"k\">break</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"n\">action</span> <span class=\"o\">!=</span> <span class=\"n\">causal_link</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">and</span> <span class=\"n\">action</span> <span class=\"o\">!=</span> <span class=\"n\">causal_link</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">]</span> <span class=\"ow\">and</span> <span class=\"n\">threat</span><span class=\"p\">:</span>\n",
       "            <span class=\"c1\"># try promotion</span>\n",
       "            <span class=\"n\">new_constraints</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">constraints</span><span class=\"p\">)</span>\n",
       "            <span class=\"n\">new_constraints</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">((</span><span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"n\">causal_link</span><span class=\"p\">[</span><span class=\"mi\">0</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\">cyclic</span><span class=\"p\">(</span><span class=\"n\">new_constraints</span><span class=\"p\">):</span>\n",
       "                <span class=\"n\">constraints</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_const</span><span class=\"p\">((</span><span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"n\">causal_link</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]),</span> <span class=\"n\">constraints</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                <span class=\"c1\"># try demotion</span>\n",
       "                <span class=\"n\">new_constraints</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">constraints</span><span class=\"p\">)</span>\n",
       "                <span class=\"n\">new_constraints</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">((</span><span class=\"n\">causal_link</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"n\">action</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\">cyclic</span><span class=\"p\">(</span><span class=\"n\">new_constraints</span><span class=\"p\">):</span>\n",
       "                    <span class=\"n\">constraints</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_const</span><span class=\"p\">((</span><span class=\"n\">causal_link</span><span class=\"p\">[</span><span class=\"mi\">2</span><span class=\"p\">],</span> <span class=\"n\">action</span><span class=\"p\">),</span> <span class=\"n\">constraints</span><span class=\"p\">)</span>\n",
       "                <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                    <span class=\"c1\"># both promotion and demotion fail</span>\n",
       "                    <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Unable to resolve a threat caused by&#39;</span><span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"s1\">&#39;onto&#39;</span><span class=\"p\">,</span> <span class=\"n\">causal_link</span><span class=\"p\">)</span>\n",
       "                    <span class=\"k\">return</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">constraints</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\">constraints</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Convert constraints into a dict of Action to set orderings&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">graph</span> <span class=\"o\">=</span> <span class=\"nb\">dict</span><span class=\"p\">()</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">constraint</span> <span class=\"ow\">in</span> <span class=\"n\">constraints</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">if</span> <span class=\"n\">constraint</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"ow\">in</span> <span class=\"n\">graph</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">graph</span><span class=\"p\">[</span><span class=\"n\">constraint</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">constraint</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n",
       "            <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">graph</span><span class=\"p\">[</span><span class=\"n\">constraint</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">()</span>\n",
       "                <span class=\"n\">graph</span><span class=\"p\">[</span><span class=\"n\">constraint</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]]</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">constraint</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">graph</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">toposort</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">graph</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Generate topological ordering of constraints&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">graph</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">return</span>\n",
       "\n",
       "        <span class=\"n\">graph</span> <span class=\"o\">=</span> <span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">copy</span><span class=\"p\">()</span>\n",
       "\n",
       "        <span class=\"k\">for</span> <span class=\"n\">k</span><span class=\"p\">,</span> <span class=\"n\">v</span> <span class=\"ow\">in</span> <span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">():</span>\n",
       "            <span class=\"n\">v</span><span class=\"o\">.</span><span class=\"n\">discard</span><span class=\"p\">(</span><span class=\"n\">k</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"n\">extra_elements_in_dependencies</span> <span class=\"o\">=</span> <span class=\"n\">_reduce</span><span class=\"p\">(</span><span class=\"nb\">set</span><span class=\"o\">.</span><span class=\"n\">union</span><span class=\"p\">,</span> <span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">values</span><span class=\"p\">())</span> <span class=\"o\">-</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">keys</span><span class=\"p\">())</span>\n",
       "\n",
       "        <span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">update</span><span class=\"p\">({</span><span class=\"n\">element</span><span class=\"p\">:</span><span class=\"nb\">set</span><span class=\"p\">()</span> <span class=\"k\">for</span> <span class=\"n\">element</span> <span class=\"ow\">in</span> <span class=\"n\">extra_elements_in_dependencies</span><span class=\"p\">})</span>\n",
       "        <span class=\"k\">while</span> <span class=\"bp\">True</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">ordered</span> <span class=\"o\">=</span> <span class=\"nb\">set</span><span class=\"p\">(</span><span class=\"n\">element</span> <span class=\"k\">for</span> <span class=\"n\">element</span><span class=\"p\">,</span> <span class=\"n\">dependency</span> <span class=\"ow\">in</span> <span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">()</span> <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">dependency</span><span class=\"p\">)</span> <span class=\"o\">==</span> <span class=\"mi\">0</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">ordered</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">break</span>\n",
       "            <span class=\"k\">yield</span> <span class=\"n\">ordered</span>\n",
       "            <span class=\"n\">graph</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"n\">element</span><span class=\"p\">:</span> <span class=\"p\">(</span><span class=\"n\">dependency</span> <span class=\"o\">-</span> <span class=\"n\">ordered</span><span class=\"p\">)</span> <span class=\"k\">for</span> <span class=\"n\">element</span><span class=\"p\">,</span> <span class=\"n\">dependency</span> <span class=\"ow\">in</span> <span class=\"n\">graph</span><span class=\"o\">.</span><span class=\"n\">items</span><span class=\"p\">()</span> <span class=\"k\">if</span> <span class=\"n\">element</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"n\">ordered</span><span class=\"p\">}</span>\n",
       "        <span class=\"k\">if</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">graph</span><span class=\"p\">)</span> <span class=\"o\">!=</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">raise</span> <span class=\"ne\">ValueError</span><span class=\"p\">(</span><span class=\"s1\">&#39;The graph is not acyclic and cannot be linearly ordered&#39;</span><span class=\"p\">)</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">display_plan</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Display causal links, constraints and the plan&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Causal Links&#39;</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">causal_link</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">causal_links</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">causal_link</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">Constraints&#39;</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">for</span> <span class=\"n\">constraint</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"n\">constraint</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">],</span> <span class=\"s1\">&#39;&lt;&#39;</span><span class=\"p\">,</span> <span class=\"n\">constraint</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">])</span>\n",
       "\n",
       "        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;</span><span class=\"se\">\\n</span><span class=\"s1\">Partial Order Plan&#39;</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"nb\">reversed</span><span class=\"p\">(</span><span class=\"nb\">list</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">toposort</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">convert</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span><span class=\"p\">))))))</span>\n",
       "\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">execute</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">display</span><span class=\"o\">=</span><span class=\"bp\">True</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Execute the algorithm&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">step</span> <span class=\"o\">=</span> <span class=\"mi\">1</span>\n",
       "        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">tries</span> <span class=\"o\">=</span> <span class=\"mi\">1</span>\n",
       "        <span class=\"k\">while</span> <span class=\"nb\">len</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">agenda</span><span class=\"p\">)</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">step</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span>\n",
       "            <span class=\"c1\"># select &lt;G, act1&gt; from Agenda</span>\n",
       "            <span class=\"k\">try</span><span class=\"p\">:</span>\n",
       "                <span class=\"n\">G</span><span class=\"p\">,</span> <span class=\"n\">act1</span><span class=\"p\">,</span> <span class=\"n\">possible_actions</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">find_open_precondition</span><span class=\"p\">()</span>\n",
       "            <span class=\"k\">except</span> <span class=\"ne\">IndexError</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Probably Wrong&#39;</span><span class=\"p\">)</span>\n",
       "                <span class=\"k\">break</span>\n",
       "\n",
       "            <span class=\"n\">act0</span> <span class=\"o\">=</span> <span class=\"n\">possible_actions</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span>\n",
       "            <span class=\"c1\"># remove &lt;G, act1&gt; from Agenda</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">agenda</span><span class=\"o\">.</span><span class=\"n\">remove</span><span class=\"p\">((</span><span class=\"n\">G</span><span class=\"p\">,</span> <span class=\"n\">act1</span><span class=\"p\">))</span>\n",
       "\n",
       "            <span class=\"c1\"># For actions with variable number of arguments, use least commitment principle</span>\n",
       "            <span class=\"c1\"># act0_temp, bindings = self.find_action_for_precondition(G)</span>\n",
       "            <span class=\"c1\"># act0 = self.generate_action_object(act0_temp, bindings)</span>\n",
       "\n",
       "            <span class=\"c1\"># Actions = Actions U {act0}</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">actions</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">(</span><span class=\"n\">act0</span><span class=\"p\">)</span>\n",
       "\n",
       "            <span class=\"c1\"># Constraints = add_const(start &lt; act0, Constraints)</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_const</span><span class=\"p\">((</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">start</span><span class=\"p\">,</span> <span class=\"n\">act0</span><span class=\"p\">),</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span><span class=\"p\">)</span>\n",
       "\n",
       "            <span class=\"c1\"># for each CL E CausalLinks do</span>\n",
       "            <span class=\"c1\">#   Constraints = protect(CL, act0, Constraints)</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">causal_link</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">causal_links</span><span class=\"p\">:</span>\n",
       "                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">protect</span><span class=\"p\">(</span><span class=\"n\">causal_link</span><span class=\"p\">,</span> <span class=\"n\">act0</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span><span class=\"p\">)</span>\n",
       "\n",
       "            <span class=\"c1\"># Agenda = Agenda U {&lt;P, act0&gt;: P is a precondition of act0}</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">precondition</span> <span class=\"ow\">in</span> <span class=\"n\">act0</span><span class=\"o\">.</span><span class=\"n\">precond</span><span class=\"p\">:</span>\n",
       "                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">agenda</span><span class=\"o\">.</span><span class=\"n\">add</span><span class=\"p\">((</span><span class=\"n\">precondition</span><span class=\"p\">,</span> <span class=\"n\">act0</span><span class=\"p\">))</span>\n",
       "\n",
       "            <span class=\"c1\"># Constraints = add_const(act0 &lt; act1, Constraints)</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">add_const</span><span class=\"p\">((</span><span class=\"n\">act0</span><span class=\"p\">,</span> <span class=\"n\">act1</span><span class=\"p\">),</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span><span class=\"p\">)</span>\n",
       "\n",
       "            <span class=\"c1\"># CausalLinks U {&lt;act0, G, act1&gt;}</span>\n",
       "            <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">act0</span><span class=\"p\">,</span> <span class=\"n\">G</span><span class=\"p\">,</span> <span class=\"n\">act1</span><span class=\"p\">)</span> <span class=\"ow\">not</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">causal_links</span><span class=\"p\">:</span>\n",
       "                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">causal_links</span><span class=\"o\">.</span><span class=\"n\">append</span><span class=\"p\">((</span><span class=\"n\">act0</span><span class=\"p\">,</span> <span class=\"n\">G</span><span class=\"p\">,</span> <span class=\"n\">act1</span><span class=\"p\">))</span>\n",
       "\n",
       "            <span class=\"c1\"># for each A E Actions do</span>\n",
       "            <span class=\"c1\">#   Constraints = protect(&lt;act0, G, act1&gt;, A, Constraints)</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">action</span> <span class=\"ow\">in</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">actions</span><span class=\"p\">:</span>\n",
       "                <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">protect</span><span class=\"p\">((</span><span class=\"n\">act0</span><span class=\"p\">,</span> <span class=\"n\">G</span><span class=\"p\">,</span> <span class=\"n\">act1</span><span class=\"p\">),</span> <span class=\"n\">action</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span><span class=\"p\">)</span>\n",
       "\n",
       "            <span class=\"k\">if</span> <span class=\"n\">step</span> <span class=\"o\">&gt;</span> <span class=\"mi\">200</span><span class=\"p\">:</span>\n",
       "                <span class=\"k\">print</span><span class=\"p\">(</span><span class=\"s1\">&#39;Couldn</span><span class=\"se\">\\&#39;</span><span class=\"s1\">t find a solution&#39;</span><span class=\"p\">)</span>\n",
       "                <span class=\"k\">return</span> <span class=\"bp\">None</span><span class=\"p\">,</span> <span class=\"bp\">None</span>\n",
       "\n",
       "        <span class=\"k\">if</span> <span class=\"n\">display</span><span class=\"p\">:</span>\n",
       "            <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">display_plan</span><span class=\"p\">()</span>\n",
       "        <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">constraints</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">causal_links</span>                \n",
       "</pre></div>\n",
       "</body>\n",
       "</html>\n"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "psource(PartialOrderPlanner)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will first describe the data-structures and helper methods used, followed by the algorithm used to find a partial-order plan."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Each plan has the following four components:\n",
    "\n",
    "1. **`actions`**: a set of actions that make up the steps of the plan.\n",
    "`actions` is always a subset of `pddl.actions` the set of possible actions for the given planning problem. \n",
    "The `start` and `finish` actions are dummy actions defined to bring uniformity to the problem. The `start` action has no preconditions and its effects constitute the initial state of the planning problem. \n",
    "The `finish` action has no effects and its preconditions constitute the goal state of the planning problem.\n",
    "The empty plan consists of just these two dummy actions.\n",
    "2. **`constraints`**: a set of temporal constraints that define the order of performing the actions relative to each other.\n",
    "`constraints` does not define a linear ordering, rather it usually represents a directed graph which is also acyclic if the plan is consistent.\n",
    "Each ordering is of the form A &lt; B, which reads as \"A before B\" and means that action A _must_ be executed sometime before action B, but not necessarily immediately before.\n",
    "`constraints` stores these as a set of tuples `(Action(A), Action(B))` which is interpreted as given above.\n",
    "A constraint cannot be added to `constraints` if it breaks the acyclicity of the existing graph.\n",
    "3. **`causal_links`**: a set of causal-links. \n",
    "A causal link between two actions _A_ and _B_ in the plan is written as _A_ --_p_--> _B_ and is read as \"A achieves p for B\".\n",
    "This imples that _p_ is an effect of _A_ and a precondition of _B_.\n",
    "It also asserts that _p_ must remain true from the time of action _A_ to the time of action _B_.\n",
    "Any violation of this rule is called a threat and must be resolved immediately by adding suitable ordering constraints.\n",
    "`causal_links` stores this information as tuples `(Action(A), precondition(p), Action(B))` which is interpreted as given above.\n",
    "Causal-links can also be called **protection-intervals**, because the link _A_ --_p_--> _B_ protects _p_ from being negated over the interval from _A_ to _B_.\n",
    "4. **`agenda`**: a set of open-preconditions.\n",
    "A precondition is open if it is not achieved by some action in the plan.\n",
    "Planners will work to reduce the set of open preconditions to the empty set, without introducing a contradiction.\n",
    "`agenda` stored this information as tuples `(precondition(p), Action(A))` where p is a precondition of the action A.\n",
    "\n",
    "A **consistent plan** is a plan in which there are no cycles in the ordering constraints and no conflicts with the causal-links.\n",
    "A consistent plan with no open preconditions is a **solution**.\n",
    "<br>\n",
    "Let's briefly glance over the helper functions before going into the actual algorithm.\n",
4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579 4580 4581 4582 4583 4584 4585 4586 4587 4588 4589 4590 4591 4592 4593 4594 4595 4596 4597 4598 4599 4600 4601 4602 4603 4604 4605 4606 4607 4608 4609 4610 4611 4612 4613 4614 4615 4616 4617 4618 4619 4620 4621 4622 4623 4624 4625 4626 4627 4628 4629 4630 4631 4632 4633 4634 4635 4636 4637 4638 4639 4640 4641 4642 4643 4644 4645 4646 4647 4648 4649 4650 4651 4652 4653 4654 4655 4656 4657 4658 4659 4660 4661 4662 4663 4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674 4675 4676 4677 4678 4679 4680 4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691 4692 4693 4694 4695 4696 4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707 4708 4709 4710 4711 4712 4713 4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724 4725 4726 4727 4728 4729 4730 4731 4732 4733 4734 4735 4736 4737 4738 4739 4740 4741 4742 4743 4744 4745 4746 4747 4748 4749 4750 4751 4752 4753 4754 4755 4756 4757 4758 4759 4760 4761 4762 4763 4764 4765 4766 4767 4768 4769 4770 4771 4772 4773 4774 4775 4776 4777 4778 4779 4780 4781 4782 4783 4784 4785 4786 4787 4788 4789 4790 4791 4792 4793 4794 4795 4796 4797 4798 4799 4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813 4814 4815 4816 4817 4818 4819 4820 4821 4822 4823 4824 4825 4826 4827 4828 4829 4830 4831 4832 4833 4834 4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855 4856 4857 4858 4859 4860 4861 4862 4863 4864 4865 4866 4867 4868 4869 4870 4871 4872
    "**`expand_actions`**: generates all possible actions with variable bindings for use as a heuristic of selection of an open precondition.\n",
    "<br>\n",
    "**`find_open_precondition`**: finds a precondition from the agenda with the least number of actions that fulfil that precondition.\n",
    "This heuristic helps form mandatory ordering constraints and causal-links to further simplify the problem and reduce the probability of encountering a threat.\n",
    "<br>\n",
    "**`find_action_for_precondition`**: finds an action that fulfils the given precondition along with the absolutely necessary variable bindings in accordance with the principle of _least commitment_.\n",
    "In case of multiple possible actions, the action with the least number of effects is chosen to minimize the chances of encountering a threat.\n",
    "<br>\n",
    "**`cyclic`**: checks if a directed graph is cyclic.\n",
    "<br>\n",
    "**`add_const`**: adds `constraint` to `constraints` if the newly formed graph is acyclic and returns `constraints` otherwise.\n",
    "<br>\n",
    "**`is_a_threat`**: checks if the given `effect` negates the given `precondition`.\n",
    "<br>\n",
    "**`protect`**: checks if the given `action` poses a threat to the given `causal_link`.\n",
    "If so, the threat is resolved by either promotion or demotion, whichever generates acyclic temporal constraints.\n",
    "If neither promotion or demotion work, the chosen action is not the correct fit or the planning problem cannot be solved altogether.\n",
    "<br>\n",
    "**`convert`**: converts a graph from a list of edges to an `Action` : `set` mapping, for use in topological sorting.\n",
    "<br>\n",
    "**`toposort`**: a generator function that generates a topological ordering of a given graph as a list of sets.\n",
    "Each set contains an action or several actions.\n",
    "If a set has more that one action in it, it means that permutations between those actions also produce a valid plan.\n",
    "<br>\n",
    "**`display_plan`**: displays the `causal_links`, `constraints` and the partial order plan generated from `toposort`.\n",
    "<br>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The **`execute`** method executes the algorithm, which is summarized below:\n",
    "<br>\n",
    "1. An open precondition is selected (a sub-goal that we want to achieve).\n",
    "2. An action that fulfils the open precondition is chosen.\n",
    "3. Temporal constraints are updated.\n",
    "4. Existing causal links are protected. Protection is a method that checks if the causal links conflict\n",
    "   and if they do, temporal constraints are added to fix the threats.\n",
    "5. The set of open preconditions is updated.\n",
    "6. Temporal constraints of the selected action and the next action are established.\n",
    "7. A new causal link is added between the selected action and the owner of the open precondition.\n",
    "8. The set of new causal links is checked for threats and if found, the threat is removed by either promotion or demotion.\n",
    "   If promotion or demotion is unable to solve the problem, the planning problem cannot be solved with the current sequence of actions\n",
    "   or it may not be solvable at all.\n",
    "9. These steps are repeated until the set of open preconditions is empty."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A partial-order plan can be used to generate different valid total-order plans.\n",
    "This step is called **linearization** of the partial-order plan.\n",
    "All possible linearizations of a partial-order plan for `socks_and_shoes` looks like this.\n",
    "<br>\n",
    "![title](images/pop.jpg)\n",
    "<br>\n",
    "Linearization can be carried out in many ways, but the most efficient way is to represent the set of temporal constraints as a directed graph.\n",
    "We can easily realize that the graph should also be acyclic as cycles in constraints means that the constraints are inconsistent.\n",
    "This acyclicity is enforced by the `add_const` method, which adds a new constraint only if the acyclicity of the existing graph is not violated.\n",
    "The `protect` method also checks for acyclicity of the newly-added temporal constraints to make a decision between promotion and demotion in case of a threat.\n",
    "This property of a graph created from the temporal constraints of a valid partial-order plan allows us to use topological sort to order the constraints linearly.\n",
    "A topological sort may produce several different valid solutions for a given directed acyclic graph."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now that we know how `PartialOrderPlanner` works, let's solve a few problems using it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Causal Links\n",
      "(Action(PutOn(Spare, Axle)), At(Spare, Axle), Action(Finish))\n",
      "(Action(Start), Tire(Spare), Action(PutOn(Spare, Axle)))\n",
      "(Action(Remove(Flat, Axle)), NotAt(Flat, Axle), Action(PutOn(Spare, Axle)))\n",
      "(Action(Start), At(Flat, Axle), Action(Remove(Flat, Axle)))\n",
      "(Action(Remove(Spare, Trunk)), At(Spare, Ground), Action(PutOn(Spare, Axle)))\n",
      "(Action(Start), At(Spare, Trunk), Action(Remove(Spare, Trunk)))\n",
      "(Action(Remove(Flat, Axle)), At(Flat, Ground), Action(Finish))\n",
      "\n",
      "Constraints\n",
      "Action(Start) < Action(Finish)\n",
      "Action(Start) < Action(Remove(Spare, Trunk))\n",
      "Action(Remove(Flat, Axle)) < Action(PutOn(Spare, Axle))\n",
      "Action(Remove(Flat, Axle)) < Action(Finish)\n",
      "Action(Remove(Spare, Trunk)) < Action(PutOn(Spare, Axle))\n",
      "Action(Start) < Action(PutOn(Spare, Axle))\n",
      "Action(Start) < Action(Remove(Flat, Axle))\n",
      "Action(PutOn(Spare, Axle)) < Action(Finish)\n",
      "\n",
      "Partial Order Plan\n",
      "[{Action(Start)}, {Action(Remove(Flat, Axle)), Action(Remove(Spare, Trunk))}, {Action(PutOn(Spare, Axle))}, {Action(Finish)}]\n"
     ]
    }
   ],
   "source": [
    "st = spare_tire()\n",
    "pop = PartialOrderPlanner(st)\n",
    "pop.execute()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We observe that in the given partial order plan, Remove(Flat, Axle) and Remove(Spare, Trunk) are in the same set.\n",
    "This means that the order of performing these actions does not affect the final outcome.\n",
    "That aside, we also see that the PutOn(Spare, Axle) action has to be performed after both the Remove actions are complete, which seems logically consistent."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Causal Links\n",
      "(Action(FromTable(B, A)), On(B, A), Action(Finish))\n",
      "(Action(FromTable(C, B)), On(C, B), Action(Finish))\n",
      "(Action(Start), Clear(C), Action(FromTable(C, B)))\n",
      "(Action(Start), Clear(A), Action(FromTable(B, A)))\n",
      "(Action(Start), OnTable(C), Action(FromTable(C, B)))\n",
      "(Action(Start), OnTable(B), Action(FromTable(B, A)))\n",
      "(Action(ToTable(A, B)), Clear(B), Action(FromTable(C, B)))\n",
      "(Action(Start), On(A, B), Action(ToTable(A, B)))\n",
      "(Action(ToTable(A, B)), Clear(B), Action(FromTable(B, A)))\n",
      "(Action(Start), Clear(A), Action(ToTable(A, B)))\n",
      "\n",
      "Constraints\n",
      "Action(Start) < Action(FromTable(B, A))\n",
      "Action(Start) < Action(FromTable(C, B))\n",
      "Action(Start) < Action(ToTable(A, B))\n",
      "Action(ToTable(A, B)) < Action(FromTable(C, B))\n",
      "Action(Start) < Action(Finish)\n",
      "Action(ToTable(A, B)) < Action(FromTable(B, A))\n",
      "Action(FromTable(C, B)) < Action(Finish)\n",
      "Action(FromTable(B, A)) < Action(Finish)\n",
      "Action(FromTable(B, A)) < Action(FromTable(C, B))\n",
      "\n",
      "Partial Order Plan\n",
      "[{Action(Start)}, {Action(ToTable(A, B))}, {Action(FromTable(B, A))}, {Action(FromTable(C, B))}, {Action(Finish)}]\n"
     ]
    }
   ],
   "source": [
    "sbw = simple_blocks_world()\n",
    "pop = PartialOrderPlanner(sbw)\n",
    "pop.execute()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "We see that this plan does not have flexibility in selecting actions, ie, actions should be performed in this order and this order only, to successfully reach the goal state."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Causal Links\n",
      "(Action(RightShoe), RightShoeOn, Action(Finish))\n",
      "(Action(LeftShoe), LeftShoeOn, Action(Finish))\n",
      "(Action(LeftSock), LeftSockOn, Action(LeftShoe))\n",
      "(Action(RightSock), RightSockOn, Action(RightShoe))\n",
      "\n",
      "Constraints\n",
      "Action(Start) < Action(RightSock)\n",
      "Action(Start) < Action(LeftSock)\n",
      "Action(RightSock) < Action(RightShoe)\n",
      "Action(RightShoe) < Action(Finish)\n",
      "Action(Start) < Action(LeftShoe)\n",
      "Action(LeftSock) < Action(LeftShoe)\n",
      "Action(Start) < Action(RightShoe)\n",
      "Action(Start) < Action(Finish)\n",
      "Action(LeftShoe) < Action(Finish)\n",
      "\n",
      "Partial Order Plan\n",
      "[{Action(Start)}, {Action(LeftSock), Action(RightSock)}, {Action(RightShoe), Action(LeftShoe)}, {Action(Finish)}]\n"
     ]
    }
   ],
   "source": [
    "ss = socks_and_shoes()\n",
    "pop = PartialOrderPlanner(ss)\n",
    "pop.execute()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "This plan again doesn't have constraints in selecting socks or shoes.\n",
    "As long as both socks are worn before both shoes, we are fine.\n",
    "Notice however, there is one valid solution,\n",
    "<br>\n",
    "LeftSock -> LeftShoe -> RightSock -> RightShoe\n",
    "<br>\n",
    "that the algorithm could not find as it cannot be represented as a general partially-ordered plan but is a specific total-order solution."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Runtime differences\n",
    "Let's briefly take a look at the running time of all the three algorithms on the `socks_and_shoes` problem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 70,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "ss = socks_and_shoes()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 71,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "333 µs ± 8.86 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "GraphPlan(ss).execute()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 72,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1.29 ms ± 43.6 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "Linearize(ss).execute()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "425 µs ± 17 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)\n"
     ]
    }
   ],
   "source": [
    "%%timeit\n",
    "PartialOrderPlanner(ss).execute(display=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We observe that `GraphPlan` is about 4 times faster than `Linearize` because `Linearize` essentially runs a `GraphPlan` subroutine under the hood and then carries out some transformations on the solved planning-graph.\n",
    "<br>\n",
    "We also find that `GraphPlan` is slightly faster than `PartialOrderPlanner`, but this is mainly due to the `expand_actions` method in `PartialOrderPlanner` that slows it down as it generates all possible permutations of actions and variable bindings.\n",
    "<br>\n",
    "Without heuristic functions, `PartialOrderPlanner` will be atleast as fast as `GraphPlan`, if not faster, but will have a higher tendency to encounter threats and conflicts which might take additional time to resolve.\n",
    "<br>\n",
    "Different planning algorithms work differently for different problems."
   ]
  },
  {
   "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."
   "execution_count": 74,
   "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",
       "<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",
       "    <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",
       "<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",
       "    <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\"># TODO - 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;: [&#39;Go(Home,SFO)&#39;, &#39;Go(Home,SFO)&#39;, &#39;Drive(Home, SFOLongTermParking)&#39;, &#39;Shuttle(SFOLongTermParking, SFO)&#39;, &#39;Taxi(Home, SFO)&#39;],</span>\n",
       "<span class=\"sd\">        &#39;steps&#39;: [[&#39;Drive(Home, SFOLongTermParking)&#39;, &#39;Shuttle(SFOLongTermParking, SFO)&#39;], [&#39;Taxi(Home, SFO)&#39;], [], [], []],</span>\n",
       "<span class=\"sd\">        # empty refinements ie primitive action</span>\n",
       "<span class=\"sd\">        &#39;precond&#39;: [[&#39;At(Home), Have(Car)&#39;], [&#39;At(Home)&#39;], [&#39;At(Home)&#39;, &#39;Have(Car)&#39;], [&#39;At(SFOLongTermParking)&#39;], [&#39;At(Home)&#39;]],</span>\n",
       "<span class=\"sd\">        &#39;effect&#39;: [[&#39;At(SFO)&#39;], [&#39;At(SFO)&#39;], [&#39;At(SFOLongTermParking)&#39;], [&#39;At(SFO)&#39;], [&#39;At(SFO)&#39;], [&#39;~At(Home)&#39;], [&#39;~At(Home)&#39;], [&#39;~At(Home)&#39;], [&#39;~At(SFOLongTermParking)&#39;], [&#39;~At(Home)&#39;]]</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=\"c1\"># TODO multiple refinements</span>\n",
       "            <span class=\"n\">precond</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">p</span> <span class=\"ow\">in</span> <span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s1\">&#39;precond&#39;</span><span class=\"p\">][</span><span class=\"n\">i</span><span class=\"p\">]:</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">p</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</span> <span class=\"o\">==</span> <span class=\"s1\">&#39;~&#39;</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">precond</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=\"n\">p</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]))</span>\n",
       "                <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">precond</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=\"n\">p</span><span class=\"p\">))</span>\n",
       "            <span class=\"n\">effect</span> <span class=\"o\">=</span> <span class=\"p\">[]</span>\n",
       "            <span class=\"k\">for</span> <span class=\"n\">e</span> <span class=\"ow\">in</span> <span class=\"n\">library</span><span class=\"p\">[</span><span class=\"s1\">&#39;effect&#39;</span><span class=\"p\">][</span><span class=\"n\">i</span><span class=\"p\">]:</span>\n",
       "                <span class=\"k\">if</span> <span class=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">0</span><span class=\"p\">]</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=\"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=\"n\">e</span><span class=\"p\">[</span><span class=\"mi\">1</span><span class=\"p\">:]))</span>\n",
       "                <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "                    <span class=\"n\">effect</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=\"n\">e</span><span class=\"p\">))</span>\n",
       "            <span class=\"n\">action</span> <span class=\"o\">=</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=\"mi\">0</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=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">check_precond</span><span class=\"p\">(</span><span class=\"n\">state</span><span class=\"o\">.</span><span class=\"n\">init</span><span class=\"p\">,</span> <span class=\"n\">action</span><span class=\"o\">.</span><span class=\"n\">args</span><span class=\"p\">):</span>\n",
       "                <span class=\"k\">yield</span> <span class=\"n\">action</span>\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",
       "    <span class=\"k\">def</span> <span class=\"nf\">result</span><span class=\"p\">(</span><span class=\"n\">problem</span><span class=\"p\">,</span> <span class=\"n\">action</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\">if</span> <span class=\"n\">action</span> <span class=\"ow\">is</span> <span class=\"ow\">not</span> <span class=\"bp\">None</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">problem</span><span class=\"o\">.</span><span class=\"n\">act</span><span class=\"p\">(</span><span class=\"n\">action</span><span class=\"p\">)</span>\n",
       "            <span class=\"k\">return</span> <span class=\"n\">problem</span>\n",
       "        <span class=\"k\">else</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">return</span> <span class=\"n\">problem</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": 75,
   "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",
       "    <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",
       "    <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",
       "    <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",
       "    <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"
    "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",
    "Let's look at how the `job_shop_problem` has been defined on the  module."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 76,
   "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",
       "<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",
       "<span class=\"sd\">    A job-shop scheduling problem for assembling two cars,</span>\n",
       "<span class=\"sd\">    with resource and ordering constraints.</span>\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",
       "    <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",
       "    <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",
       "    <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",
       "    <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",
    "Our goal is to have engines and wheels on both cars and to get them inspected. We will discuss how to achieve this.\n",
    "Let's define an object of the `job_shop_problem`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 77,
   "metadata": {
    "collapsed": true
   },
   "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": 78,
   "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": 79,
   "metadata": {
    "collapsed": true
   },
   "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": 80,
   "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",
    "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": 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\">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",
       "<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",
       "<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",
       "    <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(x, LeftNet) &amp; At(y, 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": 82,
   "metadata": {
    "collapsed": true
   },
   "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": 83,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "False\n"
     ]
    "print(goal_test(doubleTennisProblem.goals, doubleTennisProblem.init))"
   ]
  },
  {
   "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": 84,
   "metadata": {
    "collapsed": true
   },
   "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": 85,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
     "execution_count": 85,
     "metadata": {},
     "output_type": "execute_result"
    "goal_test(doubleTennisProblem.goals, doubleTennisProblem.init)"
   ]
  },
  {
   "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.6.1"
 "nbformat_minor": 1