数据日志引擎
arrdem.datalog的Python项目详细描述
数据日志
在python中实现数据日志。
什么是数据日志?
数据日志是一种用于表示关系数据和查询的完全声明性语言,通常使用prolog的语法子集编写。 与其他关系语言(如sql)相比,它最有趣的特性是它具有产生式规则。
简而言之,数据日志数据库由规则和元组组成。
元组被写入a(b,"c",126,…。
,不需要声明例如。
表的长度可以是任意的甚至可变的。
编写规则时f(a,b):-a(a),b(b)
,计算时生成元组。
例如,这个规则定义了元组集合的元素的叉积。
快速启动
我们将使用datalog.easy rel="nofollow">datalog.easyapi。 它有点简单,而且有明显的优势,但是比直接使用python的查询引擎更符合人体工程学。
# Pull in the datalog.easy package
>>> from datalog import easy
# Read some tuples into a Dataset.
#
# Because the base Dataset class has some limitations, easy gives you
# an instance of the IndexedDataset which is best supported
>>> db = read('''
... edge(a, b).
... edge(b, c).
... edge(c, d).
... edge(d, e).
... ''')
现在我们已经有了一个数据库实例,我们可以对它运行一些查询。
这两个核心操作是select和join。 select选择元组-常量和from规则。 join通过统一逻辑变量一次选择多个元组。
让我们先选择一些元组。
select返回一组对(元组,绑定)
,其中元组是所选元组(实际上总是一个元组),绑定是lvar到绑定常量的映射。
>>> easy.select(db, ('edge', 'a', 'b'))
[((('edge', 'a', 'b'),), {})]
酷!
但如果我们想从一个
这就是逻辑变量的来源。
逻辑变量在文本数据日志中以大写形式写入,并且在处理查询时,easy包将大写字符串识别为逻辑变量。只有一个这样的元组,边(a,b)
,但让我们看看是否找到它。
>>> easy.select(db, ('edge', 'a', 'B'))
[((('edge', 'a', 'b'),), {'B': 'b'})]
很好。
但是加入呢?
规则确实是给连接结果命名的一种方法,但是我们也可以直接进行连接。
例如,我们可以尝试选择所有连续的2段路径。不像select只接受一个元组,join需要同时满足一系列元组。 然而,select like join返回一个成对的序列(元组,绑定),元组实际上可能有许多元素。
在本例中,我们选择相邻的边对,这样我们将在每个结果中得到两个元组和三个绑定。
>>> easy.join(db, [
... ('edge', 'A', 'B'), # Any edge, ending at B
... ('edge', 'B', 'C') # Any edge, beginning at the same B
... ])
[((('edge', 'a', 'b'),
('edge', 'b', 'c')),
{'A': 'a', 'B': 'b', 'C': 'c'}),
((('edge', 'b', 'c'),
('edge', 'c', 'd')),
{'A': 'b', 'B': 'c', 'C': 'd'}),
((('edge', 'c', 'd'),
('edge', 'd', 'e')),
{'A': 'c', 'B': 'd', 'C': 'e'})]
API
数据日志类型
types包提供了系统其余部分使用的核心表示。
它定义常量(值)
和lvar(名称)
元组类型。
数据日志元组a(b,c)
在内部表示为(constant('a')、constant('b')、constant('c'))
。
包含逻辑变量的元组除了包含常量值之外,还包含lvar实例。
类型别名用于同时包含常量和逻辑变量的元组。
类型别名用于只包含常量的元组。
a规则(模式,子句)
是一对altuple
作为规则生成的元组的模式,以及一系列表示规则结果的连接约束的子句ltuple
值。
types包还定义了数据集
类。
数据集是元组序列的容器,是定义元组的规则序列。
实际上,数据集
类只有三个方法rules()
,tuples()
和merge(other)
查询规划者主要在dataset
实例方面工作,尽管dataset
的扩展可能得到更好的支持。
cacheddataset
是dataset
类型的扩展,它允许查询引擎缓存求值规则的结果。
这将启用递归规则计算和其他一些优化。
indexedataset
是cacheddataset
的扩展,它还支持可以减少处理数据量的索引。
数据日志分析器
此包仅包含生成的代码,用于实现读取器。 其内容不稳定。
数据日志读取器
读取器只故意公开三个方法-read
akaread_dataset
它接受一个字符串和一个可选的kwargdb_cls
作为扩展dataset
的类,应该在其中读取元组和规则。
它还公开了read_命令,该命令返回一对
(op:str,val:anyer[rule,ltuple])
。
此函数用于实现repl的部分,单独打包(pypi,git)。
数据日志计算器
目前,evaluator只包含两种方法-select
和join
。
select和join是相互递归的,因为规则求值是递归地选择连接的结果。
目前,系统中只有一个select和join的实现。 将来,此界面将被替换,以添加对查询计划器的支持。
用户应该更喜欢通常稳定的datalog.easy
界面,而不是直接使用计算器。
数据日志。简单
读取器和求值器上的填充程序,旨在使与来自python的求值器的交互更加方便。 不是更简单,只是更方便。
read(str,db_cls=indexedataset)
只是一个填充程序,可以使用更好的默认类来datalog.reader.read
。
select(db:dataset,query:ltuple)
急切地计算所有结果,而不是生成生成器,消除元组和绑定中的constant()
和lvar()
包装器。
join(db:dataset,query:sequence[ltuple])
同样急切地求值所有结果,同样地简化了结果。
用法
$ pip install --user arrdem.datalog
限制
递归可能有一些完整性错误。我还没有遇到过,但是我 对于 规则尚未制定。
当前的否定子句实现不能传播正的 信息。这意味着否定子句只能与 带有肯定从句。不清楚这是否是一个必要的限制。
到目前为止还没有查询规划器-甚至没有根据
与限制性评价的关系。这意味着查询的复杂性是
o(数据集*术语计数)
,这显然不太理想。
许可证
从https://git.arrdem.com/arrdem/datalog-py" rel="nofollow">https://git.arrdem.com/arrdem/datalog py
镜像根据麻省理工学院的许可证出版。请参见license.md