Jena规则推理引擎 - xibryan/notes GitHub Wiki

1. Jena规则推理引擎

Jena包含了一个通用的规则推理引擎,Jena的RDFS、OWL推理引擎也是基于这个通用的规则引擎实现的。实际上,Jena内部实现了两个独立的规则引擎,一个是基于RETE算法的forward chaining引擎,一个是基于tabled datalog的backward chaining引擎,这两个引擎可以独立运行,也可以放在一起使用。

通用规则引擎对应的接口是GenericRuleReasoner,要使用规则引擎,需要定义一组规则定义引擎的行为。

1.1 规则结构及语法

可以使用#或者//开头注释一行代码。用@include可以导入已经定义好的规则,还可以导入Jena预定义好的RDFS、OWL规则,只需要把文件名称替换为RDFSOWLOWLMicro或者OWLMini 关键字就可以了。

规则结构:

# Example rule file
// A comment line.
@prefix pre: <http://jena.hpl.hp.com/prefix#>.
@include <RDFS>.

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

规则语法:

Rule      :=   bare-rule .
          or   [ bare-rule ]
          or   [ ruleName : bare-rule ]
bare-rule :=   term, … term -> hterm, … hterm    // forward rule
          or   bhterm <- term, … term            // backward rule


hterm     :=   term
          or   [ bare-rule ]


term      :=   (node, node, node)           // triple pattern
          or   (node, node, functor)        // extended triple pattern
          or   builtin(node, … node)        // invoke procedural primitive


bhterm    :=   (node, node, node)           // triple pattern


functor   :=   functorName(node, … node)    // structured literal


node      :=   uri-ref                      // e.g. http://foo.com/eg
          or   prefix:localname             // e.g. rdf:type
          or   <uri-ref>                    // e.g. <myscheme:myuri>
          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

规则样例:

[rule1: (?f pre:father ?a) (?u pre:brother ?f) -> (?u pre:uncle ?a)]
[max1: (?A rdf:type max(?P, 1)), (?A ?P ?B), (?A ?P ?C)
       -> (?B owl:sameAs ?C) ]
(s, p, o), (s1, p1, o1) ... <- (sb1, pb1, ob1), .... 

1.2 规则引擎配置项

Parameter Values Description
PROPruleMode "forward", "forwardRETE", "backward", "hybrid" Sets the rule direction mode as discussed above. Default is "hybrid".
PROPruleSet filename-string The name of a rule text file which can be found on the classpath or from the current directory.
PROPenableTGCCaching Boolean If true, causes an instance of the TransitiveReasoner to be inserted in the forward dataflow to cache the transitive closure of the subProperty and subClass lattices.
PROPenableFunctorFiltering Boolean If set to true, this causes the structured literals (functors) generated by rules to be filtered out of any final queries. This allows them to be used for storing intermediate results hidden from the view of the InfModel's clients.
PROPenableOWLTranslation Boolean If set to true this causes a procedural preprocessing step to be inserted in the dataflow which supports the OWL reasoner (it translates intersectionOf clauses into groups of backward rules in a way that is clumsy to express in pure rule form).
PROPtraceOn Boolean If true, switches on exhaustive tracing of rule executions at the INFO level.
PROPderivationLogging Boolean If true, causes derivation routes to be recorded internally so that future getDerivation calls can return useful information.

配置项使用方法:

Resource configuration = m.createResource();
configuration.addProperty(ReasonerVocabulary.PROPruleMode, "hybrid");
configuration.addProperty(ReasonerVocabulary.PROPruleSet, "src/test/data/rule/demo.rules");

// Create an instance of such a reasoner
Reasoner reasoner = GenericRuleReasonerFactory.theInstance().create(configuration);

1.3 内置函数

Builtin Operations

isLiteral(?x) notLiteral(?x)
isFunctor(?x) notFunctor(?x)
isBNode(?x) notBNode(?x)

Test whether the single argument is or is not a literal, a functor-valued literal or a blank-node, respectively.
bound(?x...) unbound(?x..)
Test if all of the arguments are bound (not bound) variables
equal(?x,?y) notEqual(?x,?y)
Test if x=y (or x != y). The equality test is semantic equality so that, for example, the xsd:int 1 and the xsd:decimal 1 would test equal.

lessThan(?x, ?y), greaterThan(?x, ?y)
le(?x, ?y), ge(?x, ?y)

Test if x is <, >, <= or >= y. Only passes if both x and y are numbers or time instants (can be integer or floating point or XSDDateTime).

sum(?a, ?b, ?c)
addOne(?a, ?c)
difference(?a, ?b, ?c)
min(?a, ?b, ?c)
max(?a, ?b, ?c)
product(?a, ?b, ?c)
quotient(?a, ?b, ?c)

Sets c to be (a+b), (a+1) (a-b), min(a,b), max(a,b), (a*b), (a/b). Note that these do not run backwards, if in sum a and c are bound and b is unbound then the test will fail rather than bind b to (c-a). This could be fixed.

strConcat(?a1, .. ?an, ?t)
uriConcat(?a1, .. ?an, ?t)

Concatenates the lexical form of all the arguments except the last, then binds the last argument to a plain literal (strConcat) or a URI node (uriConcat) with that lexical form. In both cases if an argument node is a URI node the URI will be used as the lexical form.

regex(?t, ?p)
regex(?t, ?p, ?m1, .. ?mn)

Matches the lexical form of a literal (?t) against a regular expression pattern given by another literal (?p). If the match succeeds, and if there are any additional arguments then it will bind the first n capture groups to the arguments ?m1 to ?mn. The regular expression pattern syntax is that provided by java.util.regex. Note that the capture groups are numbered from 1 and the first capture group will be bound to ?m1, we ignore the implicit capture group 0 which corresponds to the entire matched string. So for example
regexp('foo bar', '(.*) (.*)', ?m1, ?m2)
will bind m1 to "foo" and m2 to "bar".
now(?x)
Binds ?x to an xsd:dateTime value corresponding to the current time.
makeTemp(?x)
Binds ?x to a newly created blank node.
makeInstance(?x, ?p, ?v)
makeInstance(?x, ?p, ?t, ?v)
Binds ?v to be a blank node which is asserted as the value of the ?p property on resource ?x and optionally has type ?t. Multiple calls with the same arguments will return the same blank node each time - thus allowing this call to be used in backward rules.
makeSkolem(?x, ?v1, ... ?vn)
Binds ?x to be a blank node. The blank node is generated based on the values of the remain ?vi arguments, so the same combination of arguments will generate the same bNode.
noValue(?x, ?p)
noValue(?x ?p ?v)
True if there is no known triple (x, p, *) or (x, p, v) in the model or the explicit forward deductions so far.
remove(n, ...)
drop(n, ...)
Remove the statement (triple) which caused the n'th body term of this (forward-only) rule to match. Remove will propagate the change to other consequent rules including the firing rule (which must thus be guarded by some other clauses). In particular, if the removed statement (triple) appears in the body of a rule that has already fired, the consequences of such rule are retracted from the deducted model. Drop will silently remove the triple(s) from the graph but not fire any rules as a consequence. These are clearly non-monotonic operations and, in particular, the behaviour of a rule set in which different rules both drop and create the same triple(s) is undefined.
isDType(?l, ?t) notDType(?l, ?t)
Tests if literal ?l is (or is not) an instance of the datatype defined by resource ?t.
print(?x, ...)
Print (to standard out) a representation of each argument. This is useful for debugging rather than serious IO work.
listContains(?l, ?x)
listNotContains(?l, ?x)
Passes if ?l is a list which contains (does not contain) the element ?x, both arguments must be ground, can not be used as a generator.
listEntry(?list, ?index, ?val)
Binds ?val to the ?index'th entry in the RDF list ?list. If there is no such entry the variable will be unbound and the call will fail. Only usable in rule bodies.
listLength(?l, ?len)
Binds ?len to the length of the list ?l.
listEqual(?la, ?lb)
listNotEqual(?la, ?lb)
listEqual tests if the two arguments are both lists and contain the same elements. The equality test is semantic equality on literals (sameValueAs) but will not take into account owl:sameAs aliases. listNotEqual is the negation of this (passes if listEqual fails).
listMapAsObject(?s, ?p ?l)
listMapAsSubject(?l, ?p, ?o)
These can only be used as actions in the head of a rule. They deduce a set of triples derived from the list argument ?l : listMapAsObject asserts triples (?s ?p ?x) for each ?x in the list ?l, listMapAsSubject asserts triples (?x ?p ?o).
table(?p) tableAll()
Declare that all goals involving property ?p (or all goals) should be tabled by the backward engine.
hide(p)
Declares that statements involving the predicate p should be hidden. Queries to the model will not report such statements. This is useful to enable non-monotonic forward rules to define flag predicates which are only used for inference control and do not "pollute" the inference results.

内置函数使用样例

[demo: (?a ?p ?b) (?b ?p ?c)
    -> (?a ?p ?c) print(?a)]

1.4 RDFS、OWL规则引擎的规则文件

  • jena-core/src/main/resources/etc/rdfs.rules
  • jena-core/src/main/resources/etc/owl.rules
⚠️ **GitHub.com Fallback** ⚠️