logic.ipynb 83,3 ko
Newer Older
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What is the funny `|'==>'|` syntax? The trick is that \"`|`\" is just the regular Python or-operator, and so is exactly equivalent to this: "
Peter Norvig's avatar
Peter Norvig a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
Peter Norvig's avatar
Peter Norvig a validé
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(P ==> ~Q)"
     "execution_count": 48,
Peter Norvig's avatar
Peter Norvig a validé
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(P | '==>') | ~Q"
Peter Norvig's avatar
Peter Norvig a validé
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In other words, there are two applications of or-operators. Here's the first one:"
Peter Norvig's avatar
Peter Norvig a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {},
Peter Norvig's avatar
Peter Norvig a validé
   "outputs": [
    {
     "data": {
      "text/plain": [
       "PartialExpr('==>', P)"
     "execution_count": 49,
Peter Norvig's avatar
Peter Norvig a validé
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "P | '==>'"
Peter Norvig's avatar
Peter Norvig a validé
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "What is going on here is that the `__or__` method of `Expr` serves a dual purpose. If the right-hand-side is another `Expr` (or a number), then the result is an `Expr`, as in `(P | Q)`. But if the right-hand-side is a string, then the string is taken to be an operator, and we create a node in the abstract syntax tree corresponding to a partially-filled  `Expr`, one where we know the left-hand-side is `P` and the operator is `==>`, but we don't yet know the right-hand-side.\n",
Peter Norvig's avatar
Peter Norvig a validé
    "\n",
    "The `PartialExpr` class has an `__or__` method that says to create an `Expr` node with the right-hand-side filled in. Here we can see the combination of the `PartialExpr` with `Q` to create a complete `Expr`:"
Peter Norvig's avatar
Peter Norvig a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
Peter Norvig's avatar
Peter Norvig a validé
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(P ==> ~Q)"
     "execution_count": 50,
Peter Norvig's avatar
Peter Norvig a validé
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "partial = PartialExpr('==>', P) \n",
    "partial | ~Q"
Peter Norvig's avatar
Peter Norvig a validé
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This  [trick](http://code.activestate.com/recipes/384122-infix-operators/) is due to [Ferdinand Jamitzky](http://code.activestate.com/recipes/users/98863/), with a modification by [C. G. Vedant](https://github.com/Chipe1),\n",
    "who suggested using a string inside the or-bars.\n",
    "\n",
    "## Appendix: The Implementation of `expr`\n",
    "\n",
    "How does `expr` parse a string into an `Expr`? It turns out there are two tricks (besides the Jamitzky/Vedant trick):\n",
    "\n",
    "1. We do a string substitution, replacing \"`==>`\" with \"`|'==>'|`\" (and likewise for other operators).\n",
    "2. We `eval` the resulting string in an environment in which every identifier\n",
    "is bound to a symbol with that identifier as the `op`.\n",
    "\n",
    "In other words,"
   "execution_count": 51,
   "metadata": {},
Peter Norvig's avatar
Peter Norvig a validé
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(~(P & Q) ==> (~P | ~Q))"
     "execution_count": 51,
Peter Norvig's avatar
Peter Norvig a validé
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "expr('~(P & Q)  ==>  (~P | ~Q)')"
Peter Norvig's avatar
Peter Norvig a validé
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "is equivalent to doing:"
Peter Norvig's avatar
Peter Norvig a validé
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
Peter Norvig's avatar
Peter Norvig a validé
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(~(P & Q) ==> (~P | ~Q))"
     "execution_count": 52,
Peter Norvig's avatar
Peter Norvig a validé
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "P, Q = symbols('P, Q')\n",
    "~(P & Q)  |'==>'|  (~P | ~Q)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "One thing to beware of: this puts `==>` at the same precedence level as `\"|\"`, which is not quite right. For example, we get this:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(((P & Q) ==> P) | Q)"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "P & Q  |'==>'|  P | Q"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "which is probably not what we meant; when in doubt, put in extra parens:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "((P & Q) ==> (P | Q))"
      ]
     },
     "execution_count": 54,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "(P & Q)  |'==>'|  (P | Q)"
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Examples"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from notebook import Canvas_fol_bc_ask\n",
    "canvas_bc_ask = Canvas_fol_bc_ask('canvas_bc_ask', crime_kb, expr('Criminal(x)'))"
   ]
  },
Peter Norvig's avatar
Peter Norvig a validé
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
Peter Norvig's avatar
Peter Norvig a validé
   "source": [
    "# Authors\n",
    "\n",
    "This notebook by [Chirag Vartak](https://github.com/chiragvartak) and [Peter Norvig](https://github.com/norvig).\n",
   "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