{ "info": { "author": "Guenter Bartsch", "author_email": "guenter@zamia.org", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)", "Operating System :: POSIX :: Linux", "Programming Language :: Prolog", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Topic :: Software Development :: Compilers", "Topic :: Software Development :: Interpreters" ], "description": "# Zamia Prolog\n\nScalable and embeddable compiler/interpreter for a Zamia-Prolog (a Prolog dialect). Stores its knowledge base in a\nDatabase via SQLAlchemy - hence the scalability, i.e. the knowledge base is not limited by the amount of RAM available.\n\nZamia-Prolog is written in pure python so it can be easily embedded into other python applications. Compiler and runtime\nhave interfaces to register custom builtins which can either be evaluated at compile time (called directives in\nZamia-Prolog) or at runtime.\n\nThe Prolog core is based on http://openbookproject.net/py4fun/prolog/prolog3.html by Chris Meyers.\n\nWhile performance is definitely important, right now Chris' interpreted approach is more than good enough for my needs. \n\nMy main focus here is embedding and language features - at the time of this writing I am experimenting with\nincorporating some imperative concepts into Zamia-Prolog, such as re-assignable variables and if/then/else constructs. \nSo please note that this is a Prolog dialect that probably never will be compliant to any Prolog standards. Instead it will\nmost likely drift further away from standard prolog and may evolve into my own logic-based language.\n\nFeatures\n========\n\n* pure Python implementation\n* easy to embed in Python applications\n* easy to extend with custom builtins for domain specific tasks\n* re-assignable variables with full backtracking support\n* assertz/retract with full backtracking support (using database overlays)\n* imperative language constructs such as if/then/else\n* pseudo-variables/-predicates that make DB assertz/retractz easier to code\n\nRequirements\n============\n\n*Note*: probably incomplete.\n\n* Python 2.7\n* py-nltools\n* SQLAlchemy\n\nUsage\n=====\n\nCompile `hanoi1.pl` example:\n\n```python\nfrom zamiaprolog.logicdb import LogicDB\nfrom zamiaprolog.parser import PrologParser\n\ndb_url = 'sqlite:///foo.db'\ndb = LogicDB(db_url)\nparser = PrologParser()\n\nparser.compile_file('samples/hanoi1.pl', 'unittests', db)\n```\n\nnow run a sample goal:\n\n```python\nfrom zamiaprolog.runtime import PrologRuntime\n\nclause = parser.parse_line_clause_body('move(3,left,right,center)')\nrt = PrologRuntime(db)\n\nsolutions = rt.search(clause)\n```\n\noutput:\n\n```\nMove top disk from left to right\nMove top disk from left to center\nMove top disk from right to center\nMove top disk from left to right\nMove top disk from center to left\nMove top disk from center to right\nMove top disk from left to right\n```\n\nAccessing Prolog Variables from Python\n--------------------------------------\n\nSet var X from python:\n```python\nclause = parser.parse_line_clause_body('Y is X*X')\nsolutions = rt.search(clause, {'X': NumberLiteral(3)})\n```\n\ncheck number of solutions:\n```python\nprint len(solutions)\n```\noutput:\n```\n1\n```\n\naccess prolog result Y from python:\n```python\nprint solutions[0]['Y'].f\n```\noutput:\n```\n9\n```\n\nCustom Python Builtin Predicates\n--------------------------------\n\nTo demonstrate how to register custom predicates with the interpreter, we will\nintroduce a python builtin to record the moves in our Hanoi example:\n\n```python\nrecorded_moves = []\n\ndef record_move(g, rt):\n global recorded_moves\n\n pred = g.terms[g.inx]\n args = pred.args\n\n arg_from = rt.prolog_eval(args[0], g.env)\n arg_to = rt.prolog_eval(args[1], g.env) \n\n recorded_moves.append((arg_from, arg_to))\n\n return True\n\nrt.register_builtin('record_move', record_move)\n\n\n```\n\nnow, compile and run the `hanoi2.pl` example:\n\n```python\nparser.compile_file('samples/hanoi2.pl', 'unittests', db)\nclause = parser.parse_line_clause_body('move(3,left,right,center)')\nsolutions = rt.search(clause)\n```\noutput:\n```\nMove top disk from left to right\nMove top disk from left to center\nMove top disk from right to center\nMove top disk from left to right\nMove top disk from center to left\nMove top disk from center to right\nMove top disk from left to right\n```\nnow, check the recorded moves:\n```python\nprint len(recorded_moves)\nprint repr(recorded_moves)\n```\noutput:\n```\n7\n[(Predicate(left), Predicate(right)), (Predicate(left), Predicate(center)), (Predicate(right), Predicate(center)), (Predicate(left), Predicate(right)), (Predicate(center), Predicate(left)), (Predicate(center), Predicate(right)), (Predicate(left), Predicate(right))]\n```\n\nGenerate Multiple Bindings from Custom Predicates\n-------------------------------------------------\n\nCustom predicates not only can return True/False and manipulate the environment directly to generate a single binding as\nin\n\n```python\ndef custom_pred1(g, rt):\n\n rt._trace ('CALLED BUILTIN custom_pred1', g)\n\n pred = g.terms[g.inx]\n args = pred.args\n if len(args) != 1:\n raise PrologRuntimeError('custom_pred1: 1 arg expected.')\n\n arg_var = rt.prolog_get_variable(args[0], g.env)\n \n g.env[arg_var] = NumberLiteral(42)\n\n return True\n```\n\nthey can also return a list of bindings which will then result in one prolog result each. In this example,\nwe generate 4 bindings of two variables each:\n\n```python\ndef multi_binder(g, rt):\n\n global recorded_moves\n\n rt._trace ('CALLED BUILTIN multi_binder', g)\n\n pred = g.terms[g.inx]\n args = pred.args\n if len(args) != 2:\n raise PrologRuntimeError('multi_binder: 2 args expected.')\n\n var_x = rt.prolog_get_variable(args[0], g.env)\n var_y = rt.prolog_get_variable(args[1], g.env) \n\n res = []\n for x in range(2):\n\n lx = NumberLiteral(x)\n\n for y in range(2):\n ly = NumberLiteral(y)\n\n res.append({var_x: lx, var_y: ly})\n\n return res\n```\nso running\n```python\nclause = self.parser.parse_line_clause_body('multi_binder(X,Y)')\nsolutions = self.rt.search(clause)\n```\nwill produce 4 solutions:\n```\n[{u'Y': 0, u'X': 0}, {u'Y': 1, u'X': 0}, {u'Y': 0, u'X': 1}, {u'Y': 1, u'X': 1}]\n```\n\nCustom Compiler Directives\n--------------------------\n\nBesides custom builtins we can also have custom compiler-directives in Zamia-Prolog. Directives are evalutated at compile\ntime and will not be stored in the database. \n\nHere is an example: First, register your custom directive:\n\n```python \ndef _custom_directive (module_name, clause, user_data):\n print \"_custom_directive has been called. clause: %s user_data:%s\" % (clause, user_data)\n\nparser.register_directive('custom_directive', _custom_directive, None)\n```\n\nnow, compile a piece of prolog code that uses the directive:\n\n```python\nparser.parse_line_clauses('custom_directive(abc, 42, \\'foo\\').')\n\n```\noutput:\n```\n_custom_directive has been called. clause: custom_directive(abc, 42.0, \"foo\"). user_data:None\n[]\n```\n\nRe-Assignable Variables \n-----------------------\n\nVariables can be re-assigned using the built-in special `set` (`:=`):\n\n```prolog\nZ := 23, Z := 42\n```\nthis comes with full backtracking support.\n\nPseudo-Variables/-Predicates\n----------------------------\n\nThis is an extension to standard prolog syntax found in Zamia-Prolog to make \"variable\" setting and access\neasier:\n```\nC:user -> user (C, X)\nC:user:name -> user (C, X), name (X, Y)\nself:name -> name (self, X)\nself:label|de -> label (self, de, X)\n```\nthis works for evaluation as well as setting/asserting (left-hand and right-hand side of expressions).\n\nExample:\n```prolog\nassertz(foo(bar, 23)), bar:foo := 42, Z := bar:foo\n```\nwill result in `Z == 42` and `foo(bar, 42)` asserted in the database.\n\nif/then/else/endif\n------------------\n\n```prolog\nif foo(bar) then\n do1, do2\nelse\n do2, do3\nendif\n\n```\nis equivalent to\n```prolog\nor ( and (foo(bar), do1, do2), and (not(foo(bar)), do2, do3) )\n```\n\nLicense\n=======\n\nMy own scripts as well as the data I create is LGPLv3 licensed unless otherwise noted in the script's copyright headers.\n\nSome scripts and files are based on works of others, in those cases it is my\nintention to keep the original license intact. Please make sure to check the\ncopyright headers inside for more information.\n\nAuthor\n======\n\n* Guenter Bartsch \n* Chris Meyers.\n* Heiko Sch\u00e4fer ", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/gooofy/zamia-prolog", "keywords": "", "license": "LGPLv3", "maintainer": "", "maintainer_email": "", "name": "zamia-prolog", "package_url": "https://pypi.org/project/zamia-prolog/", "platform": "Linux", "project_url": "https://pypi.org/project/zamia-prolog/", "project_urls": { "Homepage": "https://github.com/gooofy/zamia-prolog" }, "release_url": "https://pypi.org/project/zamia-prolog/0.1.0/", "requires_dist": null, "requires_python": "", "summary": "Embeddable Prolog dialect implemented in pure Python. Stores its knowlegdebase using SQLAlchemy for scalability.", "version": "0.1.0" }, "last_serial": 3325220, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "d63e4c05506605c31186f8cc41a7f813", "sha256": "61ff7cd17ae246b42d40b71a0e060bd92ad03372897d9c2e097823de6cb63cf4" }, "downloads": -1, "filename": "zamia-prolog-0.1.0.tar.gz", "has_sig": false, "md5_digest": "d63e4c05506605c31186f8cc41a7f813", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29659, "upload_time": "2017-11-11T23:51:12", "url": "https://files.pythonhosted.org/packages/4b/2a/bd9ac669cdade907b6dd1922d9c08077378d43042458b75990d41c8bca8b/zamia-prolog-0.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d63e4c05506605c31186f8cc41a7f813", "sha256": "61ff7cd17ae246b42d40b71a0e060bd92ad03372897d9c2e097823de6cb63cf4" }, "downloads": -1, "filename": "zamia-prolog-0.1.0.tar.gz", "has_sig": false, "md5_digest": "d63e4c05506605c31186f8cc41a7f813", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 29659, "upload_time": "2017-11-11T23:51:12", "url": "https://files.pythonhosted.org/packages/4b/2a/bd9ac669cdade907b6dd1922d9c08077378d43042458b75990d41c8bca8b/zamia-prolog-0.1.0.tar.gz" } ] }