之前的教程中,所有的操作,包括定义数据等都是在python里面进行的。但是当我们处理庞大的知识库的时候,我们肯定不希望把所有的数据都写在一个py文件里,而是希望把它存在更通用的保存数据的文件格式/数据库里面,在需要的时候再让程序来读取就好了。
pyDatalog可以做到这些功能。下面是关于从文件中读取pyDatalog程序,我自己写的简单例子:
In [1]:
代码语言:javascript复制from pyDatalog import pyDatalog
def run_program():
# 创建一个简单的Datalog程序文件
text0 = "factorial[N] = N*factorial[N-1]nfactorial[1] = 1"
with open("sample_datalog_program.txt", 'w') as f:
f.write(text0)
file_in = open("sample_datalog_program.txt", 'r')
mc = file_in.read()
print(mc)
pyDatalog.load(mc)
file_in.close()
print(pyDatalog.ask('factorial[3]==N')) # 执行语句,注意这里不需要预先create_terms
if __name__ == "__main__":
run_program()
代码语言:javascript复制factorial[N] = N*factorial[N-1]
factorial[1] = 1
{(6,)}
这一部分功能,官网上称之为:
动态Datalog语句
因为一些应用可能需要动态创建和执行Datalog语句(比如实时),这时就可以使用这些指令。下面的例子给出了所有动态Datalog语句的接口:
In [2]:
代码语言:javascript复制from pyDatalog.pyDatalog import assert_fact, retract_fact, load, ask
from pyDatalog import pyDatalog
# load(string): 从字符中加载Datalog语句
load("""
parent('Kangxi', 'Yongzheng')
parent('Yongzheng', 'Qianlong')
ancestor(X,Y) <= parent(X,Y)
ancestor(X,Y) <= parent(X,Z) & ancestor(Z,Y)
""")
# assert_fact(string,不限量任意参数): 添加事实
assert_fact('parent', 'Qianlong','Jiaqing')
# 相当于 ' parent('Qianlong', 'Jiaqing') '
# ask: 通过字符串执行指令,并把answer作为元组返回
print(ask("ancestor('Kangxi',Y)"))
# assert_fact(string,不限量任意参数): 删除事实
retract_fact('parent', 'Qianlong','Jiaqing')
# 相当于 '- parent('Qianlong', 'Jiaqing')
代码语言:javascript复制print(ask("ancestor('Kangxi',Y)"))
代码语言:javascript复制{('Jiaqing',), ('Yongzheng',), ('Qianlong',)}
{('Yongzheng',), ('Qianlong',)}
有了这些操作,我们就可以想一些办法来处理更通用的数据格式了,比如说Excel表格(这里使用pandas的DataFrame演示一个简单例子):
In [3]:
代码语言:javascript复制import pandas as pd
pyDatalog.clear() #清空前面学到的事实
# 简单的表示关系的数据表
data = pd.DataFrame({"object":['Kangxi','Yongzheng','Qianlong'],
"relation":['parent','parent','parent'],
"subject":['Yongzheng','Qianlong','Jiaqing']})
print(data)
代码语言:javascript复制 object relation subject
0 Kangxi parent Yongzheng
1 Yongzheng parent Qianlong
2 Qianlong parent Jiaqing
In [4]:
代码语言:javascript复制# 数据表转为Datalog语句
data_str = ""
for line_id,line in data.iterrows():
obj,rela,subj = line["object"],line["relation"],line["subject"]
data_str = " %s('%s','%s')n" % (rela,obj,subj)
print(data_str)
load(data_str)
代码语言:javascript复制 parent('Kangxi','Yongzheng')
parent('Yongzheng','Qianlong')
parent('Qianlong','Jiaqing')
In [5]:
代码语言:javascript复制# 规则与数据分离
rules = """
ancestor(X,Y) <= parent(X,Y)
ancestor(X,Y) <= parent(X,Z) & ancestor(Z,Y)
"""
load(rules)
print(ask("ancestor(X,Y)"))
代码语言:javascript复制{('Kangxi', 'Yongzheng'), ('Qianlong', 'Jiaqing'), ('Yongzheng', 'Jiaqing'), ('Yongzheng', 'Qianlong'), ('Kangxi', 'Jiaqing'), ('Kangxi', 'Qianlong')}