OWL RDF/TTL根据属性使实例成为类的成员 [英] OWL RDF/TTL Make an instance member of class based on property
问题描述
我正在尝试设计一个本体,该本体将根据产品组件对产品进行分类.在下面的示例中,我有一个类Ingredient
和一个实例eggs
.我想将apple_tart
添加到所有不包含eggs
的产品类别中.因此,在这种情况下,apple_tart
将添加到类GlutenFriendly
而不是VeganFriendly
中.
I am trying to design an ontology that will categorise products based on the products components. In the example below I have a class Ingredient
with an instance eggs
. I want to add apple_tart
to all classes of products that do not contain eggs
. So in this case apple_tart
will be added to the class GlutenFriendly
and NOT VeganFriendly
.
bakery:VeganFriendly rdf:type owl:Class ;
rdfs:subClassOf [ rdf:type owl:Restriction ;
owl:onProperty :hasIngredient ;
owl:hasValue :eggs
]
owl:disjointWith bakery:Ingredient .
所以我想在eggs
和类VeganFriendly
之间创建负关联?上面的代码将添加带有eggs
...
So I'm trying to create a negative association between eggs
and the class VeganFriendly
? The above code will add products with eggs
...
EIDT:我也乐意接受能带来相同效果的新设计.最好只使用OWL/RDF/RDFS.
EIDT: I'm also open to new designs that would result in the same. Preferably only using OWL/RDF/RDFS.
推荐答案
The only way to do what you need (that I am aware of) is using SHACL rules. Assuming you have the following RDF data:
@prefix bakery: <http://bakery.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 owl: <http://www.w3.org/2002/07/owl#> .
bakery:hasIngredient rdf:type owl:ObjectProperty ;
rdfs:domain bakery:BakeryGood ;
rdfs:range bakery:Ingredient .
bakery:VeganFriendly rdf:type owl:Class ;
owl:subClassOf bakery:Ingredient .
bakery:NonVeganFriendly rdf:type owl:Class ;
owl:subClassOf bakery:Ingredient .
bakery:GlutenFree rdf:type owl:Class ;
owl:subClassOf bakery:Ingredient .
bakery:NonGlutenFree rdf:type owl:Class ;
owl:subClassOf bakery:Ingredient .
bakery:Apple a bakery:VeganFriendly, bakery:GlutenFree .
bakery:Egg a bakery:NonVeganFriendly, bakery:GlutenFree .
bakery:Flour a bakery:VeganFriendly, bakery:NonGlutenFree .
bakery:AlmondFlour a bakery:VeganFriendly, bakery:GlutenFree .
bakery:RiceMilk a bakery:VeganFriendly, bakery:GlutenFree .
bakery:AppleTartA
a bakery:BakedGood ;
bakery:hasIngredient bakery:Apple, bakery:Egg, bakery:Flour .
bakery:AppleTartB
a bakery:BakedGood ;
bakery:hasIngredient bakery:Apple, bakery:RiceMilk, bakery:AlmondFlour .
bakery:AppleTartC
a bakery:BakedGood ;
bakery:hasIngredient bakery:Apple, bakery:RiceMilk, bakery:Flour .
bakery:AppleTartD
a bakery:BakedGood ;
bakery:hasIngredient bakery:Apple, bakery:Egg, bakery:AlmondFlour .
您可以指定以下形状规则文件:
you can specify the following shape rule file:
@prefix bakery: <http://bakery.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#> .
bakery:bakery:NonVeganFriendly
a rdfs:Class, sh:NodeShape .
bakery:bakery:NonGlutenFree
a rdfs:Class, sh:NodeShape .
bakery:BakedGood
a rdfs:Class, sh:NodeShape ;
sh:property [
sh:path bakery:hasIngredient ;
sh:class bakery:Ingredient ;
sh:nodeKind sh:IRI ;
sh:minCount 1 ;
] ;
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate rdf:type ;
sh:object bakery:VeganBakedGood ;
sh:condition bakery:BakedGood ;
sh:condition [
sh:property [
sh:path bakery:hasIngredient ;
sh:qualifiedValueShape [ sh:class bakery:NonVeganFriendly ] ;
sh:qualifiedMaxCount 0 ;
] ;
] ;
] ;
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate rdf:type ;
sh:object bakery:NonVeganBakedGood ;
sh:condition bakery:BakedGood ;
sh:condition [
sh:property [
sh:path bakery:hasIngredient ;
sh:qualifiedValueShape [ sh:class bakery:NonVeganFriendly ] ;
sh:qualifiedMinCount 1 ;
] ;
] ;
] ;
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate rdf:type ;
sh:object bakery:GlutenFreeBakedGood ;
sh:condition bakery:BakedGood ;
sh:condition [
sh:property [
sh:path bakery:hasIngredient ;
sh:qualifiedValueShape [ sh:class bakery:NonGlutenFree ] ;
sh:qualifiedMaxCount 0 ;
] ;
] ;
] ;
sh:rule [
a sh:TripleRule ;
sh:subject sh:this ;
sh:predicate rdf:type ;
sh:object bakery:NonGlutenFreeBakedGood ;
sh:condition bakery:BakedGood ;
sh:condition [
sh:property [
sh:path bakery:hasIngredient ;
sh:qualifiedValueShape [ sh:class bakery:NonGlutenFree] ;
sh:qualifiedMinCount 1 ;
] ;
] ;
] .
,并使用SHACL的Jena实现使用以下代码来执行您的规则:
and use the following code using the Jena implementation of SHACL to execute your rules:
package org.shacl.tutorial;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.jena.rdf.model.Model;
import org.apache.jena.rdf.model.ModelFactory;
import org.apache.jena.reasoner.Reasoner;
import org.apache.jena.reasoner.ReasonerRegistry;
import org.apache.jena.riot.RDFDataMgr;
import org.apache.jena.riot.RDFFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;
import org.topbraid.shacl.rules.RuleUtil;
import org.topbraid.spin.util.JenaUtil;
public class ShaclClassification {
private static Logger logger = LoggerFactory.getLogger(ShaclValidation.class);
// Why This Failure marker
private static final Marker WTF_MARKER = MarkerFactory.getMarker("WTF");
public static void main(String[] args) {
try {
Path path = Paths.get(".").toAbsolutePath().normalize();
String data = "file:" + path.toFile().getAbsolutePath() + "/src/main/resources/bakery.ttl";
String shape = "file:" + path.toFile().getAbsolutePath() + "/src/main/resources/bakeryRules.ttl";
Reasoner reasoner = ReasonerRegistry.getRDFSReasoner();
Model dataModel = JenaUtil.createDefaultModel();
dataModel.read(data);
Model infModel = ModelFactory.createInfModel(reasoner, dataModel);
Model shapeModel = JenaUtil.createDefaultModel();
shapeModel.read(shape);
Model inferenceModel = JenaUtil.createDefaultModel();
inferenceModel = RuleUtil.executeRules(infModel, shapeModel, inferenceModel, null);
String inferences = path.toFile().getAbsolutePath() + "/src/main/resources/inferences.ttl";
File inferencesFile = new File(inferences);
inferencesFile.createNewFile();
OutputStream reportOutputStream = new FileOutputStream(inferencesFile);
RDFDataMgr.write(reportOutputStream, inferenceModel, RDFFormat.TTL);
} catch (Throwable t) {
logger.error(WTF_MARKER, t.getMessage(), t);
}
}
}
它将为您提供以下输出:
which will provide you with the following output:
<http://bakery.com/ns#AppleTartC>
a <http://bakery.com/ns#NonGlutenFreeBakedGood> , <http://bakery.com/ns#VeganBakedGood> .
<http://bakery.com/ns#AppleTartB>
a <http://bakery.com/ns#GlutenFreeBakedGood> , <http://bakery.com/ns#VeganBakedGood> .
<http://bakery.com/ns#AppleTartA>
a <http://bakery.com/ns#NonGlutenFreeBakedGood> , <http://bakery.com/ns#NonVeganBakedGood> .
<http://bakery.com/ns#AppleTartD>
a <http://bakery.com/ns#GlutenFreeBakedGood> , <http://bakery.com/ns#NonVeganBakedGood> .
在我的博客上,我对此示例进行了详细说明:使用SHACL规则进行分类.
On my blog I give a detailed explanation for this example: Classification with SHACL rules.
这篇关于OWL RDF/TTL根据属性使实例成为类的成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!