{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Simple prologterms example\n", "\n", "Walkthrough of basic commands" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from prologterms import TermGenerator, PrologRenderer, Var\n", "\n", "# term generators allow for convient construction of\n", "# compound terms\n", "P = TermGenerator()\n", "\n", "# prolog variables; must start with uppercase\n", "X = Var('X')\n", "\n", "# create a compound term object, representing\n", "# a non-ground prolog goal\n", "term = P.member(X, [1, 2, 3])" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "member(X, [1, 2, 3])\n" ] } ], "source": [ "from prologterms import PrologRenderer\n", "r = PrologRenderer()\n", "print(r.render(term))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### escaping characters\n", "\n", "this module will take care of escaping characters to conform to\n", "prolog syntax\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "member(X, [1, b, 'foo\\nbar', '\\'hi\\''])\n" ] } ], "source": [ "term = P.member(X, [1, 'b', \"foo\\nbar\", \"'hi'\"])\n", "print(r.render(term))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Rules\n", "\n", "The \"<=\" operator in python is overloaded to mean the same as prolog\n", "\":-\". This means a rule object can be created as follows:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ancestor(X, Y) :-\n", " parent(X, Z), ancestor(Z, Y)\n" ] } ], "source": [ "X = Var('X')\n", "Y = Var('Y')\n", "Z = Var('Z')\n", "\n", "rule = P.ancestor(X,Y) <= (P.parent(X,Z), P.ancestor(Z,Y))\n", "print(r.render(rule))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Adding comments\n", "\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "% the ancestor relation propagates over parent/2\n", "ancestor(X, Y) :-\n", " parent(X, Z), ancestor(Z, Y)\n" ] } ], "source": [ "rule = (P.ancestor(X,Y) <= (P.parent(X,Z), P.ancestor(Z,Y))) % 'the ancestor relation propagates over parent/2'\n", "print(r.render(rule))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Programs\n" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "ancestor(X, Y) :-\n", " parent(X, Z), ancestor(Z, Y).\n", "ancestor(X, Y) :-\n", " parent(X, Y).\n", "parent(a, b).\n", "parent(b, c).\n", "parent(c, d).\n", "\n" ] } ], "source": [ "from prologterms import TermGenerator, PrologRenderer, Program, Var\n", "\n", "P = TermGenerator()\n", "X = Var('X')\n", "Y = Var('Y')\n", "Z = Var('Z')\n", "R = PrologRenderer()\n", "\n", "prog = Program(\n", " P.ancestor(X,Y) <= (P.parent(X,Z), P.ancestor(Z,Y)),\n", " P.ancestor(X,Y) <= P.parent(X,Y),\n", " P.parent('a','b'),\n", " P.parent('b','c'),\n", " P.parent('c','d')\n", ")\n", "\n", "print(R.render(prog))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interfacing with prolog systems\n", "\n", "we show two ways of doing this" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Interfacing with SWI-Prolog via commandline\n", "\n", "This requires `swipl` on command line to run" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "swipl -l anc.pl -g '(forall(ancestor(X, Y), writeln(anc(X, Y))), halt)'\n" ] } ], "source": [ "# write program\n", "f = open('anc.pl', 'w')\n", "f.write(R.render(prog))\n", "f.close()\n", "\n", "# query\n", "q = P.ancestor(X,Y)\n", "\n", "# make a wrapper goal\n", "goal = (P.forall(q, P.writeln(P.anc(X,Y))),'halt')\n", "\n", "# call\n", "cmd = \"swipl -l anc.pl -g '{}'\".format(R.render(goal))\n", "print(cmd)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "anc(a,d)\n", "anc(a,c)\n", "anc(b,d)\n", "anc(a,b)\n", "anc(b,c)\n", "anc(c,d)\n", "\n" ] } ], "source": [ "import subprocess\n", "from subprocess import run\n", "result = run(cmd, shell=True, stdout=subprocess.PIPE)\n", "print(\"{}\".format(result.stdout.decode('ascii')))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Interfacing via pengines\n", "\n", "[pengines](http://pengines.swi-prolog.org/docs/index.html) (Prolog Engines) is a means of communicating with a prolog server from any language. We will use the python pengines API here (TODO: release to PyPi).\n", "\n", "This example requires a pengines server to be running on port 4242. This is fairly easy to do using the pengines framework, and even easier if you have docker, in which case you can run a container like this:\n", "\n", "```\n", "docker run -p 4242:9083 -e PORT=9083 --name cmungall/sparqlprog\n", "```\n", "\n", "Once this is done, the following program should run." ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Builder._getActualURL log.\n", "New value is : http://localhost:4242/pengine/create\n", "a <- d\n", "a <- c\n", "b <- d\n", "a <- b\n", "b <- c\n", "c <- d\n" ] } ], "source": [ "from pengines.Builder import PengineBuilder\n", "from pengines.Pengine import Pengine\n", "\n", "factory = PengineBuilder(urlserver=\"http://localhost:4242\",\n", " srctext=R.render(prog),\n", " ask=R.render(q))\n", "pengine = Pengine(builder=factory, debug=False)\n", "while pengine.currentQuery.hasMore:\n", " pengine.doNext(pengine.currentQuery)\n", "for p in pengine.currentQuery.availProofs:\n", " print('{} <- {}'.format(p[X.name], p[Y.name]))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "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.2" } }, "nbformat": 4, "nbformat_minor": 2 }