diff --git a/notebooks/presentations/BvsLP.ipynb b/notebooks/presentations/BvsLP.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..80ab79828c44b9427b01d19d87647155aec21d1c
--- /dev/null
+++ b/notebooks/presentations/BvsLP.ipynb
@@ -0,0 +1,385 @@
+{
+ "cells": [
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# B compared to Logic Programming"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Append in B\n",
+    "\n",
+    "The logic program\n",
+    "```\n",
+    "append([],L,L) <-\n",
+    "append([H|X],Y,[H|Z]) <- append(X,Y,Z)\n",
+    "```\n",
+    "can be encoded in various ways in B.\n",
+    "\n",
+    "### Built-in Sequence Operator\n",
+    "\n",
+    "B has built-in sequences, which are special cases of functions, which are special cases of relations, which are sets of pairs.\n",
+    "\n",
+    "The sequence [4,5,6] is represented by the relation {(1,4),(2,5),(3,6)}:\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 2,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "$\\mathit{TRUE}$"
+      ],
+      "text/plain": [
+       "TRUE"
+      ]
+     },
+     "execution_count": 2,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[4,5,6] = {(1,4),(2,5),(3,6)}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "The built-in concatenation operator can be used to append sequences:"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 1,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "$[1,2,3,4,5,6]$"
+      ],
+      "text/plain": [
+       "[1,2,3,4,5,6]"
+      ]
+     },
+     "execution_count": 1,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[1,2,3] ^ [4,5,6]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 4,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "$\\mathit{TRUE}$\n",
+       "\n",
+       "**Solution:**\n",
+       "* $\\mathit{x} = [4,5,6]$"
+      ],
+      "text/plain": [
+       "TRUE\n",
+       "\n",
+       "Solution:\n",
+       "\tx = [4,5,6]"
+      ]
+     },
+     "execution_count": 4,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "[1,2,3] ^ x = [1,2,3,4,5,6]"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 6,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "|x|y|\n",
+       "|---|---|\n",
+       "|$\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\emptyset$|$[1,2,3]$|\n",
+       "|$\\{(1\\mapsto 1)\\}$|$\\{(1\\mapsto 2),(2\\mapsto 3)\\}$|\n",
+       "|$\\{(1\\mapsto 1),(2\\mapsto 2)\\}$|$\\{(1\\mapsto 3)\\}$|\n",
+       "|$[1,2,3]$|$\\emptyset$|\n"
+      ],
+      "text/plain": [
+       "x\ty\n",
+       "{}\t[1,2,3]\n",
+       "{(1|->1)}\t{(1|->2),(2|->3)}\n",
+       "{(1|->1),(2|->2)}\t{(1|->3)}\n",
+       "[1,2,3]\t{}\n"
+      ]
+     },
+     "execution_count": 6,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    ":table {x,y | x^y = [1,2,3]}"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "One can also write the append as a B function. Note that B is strongly typed (and user defined functions cannot yet be polymorphic), hence we have to provide the type for the arguments to the function."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 12,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "$\\newcommand{\\qdot}{\\mathord{\\mkern1mu\\cdot\\mkern1mu}}\\newcommand{\\bunion}{\\mathbin{\\mkern1mu\\cup\\mkern1mu}}\\mathit{TRUE}$\n",
+       "\n",
+       "**Solution:**\n",
+       "* $\\mathit{app} = \\lambda(\\mathit{x},\\mathit{y})\\qdot(\\mathit{x} \\in \\mathit{seq}(\\mathit{INTEGER}) \\land \\mathit{y} \\in \\mathit{seq}(\\mathit{INTEGER})\\mid \\mathit{x} \\bunion \\{\\mathit{i},\\mathit{e}\\mid \\mathit{i} - \\mathit{size}(\\mathit{x}) \\mapsto \\mathit{e} \\in \\mathit{y}\\})$\n",
+       "* $\\mathit{res} = [1,2,3,4]$"
+      ],
+      "text/plain": [
+       "TRUE\n",
+       "\n",
+       "Solution:\n",
+       "\tapp = λ(x,y)·(x ∈ seq(INTEGER) ∧ y ∈ seq(INTEGER)∣x ∪ {i,e∣i − size(x) ↦ e ∈ y})\n",
+       "\tres = [1,2,3,4]"
+      ]
+     },
+     "execution_count": 12,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "app = %(x,y).(x:seq(INTEGER) & y:seq(INTEGER) | x \\/ {i,e | (i-size(x),e) : y}) & app([1,2],[3,4]) = res"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "## Recursion using transitive closure\n",
+    "\n",
+    "Given an operator TP from sets to sets, one can compute the transitive closure\n",
+    "using ```closure(TP)```. Together with the relational image operator ```.[.]``` one can\n",
+    "compute the least fixed point containing a starting set S \n",
+    "(given the well known conditions) using ```closure(TP)[S]```.\n",
+    "\n",
+    "To simplify the presentation, we encode a variation of append, working on sets:\n",
+    "```\n",
+    "set_app({},L,L) <-\n",
+    "set_app({H}\\/X],Y,{H}\\/Z) <- set_app(X,Y,Z)\n",
+    "```"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 32,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "$\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\qdot}{\\mathord{\\mkern1mu\\cdot\\mkern1mu}}\\newcommand{\\bunion}{\\mathbin{\\mkern1mu\\cup\\mkern1mu}}\\newcommand{\\bunion}{\\mathbin{\\mkern1mu\\cup\\mkern1mu}}\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\mathit{TRUE}$\n",
+       "\n",
+       "**Solution:**\n",
+       "* $\\mathit{LHM} = \\{((\\emptyset\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE}\\}),((\\emptyset\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{TRUE}\\}),((\\{\\mathit{FALSE}\\}\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE}\\}),((\\{\\mathit{FALSE}\\}\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{FALSE},\\mathit{TRUE}\\}),((\\{\\mathit{FALSE},\\mathit{TRUE}\\}\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE},\\mathit{TRUE}\\}),((\\{\\mathit{FALSE},\\mathit{TRUE}\\}\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{FALSE},\\mathit{TRUE}\\}),((\\{\\mathit{TRUE}\\}\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE},\\mathit{TRUE}\\}),((\\{\\mathit{TRUE}\\}\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{TRUE}\\})\\}$\n",
+       "* $\\mathit{HB} = ((\\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\}) * \\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\})) * \\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\}))$\n",
+       "* $\\mathit{tp} = \\{\\mathit{S},\\mathit{TPS}\\mid \\mathit{S} \\in ((\\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\}) * \\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\})) * \\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\})) \\land \\exists(\\mathit{x},\\mathit{y},\\mathit{z},\\mathit{h})\\qdot(\\mathit{x} \\mapsto \\mathit{y} \\mapsto \\mathit{z} = \\mathit{S} \\land \\mathit{h} \\in \\{\\mathit{FALSE},\\mathit{TRUE}\\} \\land \\mathit{TPS} = (\\mathit{x} \\bunion \\{\\mathit{h}\\}) \\mapsto \\mathit{y} \\mapsto (\\mathit{z} \\bunion \\{\\mathit{h}\\}))\\}$\n",
+       "* $\\mathit{TYPE} = \\{\\mathit{FALSE},\\mathit{TRUE}\\}$\n",
+       "* $\\mathit{Facts} = \\{((\\emptyset\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE}\\}),((\\emptyset\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{TRUE}\\})\\}$"
+      ],
+      "text/plain": [
+       "TRUE\n",
+       "\n",
+       "Solution:\n",
+       "\tLHM = {((∅↦{FALSE})↦{FALSE}),((∅↦{TRUE})↦{TRUE}),(({FALSE}↦{FALSE})↦{FALSE}),(({FALSE}↦{TRUE})↦{FALSE,TRUE}),(({FALSE,TRUE}↦{FALSE})↦{FALSE,TRUE}),(({FALSE,TRUE}↦{TRUE})↦{FALSE,TRUE}),(({TRUE}↦{FALSE})↦{FALSE,TRUE}),(({TRUE}↦{TRUE})↦{TRUE})}\n",
+       "\tHB = ((ℙ({FALSE,TRUE}) ∗ ℙ({FALSE,TRUE})) ∗ ℙ({FALSE,TRUE}))\n",
+       "\ttp = {S,TPS∣S ∈ ((ℙ({FALSE,TRUE}) ∗ ℙ({FALSE,TRUE})) ∗ ℙ({FALSE,TRUE})) ∧ ∃(x,y,z,h)·(x ↦ y ↦ z = S ∧ h ∈ {FALSE,TRUE} ∧ TPS = (x ∪ {h}) ↦ y ↦ (z ∪ {h}))}\n",
+       "\tTYPE = {FALSE,TRUE}\n",
+       "\tFacts = {((∅↦{FALSE})↦{FALSE}),((∅↦{TRUE})↦{TRUE})}"
+      ]
+     },
+     "execution_count": 32,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "TYPE = BOOL & HB = POW(TYPE)*POW(TYPE)*POW(TYPE)\n",
+    "&\n",
+    "Facts = UNION(L).(L:TYPE|{({L}-{L},{L},{L})})   // The set of all Facts\n",
+    "&\n",
+    "tp = /*@symbolic*/ {S,TPS|S:HB & #(x,y,z,h).( (x,y,z) = S & h:TYPE & TPS= (x\\/{h},y,z\\/{h}))} // The TP Operator\n",
+    "&\n",
+    "LHM = closure(tp)[Facts] // the least Herbrand model"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Axiomatic Encoding using logical implication\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 34,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "$\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\mathit{TRUE}$\n",
+       "\n",
+       "**Solution:**\n",
+       "* $\\mathit{Model} = \\{((\\emptyset\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{TRUE}\\}),((\\emptyset\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE}\\}),((\\{\\mathit{FALSE}\\}\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{FALSE},\\mathit{TRUE}\\}),((\\{\\mathit{TRUE}\\}\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{TRUE}\\}),((\\{\\mathit{FALSE}\\}\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE}\\}),((\\{\\mathit{TRUE}\\}\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE},\\mathit{TRUE}\\}),((\\{\\mathit{FALSE},\\mathit{TRUE}\\}\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{FALSE},\\mathit{TRUE}\\}),((\\{\\mathit{FALSE},\\mathit{TRUE}\\}\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE},\\mathit{TRUE}\\})\\}$\n",
+       "* $\\mathit{HB} = ((\\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\}) * \\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\})) * \\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\}))$\n",
+       "* $\\mathit{TYPE} = \\{\\mathit{FALSE},\\mathit{TRUE}\\}$\n",
+       "* $\\mathit{Facts} = \\{((\\emptyset\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE}\\}),((\\emptyset\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{TRUE}\\})\\}$"
+      ],
+      "text/plain": [
+       "TRUE\n",
+       "\n",
+       "Solution:\n",
+       "\tModel = {((∅↦{TRUE})↦{TRUE}),((∅↦{FALSE})↦{FALSE}),(({FALSE}↦{TRUE})↦{FALSE,TRUE}),(({TRUE}↦{TRUE})↦{TRUE}),(({FALSE}↦{FALSE})↦{FALSE}),(({TRUE}↦{FALSE})↦{FALSE,TRUE}),(({FALSE,TRUE}↦{TRUE})↦{FALSE,TRUE}),(({FALSE,TRUE}↦{FALSE})↦{FALSE,TRUE})}\n",
+       "\tHB = ((ℙ({FALSE,TRUE}) ∗ ℙ({FALSE,TRUE})) ∗ ℙ({FALSE,TRUE}))\n",
+       "\tTYPE = {FALSE,TRUE}\n",
+       "\tFacts = {((∅↦{FALSE})↦{FALSE}),((∅↦{TRUE})↦{TRUE})}"
+      ]
+     },
+     "execution_count": 34,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "TYPE = BOOL & HB = POW(TYPE)*POW(TYPE)*POW(TYPE)\n",
+    "&\n",
+    "Facts = UNION(L).(L:TYPE|{({L}-{L},{L},{L})})   // The set of all Facts\n",
+    "&\n",
+    "Facts <: Model\n",
+    "&\n",
+    "!(x,y,z).( (x,y,z):Model => !h.(h:TYPE => (x\\/{h},y,z\\/{h}):Model))"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 36,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "$\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\newcommand{\\pow}{\\mathop{\\mathbb P\\hbox{}}\\nolimits}\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\renewcommand{\\emptyset}{\\mathord\\varnothing}\\mathit{TRUE}$\n",
+       "\n",
+       "**Solution:**\n",
+       "* $\\mathit{Model} = ((\\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\}) * \\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\})) * \\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\}))$\n",
+       "* $\\mathit{HB} = ((\\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\}) * \\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\})) * \\pow(\\{\\mathit{FALSE},\\mathit{TRUE}\\}))$\n",
+       "* $\\mathit{TYPE} = \\{\\mathit{FALSE},\\mathit{TRUE}\\}$\n",
+       "* $\\mathit{Facts} = \\{((\\emptyset\\mapsto\\{\\mathit{FALSE}\\})\\mapsto\\{\\mathit{FALSE}\\}),((\\emptyset\\mapsto\\{\\mathit{TRUE}\\})\\mapsto\\{\\mathit{TRUE}\\})\\}$"
+      ],
+      "text/plain": [
+       "TRUE\n",
+       "\n",
+       "Solution:\n",
+       "\tModel = ((ℙ({FALSE,TRUE}) ∗ ℙ({FALSE,TRUE})) ∗ ℙ({FALSE,TRUE}))\n",
+       "\tHB = ((ℙ({FALSE,TRUE}) ∗ ℙ({FALSE,TRUE})) ∗ ℙ({FALSE,TRUE}))\n",
+       "\tTYPE = {FALSE,TRUE}\n",
+       "\tFacts = {((∅↦{FALSE})↦{FALSE}),((∅↦{TRUE})↦{TRUE})}"
+      ]
+     },
+     "execution_count": 36,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "TYPE = BOOL & HB = POW(TYPE)*POW(TYPE)*POW(TYPE)\n",
+    "&\n",
+    "Facts = UNION(L).(L:TYPE|{({L}-{L},{L},{L})})   // The set of all Facts\n",
+    "&\n",
+    "Facts <: Model\n",
+    "&\n",
+    "!(x,y,z).( (x,y,z):Model => !h.(h:TYPE => (x\\/{h},y,z\\/{h}):Model))\n",
+    "&\n",
+    "Model = HB"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 35,
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/markdown": [
+       "$\\mathit{time\\_out}$"
+      ],
+      "text/plain": [
+       "time_out"
+      ]
+     },
+     "execution_count": 35,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "TYPE = BOOL & HB = POW(TYPE)*POW(TYPE)*POW(TYPE)\n",
+    "&\n",
+    "Facts = UNION(L).(L:TYPE|{({L}-{L},{L},{L})})   // The set of all Facts\n",
+    "&\n",
+    "AllModels = {Model | Facts <: Model &\n",
+    "                     !(x,y,z).( (x,y,z):Model => !h.(h:TYPE => (x\\/{h},y,z\\/{h}):Model))}"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "ProB 2",
+   "language": "prob",
+   "name": "prob2"
+  },
+  "language_info": {
+   "codemirror_mode": "prob2_jupyter_repl",
+   "file_extension": ".prob",
+   "mimetype": "text/x-prob2-jupyter-repl",
+   "name": "prob"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}