这一回,我们的目标是用pyDatalog与“知识图谱”交互。知识图谱是个很复杂的概念,但一般其中的知识都是以RDF三元组的形式存储的,所以我在这里实际上演示的是pyDatalog与RDF类三元组的交互。官网上没有提供这类问题的“标准解法”,下面的例子是我的一些思考,我也从中发现了用Datalog管理和维护知识图谱的一些特有优势:
话说东汉末年,群雄并起,其中一支号称汉室宗亲,这正是我们熟悉的刘备刘皇叔了。刘备自称中山靖王之后,而这一点在近代保守质疑。假如这一点被推翻,刘备及其后代的宗亲身份,获得的名望和资源,以皇帝身份匡扶汉室的正统性就都不成立了。
这里存在着一个逻辑链和许多关系。关系的表达是知识图谱的长处,而逻辑链的建立和维护则是Datalog的优势。所以我就以这个作为例子,演示pyDatalog与知识图谱的交互。
In [1]:
#coding=utf-8
# 与RDF的交互
from pyDatalog import pyDatalog
from pyDatalog.pyDatalog import assert_fact, retract_fact, load, ask
import rdflib
from rdflib import Literal
pyDatalog.create_terms('X,Y,R,relation')
prefix0 = "http://www.blmoistawinde.org/example1#" # URI的统一前缀
abbr = lambda x: x[len(prefix0):] # 取URI的缩写,为了展示的简洁
verbose = lambda x: prefix0+x # 恢复缩写为URI的全称
g = rdflib.Graph()
g.parse("father_son.ttl", format="turtle")
print("original data:")
for subj, pred, obj in g: #从RDF取出三元组
print(abbr(subj),abbr(pred), abbr(obj))
assert_fact("relation",abbr(subj),abbr(pred), abbr(obj)) #加入Datalog数据库
load("relation(X,'GrandfatherOf',Z) <= relation(X,'FatherOf',Y) & relation(Y,'FatherOf',Z)")
这里用到的RDF文件内容(father_son.ttl):
In [2]:
# @prefix : <http://www.blmoistawinde.org/example1#>.
# :ZhongShanJingWang :IsA :ZongQin .
# :LiuBei :FatherOf :LiuShan.