{ "info": { "author": "Reid 'arrdem' McKenzie", "author_email": "me@arrdem.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Topic :: Database", "Topic :: Database :: Database Engines/Servers", "Topic :: Database :: Front-Ends" ], "description": "# Datalog\n\nAn implementation of Datalog in Python.\n\n## What is Datalog?\n\n[Datalog](https://en.wikipedia.org/wiki/Datalog) is a fully declarative language for expressing relational data and queries, typically written using a syntactic subset of Prolog.\nIts most interesting feature compared to other relational languages such as SQL is that it features production rules.\n\nBriefly, a datalog database consists of rules and tuples.\n\nTuples are written `a(b, \"c\", 126, ...).`, require no declaration eg.\nof table, may be of arbitrary even varying length.\n\nRules are written `f(A, B) :- a(A), b(B)` and when evaluated produce tuples.\nThis rule for instance would define `\u2200 a\u2091\u2208a, b\u2091\u2208b f(a, b)` eg the cross-product of the elements of the tuple sets `a(A)` and `b(B)`.\n\n## Quickstart\n\nWe're gonna make use of the [datalog.easy](#datalog.easy) API.\nIt's somewhat simplified and definitely has sharp edges, but has much better ergonomics than working directly with the query engine from Python.\n\n```\n# Pull in the datalog.easy package\n>>> from datalog import easy\n# Read some tuples into a Dataset.\n#\n# Because the base Dataset class has some limitations, easy gives you\n# an instance of the IndexedDataset which is best supported\n>>> db = read('''\n... edge(a, b).\n... edge(b, c).\n... edge(c, d).\n... edge(d, e).\n... ''')\n```\nNow that we've got a db instance, we can run some queries over it.\n\nThe two core operations are Select and Join.\nSelect selects tuples - both constants and from rules.\nJoin selects several tuples at once by unifying logic variables.\n\nLet's select some tuples first.\n\nSelect returns a sequence of pairs `(tuples, bindings)`, where tuples are the selected tuples (always one tuple in fact), and bindings is a mapping of LVars to bound constants.\n\n```\n>>> easy.select(db, ('edge', 'a', 'b'))\n[((('edge', 'a', 'b'),), {})]\n```\n\nCool!\nBut what if we wanted to find all edges from a?\nThis is where logic variables come in.\nLogic variables are written as capitalized words in textual datalog, and the easy package recognizes capitalized strings as logic variables when processing queries.\n\nThere's only one such tuple, `edge(a, b)`, but lets see if we find it.\n\n```\n>>> easy.select(db, ('edge', 'a', 'B'))\n[((('edge', 'a', 'b'),), {'B': 'b'})] \n```\n\nNice.\nBut what of joins?\nRules are really a way to give a name to the result of a join, but we can do joins directly too.\nFor instance, we could try to select all contiguous 2-segment paths.\n\nUnlike select which takes a single tuple, join takes a sequence of tuples to simultaneously satisfy.\nHowever select like join returns a sequence of pairs `(tuples, bindings)`, where tuples may actually have many elements.\n\nIn this case, we're selecting pairs of adjacent edges, so we'll get two tuples and three bindings back in each result.\n\n```\n>>> easy.join(db, [\n... ('edge', 'A', 'B'), # Any edge, ending at B\n... ('edge', 'B', 'C') # Any edge, beginning at the same B\n... ])\n[((('edge', 'a', 'b'),\n ('edge', 'b', 'c')),\n {'A': 'a', 'B': 'b', 'C': 'c'}),\n ((('edge', 'b', 'c'),\n ('edge', 'c', 'd')),\n {'A': 'b', 'B': 'c', 'C': 'd'}),\n ((('edge', 'c', 'd'),\n ('edge', 'd', 'e')),\n {'A': 'c', 'B': 'd', 'C': 'e'})]\n```\n\n## API\n\n### `datalog.types`\n\n\nThe types package provides the core representation used by the rest of the system.\nIt defines the `Constant(value)` and `LVar(name)` tuples types.\n\nA datalog tuple `a(b, c)` is internally represented as `(Constant('a'), Constant('b'), Constant('c')')`.\nTuples containing logic variables simply contain `LVar` instances in addition to `Constant` values.\n\nThe `LTuple` type alias is for tuples which contain both constants and logic variables.\n\nThe `CTuple` type alias is for tuples containing only constants.\n\nA `Rule(pattern, clauses)` is a pair of an `LTuple` being the pattern for the tuples produced by the rule, and a sequence of clauses being `LTuple` values representing join constraints on the result of the rule.\n\nThe types package also defines the `Dataset` class.\nA `Dataset` is a container for a sequence of tuples, and a sequence of rules which define tuples.\nIn fact the `Dataset` class only has three methods `rules()`, `tuples()` and `merge(other)`.\n\nThe query planners work mostly in terms of `Dataset` instances, although extensions of `Dataset` may be better supported.\n\n`CachedDataset` is an extension of the `Dataset` type which allows the query engine to cache the result(s) of evaluating rules.\nThis enables recursive rule evaluation, and some other optimizations.\n\n`IndexedDataset` is an extension of `CachedDataset` which also features support for indices which can reduce the amount of data processed.\n\n### `datalog.parser`\n\n\nThis package contains only generated code, and is used to implement the reader.\nIts contents are unstable.\n\n### `datalog.reader`\n\n\nThe reader only intentionally exposes three methods - `read` aka `read_dataset` which accepts a string and an optional kwarg `db_cls` being a class extending `Dataset` into which tuples and rules should be read.\n\nIt also exposes `read_command` which returns a pair `(op: str, val: Either[Rule, LTuple])`.\nThis function is used to implement parts of the REPL, packaged separately ([PyPi](https://pypi.org/package/arrdem/datalog.shell), [git](https://git.arrdem.com/arrdem/datalog-shell)).\n\n### `datalog.evaluator`\n\n\nAt present, the evaluator only contains two methods - `select` and `join`.\nSelect and join are mutually recursive, because rule evaluation is recursively selecting the results of joins.\n\nAt present, there is only one implementation of select and join in the system.\nIn the future, this interface will be replaced to add support for query planners.\n\nUsers should prefer the generally stable `datalog.easy` interface to working directly with the evaluator.\n\n### `datalog.easy`\n\n\nA shim over the reader and evaluator designed to make interacting with the evaluator from python more convenient.\nNot simpler, just more convenient.\n\n`read(str, db_cls=IndexedDataset)` is just a shim to `datalog.reader.read` with a better default class.\n\n`select(db: Dataset, query: LTuple)` eagerly evaluates all results instead of producing a generator, eliminating `Constant()` and `LVar()` wrappers in both tuples and bindings.\n\n`join(db: Dataset, query: Sequence[LTuple])` likewise eagerly evaluates all results, and likewise simplifies results.\n\n## Usage\n\n```\n$ pip install --user arrdem.datalog\n```\n\n### Limitations\n\nRecursion may have some completeness bugs. I have not yet encountered any, but I\nalso don't have a strong proof of correctness for the recursive evaluation of\nrules yet.\n\nThe current implementation of negated clauses CANNOT propagate positive\ninformation. This means that negated clauses can only be used in conjunction\nwith positive clauses. It's not clear if this is an essential limitation.\n\nThere is as of yet no query planner - not even segmenting rules and tuples by\nrelation to restrict evaluation. This means that the complexity of a query is\n`O(dataset * term count)`, which is clearly less than ideal.\n\n## License\n\nMirrored from https://git.arrdem.com/arrdem/datalog-py\n\nPublished under the MIT license. See [LICENSE.md](LICENSE.md)", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://git.arrdem.com/arrdem/datalog-py", "keywords": "", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "arrdem.datalog", "package_url": "https://pypi.org/project/arrdem.datalog/", "platform": "", "project_url": "https://pypi.org/project/arrdem.datalog/", "project_urls": { "Homepage": "https://git.arrdem.com/arrdem/datalog-py" }, "release_url": "https://pypi.org/project/arrdem.datalog/2.0.0/", "requires_dist": null, "requires_python": "", "summary": "A Datalog engine", "version": "2.0.0" }, "last_serial": 5416596, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "11b04155d4bdf2a1790ae22c149c5f15", "sha256": "fc53bbd763a918663950a088e860ec8b43e4be8cd31179cdf060b88f6c8ce965" }, "downloads": -1, "filename": "arrdem.datalog-0.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "11b04155d4bdf2a1790ae22c149c5f15", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 9743, "upload_time": "2019-05-28T21:12:49", "url": "https://files.pythonhosted.org/packages/4b/86/2692186c3cc19aafe201b84ad0e552421c0669840730510156ddf92b5f5a/arrdem.datalog-0.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "fb46e312b737ca6ceb3963c43117231d", "sha256": "fa2fb016845478592f38190787c9509465f0d953f5d5d08baa3ebcd0dd1985c9" }, "downloads": -1, "filename": "arrdem.datalog-0.0.1-py3-none-any.whl", "has_sig": false, "md5_digest": "fb46e312b737ca6ceb3963c43117231d", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 9741, "upload_time": "2019-05-28T21:12:50", "url": "https://files.pythonhosted.org/packages/31/67/de789c6cb436ca7883c24bf458e12c555aba68d377b7c505ce3ed96d42bb/arrdem.datalog-0.0.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "a7d6efe654ff3ad366691bf3f061e517", "sha256": "449f83b0fa8474ae2c1d46c9fe24def8a1037006a4a0f788bad4f3e91fd8d6fc" }, "downloads": -1, "filename": "arrdem.datalog-0.0.1.tar.gz", "has_sig": false, "md5_digest": "a7d6efe654ff3ad366691bf3f061e517", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9608, "upload_time": "2019-05-28T19:57:35", "url": "https://files.pythonhosted.org/packages/4d/7e/aea769d6e5234809a9c9e8883180af2c0e8e9c50218bb5ef11049d09e7ec/arrdem.datalog-0.0.1.tar.gz" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "20ba8c3ef2be8156f39714bb3185760f", "sha256": "4161c6f69afa2a0badaec7cee07e0988d864aab1d3bd7badf45ecd07338fcf5d" }, "downloads": -1, "filename": "arrdem.datalog-0.0.2.tar.gz", "has_sig": false, "md5_digest": "20ba8c3ef2be8156f39714bb3185760f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9619, "upload_time": "2019-05-28T21:13:18", "url": "https://files.pythonhosted.org/packages/3e/1a/3e61b7d63817f7f5220db9a6a605b66060bea7687ae12a3a1c6d9c2222ef/arrdem.datalog-0.0.2.tar.gz" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "f421e7cbece747296bbfc3ba9fca63af", "sha256": "dcdf4d6d7fb8751ae327feeea2b40af3a820e91ea52c355f1f8decfea8286df2" }, "downloads": -1, "filename": "arrdem.datalog-0.0.3.tar.gz", "has_sig": false, "md5_digest": "f421e7cbece747296bbfc3ba9fca63af", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10111, "upload_time": "2019-05-29T06:45:32", "url": "https://files.pythonhosted.org/packages/91/6e/b5213f39f41084f3e44567a6487e34f3e05cffd9eafd96c14a2f4aedd88d/arrdem.datalog-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "8deb6960035b9e9308d12d4394e812c1", "sha256": "0f43a9b7ae40515439acbaa78fe5fd12d25efbbccff79bc504a2bbd8af72e0b7" }, "downloads": -1, "filename": "arrdem.datalog-0.0.4.tar.gz", "has_sig": false, "md5_digest": "8deb6960035b9e9308d12d4394e812c1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12648, "upload_time": "2019-05-30T19:51:26", "url": "https://files.pythonhosted.org/packages/f0/bf/2d77ca5130af7c9cb4f761e3d3021c1fe745f1235704bead9bb87f4d2e30/arrdem.datalog-0.0.4.tar.gz" } ], "0.0.5": [ { "comment_text": "", "digests": { "md5": "c297220d5ba2e43796e83c883c777da2", "sha256": "9a1a5443415ba181e2bf24e156a9ef87a8e6f23ae0d3e1db897dfa1d98eec2e0" }, "downloads": -1, "filename": "arrdem.datalog-0.0.5.tar.gz", "has_sig": false, "md5_digest": "c297220d5ba2e43796e83c883c777da2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14409, "upload_time": "2019-06-05T16:14:10", "url": "https://files.pythonhosted.org/packages/8a/3c/0f3e8990bf267f203d0299efc44e7e00d290c233f0e461905af0e7d811bb/arrdem.datalog-0.0.5.tar.gz" } ], "0.0.6": [ { "comment_text": "", "digests": { "md5": "cf85a8a22b0c88d58bc1b8d2ac713000", "sha256": "27b4d9c7c167c18708a6174b95a27230830366aa5e8aa42e72d2f97152cb2cf3" }, "downloads": -1, "filename": "arrdem.datalog-0.0.6.tar.gz", "has_sig": false, "md5_digest": "cf85a8a22b0c88d58bc1b8d2ac713000", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14951, "upload_time": "2019-06-12T19:19:43", "url": "https://files.pythonhosted.org/packages/7b/d4/9d64cbabb0595318dfe078916a170d26ed41db7ceaf8b087ac6dd71f1109/arrdem.datalog-0.0.6.tar.gz" } ], "0.0.7": [ { "comment_text": "", "digests": { "md5": "ee52a8c83eb40967060f89a0dfbce9ae", "sha256": "d1bf2c96f78290012cfa3455b6f54b62904475763a6a50cc092c647e22ec65ac" }, "downloads": -1, "filename": "arrdem.datalog-0.0.7.tar.gz", "has_sig": false, "md5_digest": "ee52a8c83eb40967060f89a0dfbce9ae", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15009, "upload_time": "2019-06-12T19:32:48", "url": "https://files.pythonhosted.org/packages/33/20/ff86ab2010a160974c49107c747ddb1ac20db3373548d47a4167c0af8f17/arrdem.datalog-0.0.7.tar.gz" } ], "0.0.8": [ { "comment_text": "", "digests": { "md5": "ce95bcf3f1b7fe163357f43e27b78542", "sha256": "265dbceb9bcdee085f71d6867993e822980454f1091cd2b3288f225750d7f2ca" }, "downloads": -1, "filename": "arrdem.datalog-0.0.8.tar.gz", "has_sig": false, "md5_digest": "ce95bcf3f1b7fe163357f43e27b78542", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 16025, "upload_time": "2019-06-13T20:57:59", "url": "https://files.pythonhosted.org/packages/20/53/80cdfb2beb9f34f59e2bb46e97fee34f756b360bdb4bb22558d2455880ba/arrdem.datalog-0.0.8.tar.gz" } ], "0.0.9": [ { "comment_text": "", "digests": { "md5": "b8776a4321948c358059bd08130a4ed2", "sha256": "4e170d54d50d291a7ada4f9c2322e2840b3acaa536eedc61135f06f844572547" }, "downloads": -1, "filename": "arrdem.datalog-0.0.9.tar.gz", "has_sig": false, "md5_digest": "b8776a4321948c358059bd08130a4ed2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14366, "upload_time": "2019-06-16T19:21:05", "url": "https://files.pythonhosted.org/packages/48/90/3ac48e40e28d78abf0ae0c935e5cd487d095755077b9d22c71ae6e0a7834/arrdem.datalog-0.0.9.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "051c97068295f08bce2e1003f7699350", "sha256": "eeb30b5b487123e53df418bfb2c0bae84731b9804aa80cadaf4ffdbdc1598764" }, "downloads": -1, "filename": "arrdem.datalog-1.0.0.tar.gz", "has_sig": false, "md5_digest": "051c97068295f08bce2e1003f7699350", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 14518, "upload_time": "2019-06-18T07:57:26", "url": "https://files.pythonhosted.org/packages/0a/cd/b658d7668376b6dc3cbb297389138c19054f14b4afbc9688ff0a656c147f/arrdem.datalog-1.0.0.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "cf8f18840c41d4342da9f01dd83b8a61", "sha256": "fea6d9dbf50f38f0cc75bf4a218567b018281f5988c6a7fcafb084fd77584e72" }, "downloads": -1, "filename": "arrdem.datalog-2.0.0.tar.gz", "has_sig": false, "md5_digest": "cf8f18840c41d4342da9f01dd83b8a61", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15324, "upload_time": "2019-06-18T18:28:59", "url": "https://files.pythonhosted.org/packages/49/8d/2c03bb058d570defb2ccbd6f1642f07000555077bc9765efa9d22c513ae0/arrdem.datalog-2.0.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "cf8f18840c41d4342da9f01dd83b8a61", "sha256": "fea6d9dbf50f38f0cc75bf4a218567b018281f5988c6a7fcafb084fd77584e72" }, "downloads": -1, "filename": "arrdem.datalog-2.0.0.tar.gz", "has_sig": false, "md5_digest": "cf8f18840c41d4342da9f01dd83b8a61", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 15324, "upload_time": "2019-06-18T18:28:59", "url": "https://files.pythonhosted.org/packages/49/8d/2c03bb058d570defb2ccbd6f1642f07000555077bc9765efa9d22c513ae0/arrdem.datalog-2.0.0.tar.gz" } ] }