diff --git a/logic_programming/2_IntroProlog.ipynb b/logic_programming/2_IntroProlog.ipynb
index ffca183a0452fce1ff804f40ff0b2b6671e9642a..06d4722851d13643df61b8c7518cb74720d6e09a 100644
--- a/logic_programming/2_IntroProlog.ipynb
+++ b/logic_programming/2_IntroProlog.ipynb
@@ -786,6 +786,15 @@
     "?- edge(A,B,C)."
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "c137912e",
+   "metadata": {},
+   "source": [
+    "By calling jupyter:print_transition_graph(PredSpec, FromIdx, ToIdx, LabelIdx),\n",
+    "a transition graph can be created (FromIdx is the number of argument specifying the origin, ToIdx the destination and LabelIdx the label)."
+   ]
+  },
   {
    "cell_type": "code",
    "execution_count": 68,
@@ -1213,64 +1222,14 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 73,
+   "execution_count": 44,
    "id": "12f78859",
    "metadata": {
     "vscode": {
      "languageId": "prolog"
     }
    },
-   "outputs": [
-    {
-     "data": {
-      "text/html": [
-       "\n",
-       "            <style>\n",
-       "            details  {\n",
-       "              font-family: Menlo, Consolas, 'DejaVu Sans Mono', monospace; font-size: 13px;\n",
-       "            }\n",
-       "\n",
-       "            details > summary {\n",
-       "              cursor: pointer;\n",
-       "            }\n",
-       "            </style>\n",
-       "            <details><summary>Previously defined clauses of user:edge/2 were retracted (click to expand)</summary><pre>:- dynamic edge/2.\n",
-       "\n",
-       "edge(a, b).\n",
-       "edge(a, c).\n",
-       "edge(b, d).\n",
-       "edge(c, d).\n",
-       "edge(d, e).\n",
-       "edge(f, g).\n",
-       "</pre></details>"
-      ],
-      "text/plain": [
-       "Previously defined clauses of user:edge/2 were retracted:\n",
-       ":- dynamic edge/2.\n",
-       "\n",
-       "edge(a, b).\n",
-       "edge(a, c).\n",
-       "edge(b, d).\n",
-       "edge(c, d).\n",
-       "edge(d, e).\n",
-       "edge(f, g).\n"
-      ]
-     },
-     "metadata": {
-      "application/json": {}
-     },
-     "output_type": "display_data"
-    },
-    {
-     "data": {
-      "text/plain": [
-       "% Asserting clauses for user:edge/2\n"
-      ]
-     },
-     "metadata": {},
-     "output_type": "display_data"
-    }
-   ],
+   "outputs": [],
    "source": [
     "edge(a,b). edge(a,c).\n",
     "edge(b,d). edge(c,d).\n",
@@ -1288,7 +1247,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 74,
+   "execution_count": 45,
    "id": "99bfae95",
    "metadata": {
     "vscode": {
@@ -1302,7 +1261,7 @@
        "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
        "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
        " \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
-       "<!-- Generated by graphviz version 6.0.1 (20220911.1526)\n",
+       "<!-- Generated by graphviz version 10.0.1 (20240210.2158)\n",
        " -->\n",
        "<!-- Pages: 1 -->\n",
        "<svg width=\"206pt\" height=\"260pt\"\n",
@@ -1313,79 +1272,79 @@
        "<g id=\"node1\" class=\"node\">\n",
        "<title>a</title>\n",
        "<ellipse fill=\"none\" stroke=\"black\" cx=\"63\" cy=\"-234\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"63\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\">a</text>\n",
+       "<text text-anchor=\"middle\" x=\"63\" y=\"-228.95\" font-family=\"Times,serif\" font-size=\"14.00\">a</text>\n",
        "</g>\n",
        "<!-- b -->\n",
        "<g id=\"node2\" class=\"node\">\n",
        "<title>b</title>\n",
        "<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"27\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">b</text>\n",
+       "<text text-anchor=\"middle\" x=\"27\" y=\"-156.95\" font-family=\"Times,serif\" font-size=\"14.00\">b</text>\n",
        "</g>\n",
        "<!-- a&#45;&gt;b -->\n",
        "<g id=\"edge1\" class=\"edge\">\n",
        "<title>a&#45;&gt;b</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M54.65,-216.76C50.29,-208.28 44.85,-197.71 39.96,-188.2\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"42.99,-186.44 35.3,-179.15 36.77,-189.64 42.99,-186.44\"/>\n",
+       "<path fill=\"none\" stroke=\"black\" d=\"M54.65,-216.76C50.42,-208.55 45.19,-198.37 40.42,-189.09\"/>\n",
+       "<polygon fill=\"black\" stroke=\"black\" points=\"43.68,-187.79 36,-180.49 37.46,-190.99 43.68,-187.79\"/>\n",
        "</g>\n",
        "<!-- c -->\n",
        "<g id=\"node3\" class=\"node\">\n",
        "<title>c</title>\n",
        "<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"99\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">c</text>\n",
+       "<text text-anchor=\"middle\" x=\"99\" y=\"-156.95\" font-family=\"Times,serif\" font-size=\"14.00\">c</text>\n",
        "</g>\n",
        "<!-- a&#45;&gt;c -->\n",
        "<g id=\"edge2\" class=\"edge\">\n",
        "<title>a&#45;&gt;c</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M71.35,-216.76C75.71,-208.28 81.15,-197.71 86.04,-188.2\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"89.23,-189.64 90.7,-179.15 83.01,-186.44 89.23,-189.64\"/>\n",
+       "<path fill=\"none\" stroke=\"black\" d=\"M71.35,-216.76C75.58,-208.55 80.81,-198.37 85.58,-189.09\"/>\n",
+       "<polygon fill=\"black\" stroke=\"black\" points=\"88.54,-190.99 90,-180.49 82.32,-187.79 88.54,-190.99\"/>\n",
        "</g>\n",
        "<!-- d -->\n",
        "<g id=\"node4\" class=\"node\">\n",
        "<title>d</title>\n",
        "<ellipse fill=\"none\" stroke=\"black\" cx=\"63\" cy=\"-90\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"63\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">d</text>\n",
+       "<text text-anchor=\"middle\" x=\"63\" y=\"-84.95\" font-family=\"Times,serif\" font-size=\"14.00\">d</text>\n",
        "</g>\n",
        "<!-- b&#45;&gt;d -->\n",
        "<g id=\"edge3\" class=\"edge\">\n",
        "<title>b&#45;&gt;d</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M35.35,-144.76C39.71,-136.28 45.15,-125.71 50.04,-116.2\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"53.23,-117.64 54.7,-107.15 47.01,-114.44 53.23,-117.64\"/>\n",
+       "<path fill=\"none\" stroke=\"black\" d=\"M35.35,-144.76C39.58,-136.55 44.81,-126.37 49.58,-117.09\"/>\n",
+       "<polygon fill=\"black\" stroke=\"black\" points=\"52.54,-118.99 54,-108.49 46.32,-115.79 52.54,-118.99\"/>\n",
        "</g>\n",
        "<!-- c&#45;&gt;d -->\n",
        "<g id=\"edge4\" class=\"edge\">\n",
        "<title>c&#45;&gt;d</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M90.65,-144.76C86.29,-136.28 80.85,-125.71 75.96,-116.2\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"78.99,-114.44 71.3,-107.15 72.77,-117.64 78.99,-114.44\"/>\n",
+       "<path fill=\"none\" stroke=\"black\" d=\"M90.65,-144.76C86.42,-136.55 81.19,-126.37 76.42,-117.09\"/>\n",
+       "<polygon fill=\"black\" stroke=\"black\" points=\"79.68,-115.79 72,-108.49 73.46,-118.99 79.68,-115.79\"/>\n",
        "</g>\n",
        "<!-- e -->\n",
        "<g id=\"node5\" class=\"node\">\n",
        "<title>e</title>\n",
        "<ellipse fill=\"none\" stroke=\"black\" cx=\"63\" cy=\"-18\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"63\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">e</text>\n",
+       "<text text-anchor=\"middle\" x=\"63\" y=\"-12.95\" font-family=\"Times,serif\" font-size=\"14.00\">e</text>\n",
        "</g>\n",
        "<!-- d&#45;&gt;e -->\n",
        "<g id=\"edge5\" class=\"edge\">\n",
        "<title>d&#45;&gt;e</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M63,-71.7C63,-63.98 63,-54.71 63,-46.11\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"66.5,-46.1 63,-36.1 59.5,-46.1 66.5,-46.1\"/>\n",
+       "<path fill=\"none\" stroke=\"black\" d=\"M63,-71.7C63,-64.41 63,-55.73 63,-47.54\"/>\n",
+       "<polygon fill=\"black\" stroke=\"black\" points=\"66.5,-47.62 63,-37.62 59.5,-47.62 66.5,-47.62\"/>\n",
        "</g>\n",
        "<!-- f -->\n",
        "<g id=\"node6\" class=\"node\">\n",
        "<title>f</title>\n",
        "<ellipse fill=\"none\" stroke=\"black\" cx=\"171\" cy=\"-234\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"171\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\">f</text>\n",
+       "<text text-anchor=\"middle\" x=\"171\" y=\"-228.95\" font-family=\"Times,serif\" font-size=\"14.00\">f</text>\n",
        "</g>\n",
        "<!-- g -->\n",
        "<g id=\"node7\" class=\"node\">\n",
        "<title>g</title>\n",
        "<ellipse fill=\"none\" stroke=\"black\" cx=\"171\" cy=\"-162\" rx=\"27\" ry=\"18\"/>\n",
-       "<text text-anchor=\"middle\" x=\"171\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">g</text>\n",
+       "<text text-anchor=\"middle\" x=\"171\" y=\"-156.95\" font-family=\"Times,serif\" font-size=\"14.00\">g</text>\n",
        "</g>\n",
        "<!-- f&#45;&gt;g -->\n",
        "<g id=\"edge6\" class=\"edge\">\n",
        "<title>f&#45;&gt;g</title>\n",
-       "<path fill=\"none\" stroke=\"black\" d=\"M171,-215.7C171,-207.98 171,-198.71 171,-190.11\"/>\n",
-       "<polygon fill=\"black\" stroke=\"black\" points=\"174.5,-190.1 171,-180.1 167.5,-190.1 174.5,-190.1\"/>\n",
+       "<path fill=\"none\" stroke=\"black\" d=\"M171,-215.7C171,-208.41 171,-199.73 171,-191.54\"/>\n",
+       "<polygon fill=\"black\" stroke=\"black\" points=\"174.5,-191.62 171,-181.62 167.5,-191.62 174.5,-191.62\"/>\n",
        "</g>\n",
        "</g>\n",
        "</svg>\n"
@@ -1418,6 +1377,28 @@
     "jupyter:print_transition_graph(edge/2, 1, 2,0)."
    ]
   },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "b400c8fa",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\u001b[1;31mERROR: call/1: Unknown procedure: jupyter:print_transition_graph/1\n",
+       "ERROR:   However, there are definitions for:\n",
+       "ERROR:         jupyter:print_transition_graph/4\n"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "jupyter:print_transition_graph(edge/2)."
+   ]
+  },
   {
    "cell_type": "code",
    "execution_count": 75,
@@ -2191,126 +2172,321 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 86,
+   "execution_count": 13,
    "id": "d4664fd8",
    "metadata": {
     "vscode": {
      "languageId": "prolog"
     }
    },
+   "outputs": [],
+   "source": [
+    "\n",
+    "construct(Name,Department,employe(Name,Department)).\n",
+    "\n",
+    "get_name(employe(Name,_),Name).\n",
+    "get_dept(employe(_,Dept),Dept)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 14,
+   "id": "08715fa2",
+   "metadata": {
+    "vscode": {
+     "languageId": "prolog"
+    }
+   },
    "outputs": [
     {
      "data": {
-      "text/html": [
-       "\n",
-       "            <style>\n",
-       "            details  {\n",
-       "              font-family: Menlo, Consolas, 'DejaVu Sans Mono', monospace; font-size: 13px;\n",
-       "            }\n",
-       "\n",
-       "            details > summary {\n",
-       "              cursor: pointer;\n",
-       "            }\n",
-       "            </style>\n",
-       "            <details><summary>Previously defined clauses of user:construct/3 were retracted (click to expand)</summary><pre>:- dynamic construct/3.\n",
-       "\n",
-       "construct(A, B, employe(A, B)).\n",
-       "</pre></details>"
-      ],
       "text/plain": [
-       "Previously defined clauses of user:construct/3 were retracted:\n",
-       ":- dynamic construct/3.\n",
-       "\n",
-       "construct(A, B, employe(A, B)).\n"
+       "\u001b[1mE1 = employe(peter,cs),\n",
+       "E2 = employe(mary,cs),\n",
+       "N1 = peter,\n",
+       "D2 = cs"
       ]
      },
-     "metadata": {
-      "application/json": {}
-     },
+     "metadata": {},
      "output_type": "display_data"
-    },
+    }
+   ],
+   "source": [
+    "?- construct(peter,cs,E1), construct(mary,cs,E2), get_name(E1,N1), get_dept(E2,D2)."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "43452d97",
+   "metadata": {},
+   "source": [
+    "Let us work out a small database example using such compound terms for data abstraction:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "id": "e9ff8860",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "% Facts for courses with time slot and location:\n",
+    "course(logic_programming,time(tuesday,1430,1600),location(25,'5F')).\n",
+    "course(sks,time(monday,1430,1600),location(25,'5G')).\n",
+    "course(drones,time(thursday,1430,1600),location(25,'12.O2.55')).\n",
+    "course(navigating_tomorrow,time(thursday,1430,1600),location(25,'12.O2.21')).\n",
+    "% separate facts about which programme the courses belong to (can be multiple):\n",
+    "programme(logic_programming,bachelor_cs).\n",
+    "programme(logic_programming,master_dsai).\n",
+    "programme(sks,master_cs).\n",
+    "programme(navigating_tomorrow,bachelor_cs).\n"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "3dc100cb",
+   "metadata": {},
+   "source": [
+    "Let us try and write a predicate for:\n",
+    "- which courses take place on a particular day\n",
+    "- which courses take place in a particular building (e.g., 25)\n",
+    "- which courses are available for multiple programmes\n",
+    "- which courses are in conflict (time-wise)\n",
+    "- on which days there are courses a given programme (e.g., bachelor_cs)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "fbed4b05",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7f506936",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "c34b9d8c",
+   "metadata": {},
+   "source": [
+    "Here is a solution. You will see that the compound term encoding of times and buildings\n",
+    "has some advantages and drawbacks over a flatter representation such as course/6 with 6 arguments:\n",
+    "```\n",
+    "course(logic_programming,tuesday,1430,1600,25,'5F').\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 21,
+   "id": "74a9e660",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "day(Lect,Day) :- course(Lect,time(Day,_,_),_).\n",
+    "building(Lect,Bldg) :- course(Lect,_,location(Bldg,_)).\n",
+    "multi(Lect) :- course(Lect,_,_), programme(Lect,P1), programme(Lect,P2), P1\\=P2.\n",
+    "conflict(L1,L2) :- course(L1,T,_), course(L2,T,_), L1\\=L2.\n",
+    "lecture_day(Day,Progr) :- course(L1,time(Day,_,_),_), programme(L1,Progr)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 19,
+   "id": "3cddfd08",
+   "metadata": {},
+   "outputs": [
     {
      "data": {
       "text/plain": [
-       "% Asserting clauses for user:construct/3\n"
+       "\u001b[1mL = logic_programming"
       ]
      },
      "metadata": {},
      "output_type": "display_data"
-    },
+    }
+   ],
+   "source": [
+    "?- multi(L)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 22,
+   "id": "9271f0d7",
+   "metadata": {},
+   "outputs": [
     {
      "data": {
-      "text/html": [
-       "\n",
-       "            <style>\n",
-       "            details  {\n",
-       "              font-family: Menlo, Consolas, 'DejaVu Sans Mono', monospace; font-size: 13px;\n",
-       "            }\n",
-       "\n",
-       "            details > summary {\n",
-       "              cursor: pointer;\n",
-       "            }\n",
-       "            </style>\n",
-       "            <details><summary>Previously defined clauses of user:get_name/2 were retracted (click to expand)</summary><pre>:- dynamic get_name/2.\n",
-       "\n",
-       "get_name(employe(A, _), A).\n",
-       "</pre></details>"
-      ],
       "text/plain": [
-       "Previously defined clauses of user:get_name/2 were retracted:\n",
-       ":- dynamic get_name/2.\n",
-       "\n",
-       "get_name(employe(A, _), A).\n"
+       "\u001b[1mX = drones,\n",
+       "Y = navigating_tomorrow"
       ]
      },
-     "metadata": {
-      "application/json": {}
-     },
+     "metadata": {},
      "output_type": "display_data"
-    },
+    }
+   ],
+   "source": [
+    "?- conflict(X,Y)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 24,
+   "id": "d7b8619e",
+   "metadata": {},
+   "outputs": [
     {
      "data": {
       "text/plain": [
-       "% Asserting clauses for user:get_name/2\n"
+       "\u001b[1mL = [tuesday,thursday]"
       ]
      },
      "metadata": {},
      "output_type": "display_data"
-    },
+    }
+   ],
+   "source": [
+    "?- findall(D,lecture_day(D,bachelor_cs),L)."
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "id": "e2ed5de7",
+   "metadata": {},
+   "source": [
+    "## Peano Arithmetic\n",
+    "\n",
+    "The arguments to a functor can in term also make use of a functor.\n",
+    "\n",
+    "We can also use functors of arity 1. (Functors of arity 0 are simply constants, i.e., atoms in Prolog terminology.)\n",
+    "This can be used to represent natural numbers:\n",
+    "- we can represent zero using the atom `zero/0`\n",
+    "- we can represent the successor of a number using a functor `s/1` \n",
+    "\n",
+    "Thus the number 1 is represented by the term `s(zero)` and the number 2 by `s(s(zero))`.\n",
+    "\n",
+    "How could one write predicates to check if a term is a valid natural number in that representation?\n",
+    "E.g., `s(zero)` is valid, `s(a)` is not.\n",
+    "How could one write addition and multiplication predicate to add or multiply two numbers?\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "7d1a7bf2",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "1735fe4c",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "id": "dbc89f40",
+   "metadata": {},
+   "source": [
+    "A possible solution is this one.\n",
+    "This is also called Peano arithmetic. Note, that contrary to built-in arithmetic (using is/2), these predicates are reversible"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 38,
+   "id": "d44c70af",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "\n",
+    "\n",
+    "\n",
+    "\n",
+    "nat(zero).\n",
+    "nat(s(X)) :- nat(X).\n",
+    "\n",
+    "plus(zero,X,X).\n",
+    "plus(s(X),Y,s(Z)) :- plus(X,Y,Z).\n",
+    "\n",
+    "mult(zero,_,zero).\n",
+    "mult(s(X),Y,Z) :- mult(X,Y,XY), plus(Y,XY,Z).  % (x+1)*y = x*y + y\n",
+    "\n",
+    "exp(zero,s(_),zero).\n",
+    "exp(s(_),zero,s(zero)).\n",
+    "exp(Y,s(X),Z) :- exp(Y,X,YX), mult(YX,Y,Z)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 39,
+   "id": "6e96b7aa",
+   "metadata": {},
+   "outputs": [
     {
      "data": {
-      "text/html": [
-       "\n",
-       "            <style>\n",
-       "            details  {\n",
-       "              font-family: Menlo, Consolas, 'DejaVu Sans Mono', monospace; font-size: 13px;\n",
-       "            }\n",
-       "\n",
-       "            details > summary {\n",
-       "              cursor: pointer;\n",
-       "            }\n",
-       "            </style>\n",
-       "            <details><summary>Previously defined clauses of user:get_dept/2 were retracted (click to expand)</summary><pre>:- dynamic get_dept/2.\n",
-       "\n",
-       "get_dept(employe(_, A), A).\n",
-       "</pre></details>"
-      ],
       "text/plain": [
-       "Previously defined clauses of user:get_dept/2 were retracted:\n",
-       ":- dynamic get_dept/2.\n",
-       "\n",
-       "get_dept(employe(_, A), A).\n"
+       "\u001b[1mR = s(s(s(zero)))"
       ]
      },
-     "metadata": {
-      "application/json": {}
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "?-plus(s(s(zero)),s(zero),R)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 40,
+   "id": "d119214f",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\u001b[1mR = s(s(s(s(s(s(zero))))))"
+      ]
      },
+     "metadata": {},
      "output_type": "display_data"
-    },
+    }
+   ],
+   "source": [
+    "?-mult(s(s(zero)),s(s(s(zero))),R)."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 41,
+   "id": "b3c9b644",
+   "metadata": {},
+   "outputs": [
     {
      "data": {
       "text/plain": [
-       "% Asserting clauses for user:get_dept/2\n"
+       "\u001b[1mR = s(s(s(s(s(s(s(s(zero))))))))"
       ]
      },
      "metadata": {},
@@ -2318,30 +2494,39 @@
     }
    ],
    "source": [
-    "\n",
-    "construct(Name,Department,employe(Name,Department)).\n",
-    "\n",
-    "get_name(employe(Name,_),Name).\n",
-    "get_dept(employe(_,Dept),Dept)."
+    "?-exp(s(s(zero)),s(s(s(zero))),R)."
    ]
   },
   {
    "cell_type": "code",
-   "execution_count": 87,
-   "id": "08715fa2",
-   "metadata": {
-    "vscode": {
-     "languageId": "prolog"
+   "execution_count": 42,
+   "id": "e61cc47b",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "\u001b[1mX = s(zero)"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
     }
-   },
+   ],
+   "source": [
+    "?-plus(X,s(zero),s(s(zero)))."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 43,
+   "id": "747d23d1",
+   "metadata": {},
    "outputs": [
     {
      "data": {
       "text/plain": [
-       "\u001b[1mE1 = employe(a,cs),\n",
-       "E2 = employe(b,cs),\n",
-       "N1 = a,\n",
-       "D2 = cs"
+       "\u001b[1mX = s(s(zero))"
       ]
      },
      "metadata": {},
@@ -2349,21 +2534,24 @@
     }
    ],
    "source": [
-    "?- construct(a,cs,E1), construct(b,cs,E2), get_name(E1,N1), get_dept(E2,D2)."
+    "?-mult(X,s(zero),s(s(zero)))."
    ]
   },
   {
    "cell_type": "markdown",
-   "id": "e2ed5de7",
+   "id": "15942ef6",
    "metadata": {},
    "source": [
-    "The arguments to a functor can in term also make use of a functor.\n",
+    "## Recursive Data Structures\n",
+    "\n",
+    "Compound terms can be used the represent complex data structures, as will see below.\n",
+    "First, think on how one could represent a list of objects, say a list of length 2 containing `a` and `b`.\n",
     "\n",
-    "One could thus for example represent a list in Prolog by using\n",
+    "One could for example represent a list in Prolog by using\n",
     "a functor `cons/2` to denote a non-empty list and `nil/0` to denote\n",
     "an empty list.\n",
-    "Note that a functor of arity 0 is simply a constant (aka atom in Prolog).\n",
-    "So a list of length two with a and b as elements is represented as follows:"
+    "(Remember, a functor of arity 0 is simply a constant (aka atom in Prolog).)\n",
+    "So a list of length two with a and b as elements can be represented as follows:"
    ]
   },
   {
@@ -2826,6 +3014,30 @@
     "?- last0(X,cons(a,cons(b,nil)))."
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "34c38129",
+   "metadata": {},
+   "source": [
+    "Exercise: write predicates prefix/2 and suffix/2 which is true if the first argument is a prefix or suffix of the second one."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "9a65d023",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "id": "df88c4bd",
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
   {
    "cell_type": "markdown",
    "id": "5f251e4d",
@@ -2839,7 +3051,10 @@
     "- the left sub-tree\n",
     "- the information at the root of the tree\n",
     "- the right sub-tree\n",
-    "We also need the empty tree, which we represent by `nil`."
+    "We also need the empty tree, which we represent by `nil`.\n",
+    "\n",
+    "For example, how would you represent this tree:\n",
+    "![Simple Tree](./img/simple_tree.png)"
    ]
   },
   {
@@ -2866,6 +3081,14 @@
     "?- Mytree = tree(  tree(nil,a,nil), b, tree(nil,c,tree(nil,d,nil)))."
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "8ac0d99f",
+   "metadata": {},
+   "source": [
+    "Let us now try to write a predicate which reverses (mirrors) the tree, swapping left and right children:"
+   ]
+  },
   {
    "cell_type": "code",
    "execution_count": 104,
diff --git a/logic_programming/img/simple_tree.png b/logic_programming/img/simple_tree.png
new file mode 100644
index 0000000000000000000000000000000000000000..6ae0a1bc2aabb33e824d3b1f27e3cd129f6dda65
Binary files /dev/null and b/logic_programming/img/simple_tree.png differ