{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "
$A \\land B \\land C$
\n", "\n", "# PLCParser implemented in [Hy](https://github.com/hylang/hy) ~language\n", "\n", "See also:\n", "\n", "- Propositional Logic Clause Parser [main project hub](https://github.com/markomanninen/PLCParser)\n", "- Jupyter notebook with Calypso Hy [kernel](http://nbviewer.jupyter.org/github/markomanninen/PLCParser/blob/master/PLCParser%20in%20Hy.ipynb)\n", "\n", "\n", "## Magics\n", "\n", "Load extension for using magics on the document:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Use for example: %plc (1 and? 1)\n", "Operators available: nope? ¬ and? ∧ xor? ⊕ or? ∨ nand? ↑ nxor? ↔ nor? ↓\n", "Operands available: True 1 ⊤ False 0 ⊥\n" ] } ], "source": [ "%load_ext hyPLCParser\n", "#%reload_ext hyPLCParser" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Line magics\n", "\n", "Prefix and infix support" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%plc (1 and? 1)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%plc (True ⊕ False ⊕ True ⊕ False ⊕ True)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%plc ( ( ∧ 1 1 1 ) ∨ ( ∧ 1 1 0 ) )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Cell magics\n", "\n", "Prefix and infix support" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%plc\n", "#$(1 and? (or? 0 1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Registering additional operators" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "6" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "%%plc\n", "; register + sign for infix notation\n", "#>+\n", "; evaluate code\n", "#$(1 + (2 + (3)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Adding more complex custom operators" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.5\n", "2.1666666666666665\n", "3.125\n" ] } ], "source": [ "%%plc\n", "\n", "; use operator macro to add mean operator with custom symbol\n", "(defoperator mean x̄ [&rest args]\n", "  (/ (sum args) (len args)))\n", "\n", "; try prefix notation with nested structure\n", "(print (x̄ 1 2 3 4))\n", "(print (x̄ 1 2 (x̄ 3 4)))\n", "\n", "; note that infix notation in cell magics needs to be prefixed with \n", "; #$ reader macro marker while in line magics it is not required\n", "(print #$(1 x̄ 2 x̄ 3 x̄ 4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Order of precedence\n", "\n", "By default order of precedence is from left to right. Here we will use defoperators to define additional operators beyond logical ones. Then for variety we use defmixfix macro to evaluate clause. First evaluation will give 9 as an answer because evaluation is started from 1 + 2 and then that is multiplied" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "First 9\n", "Second 7\n" ] } ], "source": [ "%%plc\n", "\n", "(defoperators * +)\n", "(print \"First\"\n", " (defmixfix 1 + 2 * 3))\n", "\n", "(defprecedence * +)\n", "(print \"Second\"\n", " (defmixfix 1 + 2 * 3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Mixing Hy and Python on same cell" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" }, { "data": { "text/plain": [ "[1, 2, 3]" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# the first line is hy code supporting infix and prefix logical clauses\n", "%plc ( 1 and? 1 or? (0) )\n", "\n", "# the second line is python code. this is possible because above code is line magics\n", "[a for a in (1, 2, 3)]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Normal Hy language support" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3.1416\n" ] } ], "source": [ "%%plc\n", "\n", "; just define a function ...\n", "(defn f [x] (print x))\n", "\n", "; ... and call it\n", "(f 3.1416)\n", "\n", "; cant use python code in plc cell magics!" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "( A ∧ B ∧ C ) = True\n" ] } ], "source": [ "%%plc\n", "\n", "; set up variables\n", "(setv A True B True C True)\n", "(setv clause \"( A ∧ B ∧ C )\")\n", "\n", "; use variables on clause\n", "(print clause \"=\" #$( A ∧ B ∧ C ))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The [MIT](https://choosealicense.com/licenses/mit/) License\n", "\n", "Copyright © 2017 Marko Manninen" ] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python [default]", "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.5.2" } }, "nbformat": 4, "nbformat_minor": 1 }