planning.ipynb 184 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 `PDDL` 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,
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from planning import *\n",
    "from notebook import psource"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## CONTENTS\n",
    "\n",
    "- PDDL\n",
    "- Action\n",
    "- Planning Problems\n",
    "    * Air cargo problem\n",
    "    * Spare tire problem\n",
    "    * Three block tower problem\n",
    "    * Shopping Problem\n",
    "    * Cake problem\n",
    "- Solving Planning Problems\n",
    "    * GraphPlan"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## PDDL\n",
    "\n",
    "PDDL stands for Planning Domain Definition Language.\n",
    "The `PDDL` 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\">PDDL</span><span class=\"p\">:</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;</span>\n",
       "<span class=\"sd\">    Planning Domain Definition Language (PDDL) 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=\"n\">expr</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\">init</span><span class=\"p\">):</span>\n",
       "        <span class=\"sd\">&quot;&quot;&quot;Converts strings into exprs&quot;&quot;&quot;</span>\n",
       "        <span class=\"k\">try</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">init</span> <span class=\"o\">=</span> <span class=\"n\">conjuncts</span><span class=\"p\">(</span><span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">))</span>\n",
       "        <span class=\"k\">except</span> <span class=\"ne\">AttributeError</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">init</span> <span class=\"o\">=</span> <span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"n\">init</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">return</span> <span class=\"n\">init</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=\"n\">conjuncts</span><span class=\"p\">(</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(PDDL)"
   ]
  },
  {
   "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 PDDL.</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=\"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=\"p\">,</span> <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\">precond</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=\"nf\">convert</span><span class=\"p\">(</span><span class=\"bp\">self</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=\"sd\">&quot;&quot;&quot;Converts strings into Exprs&quot;&quot;&quot;</span>\n",
       "\n",
       "        <span class=\"n\">precond</span> <span class=\"o\">=</span> <span class=\"n\">precond</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\">precond</span><span class=\"p\">)</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">precond</span> <span class=\"o\">=</span> <span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"n\">precond</span><span class=\"p\">)</span>\n",
       "        <span class=\"n\">effect</span> <span class=\"o\">=</span> <span class=\"n\">effect</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\">effect</span><span class=\"p\">)</span> <span class=\"o\">&gt;</span> <span class=\"mi\">0</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">effect</span> <span class=\"o\">=</span> <span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"n\">effect</span><span class=\"p\">)</span>\n",
       "\n",
       "        <span class=\"k\">try</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">precond</span> <span class=\"o\">=</span> <span class=\"n\">conjuncts</span><span class=\"p\">(</span><span class=\"n\">precond</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\">try</span><span class=\"p\">:</span>\n",
       "            <span class=\"n\">effect</span> <span class=\"o\">=</span> <span class=\"n\">conjuncts</span><span class=\"p\">(</span><span class=\"n\">effect</span><span class=\"p\">)</span>\n",
       "        <span class=\"k\">except</span> <span class=\"ne\">AttributeError</span><span class=\"p\">:</span>\n",
       "            <span class=\"k\">pass</span>\n",
       "\n",
       "        <span class=\"k\">return</span> <span class=\"n\">precond</span><span class=\"p\">,</span> <span class=\"n\">effect</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",
       "\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 = PDDL(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;Air cargo problem&quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PDDL</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` PDDL.\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;Spare tire problem&quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PDDL</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` PDDL.\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;Sussman Anomaly problem&quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PDDL</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` PDDL.\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": [
    "## Shopping Problem"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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": 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\">shopping_problem</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;Shopping problem&quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PDDL</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"
      ],
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(shopping_problem)"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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",
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
    "\n",
    "**~At(x):** Indicates that we are currently _not_ at **'x'**.\n",
    "\n",
    "**Sells(s, x):** Indicates that item **'x'** can be bought from store **'s'**.\n",
    "\n",
    "**Have(x):** Indicates that we possess the item **'x'**."
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": [
    "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": 31,
   "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",
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
    "\n",
    "**Buy(x, store):** Buy an item **'x'** from a **'store'** given that the **'store'** sells **'x'**.\n",
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
    "\n",
    "**Go(x, y):** Go to destination **'y'** starting from source **'x'**."
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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` PDDL."
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('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)"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "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."
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "source": [
    "shoppingProblem.goal_test()"
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "It has now successfully achieved the goal."
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Have Cake and Eat Cake Too"
   ]
  },
  {
   "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."
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\">have_cake_and_eat_cake_too</span><span class=\"p\">():</span>\n",
       "    <span class=\"sd\">&quot;&quot;&quot;Cake problem&quot;&quot;&quot;</span>\n",
       "\n",
       "    <span class=\"k\">return</span> <span class=\"n\">PDDL</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",
    "**Have(Cake):** Declares that we have a **'Cake'**.\n",
    "**~Have(Cake):** Declares that we _don't_ have a **'Cake'**."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {
    "collapsed": true
   },
Kaivalya Rawal's avatar
Kaivalya Rawal a validé
   "outputs": [],
    "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": 36,
   "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",
    "**Bake(x):** To bake **' x '**.\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` PDDL."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "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": 38,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "True\n"
     ]
    "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": 39,
   "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-39-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\\Aima\\aima-python\\planning.py\u001b[0m in \u001b[0;36mact\u001b[1;34m(self, action)\u001b[0m\n\u001b[0;32m     44\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     45\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---> 46\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     47\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     48\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",
    "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 by a 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."
   "execution_count": 40,
   "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": 41,
   "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"
    "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": 42,
   "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",
       "</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 PDDL, `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",
    "<br>\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": 43,
   "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=\"n\">pddl</span> <span class=\"o\">=</span> <span class=\"n\">air_cargo</span><span class=\"p\">()</span>\n",
       "    <span class=\"n\">graphplan</span> <span class=\"o\">=</span> <span class=\"n\">GraphPlan</span><span class=\"p\">(</span><span class=\"n\">pddl</span><span class=\"p\">)</span>\n",
       "    <span class=\"k\">def</span> <span class=\"nf\">goal_test</span><span class=\"p\">(</span><span class=\"n\">kb</span><span class=\"p\">,</span> <span class=\"n\">goals</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=\"n\">goals</span><span class=\"p\">)</span>\n",
       "    <span class=\"n\">goals</span> <span class=\"o\">=</span> <span class=\"n\">expr</span><span class=\"p\">(</span><span class=\"s1\">&#39;At(C1, JFK), At(C2, SFO)&#39;</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=\"p\">(</span><span class=\"n\">goal_test</span><span class=\"p\">(</span><span class=\"n\">graphplan</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=\"n\">goals</span><span class=\"p\">)</span> <span class=\"ow\">and</span> <span class=\"n\">graphplan</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=\"o\">-</span><span class=\"mi\">1</span><span class=\"p\">)):</span>\n",
       "            <span class=\"n\">solution</span> <span class=\"o\">=</span> <span class=\"n\">graphplan</span><span class=\"o\">.</span><span class=\"n\">extract_solution</span><span class=\"p\">(</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",
       "        <span class=\"n\">graphplan</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=\"nb\">len</span><span class=\"p\">(</span><span class=\"n\">graphplan</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=\"n\">graphplan</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(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": 44,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[[[PCargo(C2),\n",
       "   Load(C2, P2, JFK),\n",
       "   PPlane(P2),\n",
       "   Load(C1, P1, SFO),\n",
       "   Fly(P1, SFO, JFK),\n",
       "   PAirport(SFO),\n",
       "   PAirport(JFK),\n",
       "   PPlane(P1),\n",
       "   PCargo(C1),\n",
       "   Fly(P2, JFK, SFO)],\n",
       "  [Unload(C2, P2, SFO), Unload(C1, P1, JFK)]]]"
      ]
     },
     "execution_count": 44,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "air_cargo = air_cargo_graphplan()\n",
    "air_cargo"
   ]
  },
  {
   "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."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Load(C2, P2, JFK),\n",
       " Load(C1, P1, SFO),\n",
       " Fly(P1, SFO, JFK),\n",
       " Fly(P2, JFK, SFO),\n",
       " Unload(C2, P2, SFO),\n",
       " Unload(C1, P1, JFK)]"
      ]
     },
     "execution_count": 45,
     "metadata": {},
     "output_type": "execute_result"
    "linearize(air_cargo)"
   ]
  },
  {
   "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": 46,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Remove(Flat, Axle), Remove(Spare, Trunk), PutOn(Spare, Axle)]"
      ]
     },
     "execution_count": 46,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "spare_tire = spare_tire_graphplan()\n",
    "linearize(spare_tire)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution for the cake problem"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Eat(Cake), Bake(Cake)]"
      ]
     },
     "execution_count": 47,
     "metadata": {},
     "output_type": "execute_result"
    "cake_problem = have_cake_and_eat_cake_too_graphplan()\n",
    "linearize(cake_problem)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution for the Sussman's Anomaly configuration of three blocks."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[MoveToTable(C, A), Move(B, Table, C), Move(A, Table, B)]"
      ]
     },
     "execution_count": 48,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sussman_anomaly = three_block_tower_graphplan()\n",
    "linearize(sussman_anomaly)"
  }
 ],
 "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