桂林山水甲天下

Jacquette的技术生活

Jena2提供的规则推理引擎(上)


翻译自Jena文档。

一,简介
Jena2提供的规则推理引擎支持前向链、后向链以及二者混合的推理执行模型,更准确地说,Jena有两个内部规则引擎:前向链推理RETE引擎和一个tabled datalog engine.它们可以独立运行,或者前向链作为后向链引擎的先导,来完成“查询-问答”。

不同的推理引擎配置可以通过一个单独的参数化推理机GenericRuleReasoner来进行。GenericRuleReasoner的最小需求是需要一个规则集来定义其行为。带有规则集的GenericRuleReasoner实例和其他推理机的用法类似,它和一个数据模型绑定,基于推理模型回答查询请求。

规则推理机还可以通过注册新的过程原语进行扩展,Jena现在的发布版本包括开始的一系列原语,它们对RDFS和OWL的实现来说已经足够并且是易于扩展的。

二,规则语法和结构
在基于规则的推理机中,规则被定义为一个Java的Rule对象,该对象由body terms(前提)的list,head terms(结论)list以及可选的名字和可选的方向来定义。每一个term或者ClauseEntry是一个三元模式(triple pattern),一个扩展的三元模式(extended triple pattern??)或者一个内嵌过程原语的调用。一个规则集是简单的规则列表(List)。

Jena的规则语法分析parser支持简单的基于文本的规则语法:
Rule := bare-rule .
         or [bare-rule]
              or [ruleName : bare-rule ]

bare-rule := term, ..., term -> hterm, ... , hterm
                or term, ..., term <- term, ...., term

hterm := term
            or  [bare-rule ]

term := (node, node, node)
          or (node, node ,functor)
          or builtin(node, ..., node)

functor := functorName(node, ..., node)  // 结构化的literal

node := uri-ref                      // 例如,http://foo.com/eg
         or prefix:localname    // e.g. , rdf:type
         or ?varname               // variable变量
        or 'a literal'                  // a plain string literal
         or 'lex'^^typeURI     // a typed literal, xsd:* type names supported
        or number                   // e.g.  42 or  25.5

functor是用来创建和访问结构化文字值的。functorName是any 简单的identifier,它不与内嵌过程原语的执行相关,它只是一个数据结构。当在多个三元组之上定义一个单一的语义结构时,需要functor,以使得规则可以将这些三元组collect到一个地方。

为了保证规则的可读性,URI引用应符合qname语法。具名prefix是那些用PrintUtil对象注册的。比如rdf,rdfs,owl,daml,xsd是初始值,更多的映射还可以进一步注册。

下面是一些规则例子:

[allID: (?C rdf:type owl:Restriction),  (?C owl:onProperty ?P),
            (?C owl:allValuesFrom ?D) -> (?C owl:equivalentClass all(?P,?D)) ]

[all2: (?C rdfs:subClassOf all(?P,?D) -> print('Rule for', ?C)
         [allb: (?Y rdf:type ?D) <- (?X rdf:type ?C)]]

[max1: (?A rdf:type max(?P,1)), (?A ?P ?B), (?A, ?P, ?C) -> (?B owl:sameAs ?C) ]

规则allID阐释了functor的使用,它是用来将OWL约束的几个元素集合成为一个单一的数据结构,然后再触发其他规则。规则all2阐释了一个前向规则,它生成一个新的后向规则,并且还调用了print过程原语。规则 max1则说明了数字类型的使用。

规则文件的加载和分析是这样进行的:

List rules = Rule.rulesFromURL("file:myfile.rules");

或者

BufferedReader br = /*open reader */;
List rules = Rule.parseRules(Rule.rulesParserFromReader(br));

或者
String ruleSrc = /* lists of rules in lines */
List rules = Rule.parseRules(rulesSrc);

在前面两种情况下,规则文件被一个简单的处理器预先处理,将注释去掉,并支持一些额外的宏命令:
@prefix pre: <http://domain/url#>.
定义一个前缀pre,前缀对规则文件来说是局部的。

@include <urlToRuleFile>
包含在一个给定文件中定义的规则。不管@include出现在哪里,包含的规则都将出现在用户定义的规则前面。
注意: A set of special cases is supported to allow a rule file to include the predefined rules for RDFS and OWL - in place of a real URL for a rule file use one of the keywords RDFS OWL OWLMicro OWLMini (case insensitive).
规则文件可以包含预定义的规则,例如RDFS和OWL等,这时urlToRuleFile被关键字RDFS, OWL, OWLMicro, OWLMini取代。

下面是包含RDFS预定义规则的一个规则文件的完整例子:
# Example rule file
@prefix pre: <http://jena.hpl.hp.com/prefix#>.
@include <RDFS>.

[rule1: (?f pre:father ?a) (?u pre:brother ?f) -> (?u pre:uncle ?a)]

前向链推理引擎
如果规则推理机被配置为以前向模式执行,那么就只能使用前向链引擎。当首次查询inference model时(或者显式调用prepare()时),模型中的所有相关数据提交到规则引擎中。任何触发创建其他三元组的规则在Jena内部的deductions graph中创建三元组,并反过来再触发其他规则。
remove原语用于删除三元组,并且能够在删除(removal mode)模式下触发规则执行。这种规则的迭代触发执行方式一致继续,直到没有规则可以触发。

一旦准备阶段完成,inference graph将作为所有在original model中的语句以及规则触发产生的放在internal deductions graph中的语句的联合来执行。这些所有的语句对所有查询都是可见的,与一般模式(normal model)下具有类似的访问速度。也可以将对原始数据和归结语句分开访问。

若推理模型(inference model)由于调用普通的API而增加、删除了部分语句,就将引发规则执行。前向规则递增式地执行,只能访问增加、删除后的结果。默认的规则引擎基于标准的RETE算法(C.L Forgy, RETE : A fast algorithm for the many pattern/many object pattern match problem, Artificial Intelligence 1982)。

当Jena以前向模式运行时,规则文件中的所有规则(包括以后向语法<-写成的规则)都被作为前向规则。

匹配的规则被触发的顺序或前提(规则体中的term)被检验的顺序还没有确保。
但一旦规则被触发,规则头中的terms将以从左到右的顺序执行。


在前向模式中,断言后向规则的规则头terms被忽略(如all1b中)。

posted on 2006-08-16 21:29  Jacquette.wang  阅读(5571)  评论(2编辑  收藏  举报

导航