使用推理规则创建新对象
Create a new object using the inference rules
我有一个语义网络。是否可以使用 jena 框架根据某些规则在语义网中创建新对象。比如有一个对象有某个属性,那么你需要创建一个新的对象,并在它们之间建立联系。可能吗?
如果您的需求相当简单,您可以使用 SPARQL CONSTRUCT 查询,即
CONSTRUCT { ?p :hasGrandfather ?g . }
WHERE {
?p :hasParent ?parent .
?parent :hasParent ?g .
?g :gender :male .
}
将导致生成三元组来说明祖父关系。
如果您的需求更复杂,您可以在 Jena exists 之上使用 SHACL for which an implementation 来实现。我将举一个简短的例子。假设您有以下 RDF 数据:
@prefix ex: <http://example.com/ns#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
ex:InvalidRectangle
a ex:Rectangle .
ex:NonSquareRectangle
a ex:Rectangle ;
ex:height 2 ;
ex:width 3 .
ex:SquareRectangle
a ex:Rectangle ;
ex:height 4 ;
ex:width 4 .
为其定义以下形状文件:
@prefix ex: <http://example.com/ns#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dash: <http://datashapes.org/dash#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
ex:Rectangle
a rdfs:Class, sh:NodeShape ;
rdfs:label "Rectangle" ;
sh:property [
sh:path ex:height ;
sh:datatype xsd:integer ;
sh:maxCount 1 ;
sh:minCount 1 ;
sh:name "height" ;
] ;
sh:property [
sh:path ex:width ;
sh:datatype xsd:integer ;
sh:maxCount 1 ;
sh:minCount 1 ;
sh:name "width" ;
] ;
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate rdf:type ;
sh:object ex:Square ;
sh:condition ex:Rectangle ;
sh:condition [
sh:property [
sh:path ex:width ;
sh:equals ex:height ;
] ;
] ;
] .
它将生成以下 RDF 数据:
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
<http://example.com/ns#SquareRectangle>
a <http://example.com/ns#Square> .
您可以将其添加到您的 RDF 商店。
可以找到这个带有代码的例子here, as well as a more advanced example。
是的,这在耶拿的规则系统中是可能的。通常,我们使用 makeSkolem
Reasoner Builtin Primitive:
创建这样的节点
[example:
(?a urn:ex:owns ?b)
makeSkolem(?ownership,?a,?b)
->
(?a urn:ex:hasOwnership ?ownership)
(?ownership urn:ex:of ?b)
]
这将在图中创建一个新的空白节点,用于具体化 <urn:ex:owns>
三元组。例如,当给定包含三元组 <urn:ex:a> <urn:ex:owns> <urn:ex:b>
作为输入的图形时,前面的规则将生成以下图形结构:
<urn:ex:a> <urn:ex:hasOwnership> [
<urn:ex:of> <urn:ex:b>
].
如果您有一些生成 URI 的方案,也可以在您的规则中构建 URI。
Java 示例
假设 so.rules
存在于您的类路径中并包含上述规则,以下 java 代码将演示此任务的自定义规则。
// Obtains a list of rules to pass to a rule-based reasoner
// These rules are read from a file.
// This is the most common case.
final List<Rule> rules;
try (final InputStream src = Resources.getResource("so.rules").openStream()) {
rules = Rule
.parseRules(Rule.rulesParserFromReader(new BufferedReader(new InputStreamReader(src))));
}
// Create a rule-based reasoner.
// There are multiple types of reasoners available.
// You may prefer some over others (e.g., when performing OWL inference in tandem with custom rules)
final GenericRuleReasoner reasoner =
(GenericRuleReasoner) GenericRuleReasonerFactory.theInstance().create(null);
reasoner.setRules(rules);
// Create a RDF Model to store data in.
// Create an inference model to interact with.
// The inference model will store any added data in the base model.
// The inference model will store inferred triples internally.
final Model baseModel = ModelFactory.createDefaultModel();
final InfModel model = ModelFactory.createInfModel(reasoner, baseModel);
model.prepare();
// Stimulate the rule by introducing the desired triples to the graph
// :a :owns :b
final Property owns = model.createProperty("urn:ex:", "owns");
final Property hasOwnership = model.createProperty("urn:ex:","hasOwnership");
final Property of = model.createProperty("urn:ex:","of");
final Resource a = model.createResource("urn:ex:a");
final Resource b = model.createResource("urn:ex:b");
model.add(a,owns,b);
// Verify that the rule has fired. That is, that we have created some node
// and that the node relates our other two resources
// -> :a :hasOwnership [ :of :b ]
assertTrue(a.hasProperty(hasOwnership));
final Resource createdObject = a.getPropertyResourceValue(hasOwnership);
assertTrue(createdObject.hasProperty(of,b));
我有一个语义网络。是否可以使用 jena 框架根据某些规则在语义网中创建新对象。比如有一个对象有某个属性,那么你需要创建一个新的对象,并在它们之间建立联系。可能吗?
如果您的需求相当简单,您可以使用 SPARQL CONSTRUCT 查询,即
CONSTRUCT { ?p :hasGrandfather ?g . }
WHERE {
?p :hasParent ?parent .
?parent :hasParent ?g .
?g :gender :male .
}
将导致生成三元组来说明祖父关系。
如果您的需求更复杂,您可以在 Jena exists 之上使用 SHACL for which an implementation 来实现。我将举一个简短的例子。假设您有以下 RDF 数据:
@prefix ex: <http://example.com/ns#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
ex:InvalidRectangle
a ex:Rectangle .
ex:NonSquareRectangle
a ex:Rectangle ;
ex:height 2 ;
ex:width 3 .
ex:SquareRectangle
a ex:Rectangle ;
ex:height 4 ;
ex:width 4 .
为其定义以下形状文件:
@prefix ex: <http://example.com/ns#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix dash: <http://datashapes.org/dash#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
ex:Rectangle
a rdfs:Class, sh:NodeShape ;
rdfs:label "Rectangle" ;
sh:property [
sh:path ex:height ;
sh:datatype xsd:integer ;
sh:maxCount 1 ;
sh:minCount 1 ;
sh:name "height" ;
] ;
sh:property [
sh:path ex:width ;
sh:datatype xsd:integer ;
sh:maxCount 1 ;
sh:minCount 1 ;
sh:name "width" ;
] ;
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate rdf:type ;
sh:object ex:Square ;
sh:condition ex:Rectangle ;
sh:condition [
sh:property [
sh:path ex:width ;
sh:equals ex:height ;
] ;
] ;
] .
它将生成以下 RDF 数据:
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
<http://example.com/ns#SquareRectangle>
a <http://example.com/ns#Square> .
您可以将其添加到您的 RDF 商店。
可以找到这个带有代码的例子here, as well as a more advanced example。
是的,这在耶拿的规则系统中是可能的。通常,我们使用 makeSkolem
Reasoner Builtin Primitive:
[example:
(?a urn:ex:owns ?b)
makeSkolem(?ownership,?a,?b)
->
(?a urn:ex:hasOwnership ?ownership)
(?ownership urn:ex:of ?b)
]
这将在图中创建一个新的空白节点,用于具体化 <urn:ex:owns>
三元组。例如,当给定包含三元组 <urn:ex:a> <urn:ex:owns> <urn:ex:b>
作为输入的图形时,前面的规则将生成以下图形结构:
<urn:ex:a> <urn:ex:hasOwnership> [
<urn:ex:of> <urn:ex:b>
].
如果您有一些生成 URI 的方案,也可以在您的规则中构建 URI。
Java 示例
假设 so.rules
存在于您的类路径中并包含上述规则,以下 java 代码将演示此任务的自定义规则。
// Obtains a list of rules to pass to a rule-based reasoner
// These rules are read from a file.
// This is the most common case.
final List<Rule> rules;
try (final InputStream src = Resources.getResource("so.rules").openStream()) {
rules = Rule
.parseRules(Rule.rulesParserFromReader(new BufferedReader(new InputStreamReader(src))));
}
// Create a rule-based reasoner.
// There are multiple types of reasoners available.
// You may prefer some over others (e.g., when performing OWL inference in tandem with custom rules)
final GenericRuleReasoner reasoner =
(GenericRuleReasoner) GenericRuleReasonerFactory.theInstance().create(null);
reasoner.setRules(rules);
// Create a RDF Model to store data in.
// Create an inference model to interact with.
// The inference model will store any added data in the base model.
// The inference model will store inferred triples internally.
final Model baseModel = ModelFactory.createDefaultModel();
final InfModel model = ModelFactory.createInfModel(reasoner, baseModel);
model.prepare();
// Stimulate the rule by introducing the desired triples to the graph
// :a :owns :b
final Property owns = model.createProperty("urn:ex:", "owns");
final Property hasOwnership = model.createProperty("urn:ex:","hasOwnership");
final Property of = model.createProperty("urn:ex:","of");
final Resource a = model.createResource("urn:ex:a");
final Resource b = model.createResource("urn:ex:b");
model.add(a,owns,b);
// Verify that the rule has fired. That is, that we have created some node
// and that the node relates our other two resources
// -> :a :hasOwnership [ :of :b ]
assertTrue(a.hasProperty(hasOwnership));
final Resource createdObject = a.getPropertyResourceValue(hasOwnership);
assertTrue(createdObject.hasProperty(of,b));