英文:
How to input inferred triples to (other) SHACL rules?
问题
我最近接触了SHACL,我真的很喜欢它。我在SHACL规则方面遇到了一个问题,想知道是否有人能帮助我。
我创建了这个小本体,它是我正在处理的GDPR更大本体的一部分。
# baseURI: http://w3.org/ns/temp
# prefix: temp
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix temp: <http://w3.org/ns/temp#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://w3.org/ns/temp>
rdf:type owl:Ontology ;
owl:versionInfo "Created with TopBraid Composer" ;
.
# ... 以下为本体的各种定义 ...
其中有五个主要的类:PersonalDataProcessing、DataSubject、LegalBasis、Consent和GiveConsent。还有四个(功能性的)对象属性:
- hasLegalBasis(领域:PersonalDataProcessing,范围:LegalBasis)。
- hasAgent(领域:GiveConsent,范围:DataSubject)
- hasPatient(领域:GiveConsent,范围:Consent)
- objectOfConsent(领域:Consent,范围:PersonalDataProcessing)
还有一个名为"isLawful"的布尔数据类型属性,定义在PersonalDataProcessing上:每个PersonalDataProcessing可以是合法的(isLawful=true)或非法的(isLawful=false)。
我创建了一个属于GiveConsent类的个体"gc"。"gc"有一个代理"John"(他是一个DataSubject),以及一个患者"c"(这是一个Consent)。Consent"c"通过属性objectOfConsent与另一个个体"pdp"连接,而"pdp"是一个PersonalDataProcessing。
然后我有两条SHACL规则。其中一条规则具有"sh:order 1",因此它应该在另一条规则之后执行(后者具有默认的sh:order,等于0)。
# baseURI: http://w3.org/ns/rules
# imports: http://w3.org/ns/temp
# prefix: rules
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rules: <http://w3.org/ns/rules#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix temp: <http://w3.org/ns/temp#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://w3.org/ns/rules>
rdf:type owl:Ontology ;
owl:imports <http://w3.org/ns/temp> ;
owl:versionInfo "Created with TopBraid Composer" ;
.
# ... 以下为规则的定义 ...
上述第一条规则指出,如果某人已经同意PersonalDataProcessing,那么该同意是PersonalDataProcessing的法律依据。第二条规则(具有"sh:order 1 ;")说明,每个具有法律依据的PersonalDataProcessing都是合法的。
最后,我编写了一个Java文件来执行这些规则:
// 加载本体
Model ontology = JenaUtil.createMemoryModel();
FileInputStream fisOntology = new FileInputStream("./ontology.ttl");
ontology.read(fisOntology, "urn:dummy", FileUtils.langTurtle);
// 加载规则
Model rules = JenaUtil.createMemoryModel();
FileInputStream fisRules = new FileInputStream("./rules.ttl");
rules.read(fisRules, "urn:dummy", FileUtils.langTurtle);
// 执行规则
Model inferredModel = RuleUtil.executeRules(ontology, rules, null, null);
// 打印结果
System.out.println(ModelPrinter.get().print(inferredModel));
我之所以写信给您,是因为上述第一条规则在上述Java代码中正确地创建了三元组"pdp hasLegalBasis c":
<http://w3.org/ns/temp#pdp>
<http://w3.org/ns/temp#hasLegalBasis>
<http://w3.org/ns/temp#c> ;
然而,第二条规则在推断出这个三元组之后没有触发:isLawful没有被设置为true。
另一方面,如果我手动在本体中添加三元组"pdp hasLegalBasis c",两条规则都会触发:
<http://w3.org/ns/temp#pdp>
<http://w3.org/ns/temp#hasLegalBasis>
<http://w3.org/ns/temp#c> ;
<http://w3.org/ns/temp#isLawful>
true .
我做错了什么?有谁能帮助我吗?
非常感谢。
英文:
I recently approached SHACL and I really like it. I have a problem with SHACL rules and I wonder if any of you could help me.
I created this small ontology, a portion of a much bigger ontology for the GDPR that I am working on.
# baseURI: http://w3.org/ns/temp
# prefix: temp
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix temp: <http://w3.org/ns/temp#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://w3.org/ns/temp>
rdf:type owl:Ontology ;
owl:versionInfo "Created with TopBraid Composer" ;
.
temp:Action
rdf:type owl:Class ;
rdfs:subClassOf owl:Thing ;
.
temp:Consent
rdf:type owl:Class ;
rdfs:subClassOf owl:Thing ;
.
temp:DataSubject
rdf:type owl:Class ;
rdfs:subClassOf owl:Thing ;
.
temp:GiveConsent
rdf:type owl:Class ;
rdfs:subClassOf temp:Action ;
.
temp:John
rdf:type temp:DataSubject ;
.
temp:LegalBasis
rdf:type owl:Class ;
rdfs:subClassOf owl:Thing ;
.
temp:PersonalDataProcessing
rdf:type owl:Class ;
rdfs:subClassOf owl:Thing ;
.
temp:c
rdf:type temp:Consent ;
temp:objectOfConsent temp:pdp ;
.
temp:gc
rdf:type temp:GiveConsent ;
temp:hasAgent temp:John ;
temp:hasPatient temp:c ;
.
temp:hasAgent
rdf:type owl:FunctionalProperty ;
rdfs:domain temp:GiveConsent ;
rdfs:range temp:DataSubject ;
.
temp:hasLegalBasis
rdf:type owl:FunctionalProperty ;
rdfs:domain temp:PersonalDataProcessing ;
rdfs:range temp:LegalBasis ;
.
temp:hasPatient
rdf:type owl:FunctionalProperty ;
rdfs:domain temp:GiveConsent ;
rdfs:range temp:Consent ;
.
temp:isLawful
rdf:type owl:DatatypeProperty ;
rdfs:domain temp:PersonalDataProcessing ;
rdfs:range xsd:boolean ;
.
temp:objectOfConsent
rdf:type owl:FunctionalProperty ;
rdfs:domain temp:Consent ;
rdfs:range temp:PersonalDataProcessing ;
.
temp:pdp
rdf:type temp:PersonalDataProcessing ;
.
There are five main classes: PersonalDataProcessing, DataSubject, LegalBasis, Consent, and GiveConsent. And, there are four (functional) object properties:
- hasLegalBasis (domain: PersonalDataProcessing, range: LegalBasis).
- hasAgent (domain: GiveConsent, range: DataSubject)
- hasPatient (domain: GiveConsent, range: Consent)
- objectOfConsent (domain: Consent, range: PersonalDataProcessing)
And there is one datatype (boolean) property called "isLawful" and defined on PersonalDataProcessing: every PersonalDataProcessing can be lawful (isLawful=true) or not (isLawful=false).
I created an individual "gc" within the class GiveConsent. "gc" has an agent "John" (who is a DataSubject) and a patient "c" (which is a Consent). The Consent "c" is connected via the property objectOfConsent to another individual "pdp", which is a PersonalDataProcessing.
Then I have two SHACL rules. One of them has "sh:order 1", so it should be executed after the other one (which has default sh:order equal to 0);
# baseURI: http://w3.org/ns/rules
# imports: http://w3.org/ns/temp
# prefix: rules
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix rules: <http://w3.org/ns/rules#> .
@prefix sh: <http://www.w3.org/ns/shacl#> .
@prefix temp: <http://w3.org/ns/temp#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<http://w3.org/ns/rules>
rdf:type owl:Ontology ;
owl:imports <http://w3.org/ns/temp> ;
owl:versionInfo "Created with TopBraid Composer" ;
.
rules:givenConsentIsLegalBasis
rdf:type sh:NodeShape ;
sh:rule [
rdf:type sh:TripleRule ;
sh:object [
sh:path temp:hasPatient ;
] ;
sh:predicate temp:hasLegalBasis ;
sh:subject [
sh:path (
temp:hasPatient
temp:objectOfConsent
) ;
] ;
] ;
sh:targetClass temp:GiveConsent ;
.
rules:legalBasisEntailLawful
rdf:type sh:NodeShape ;
sh:rule [
rdf:type sh:TripleRule ;
sh:order 1 ;
sh:condition [
sh:property [
sh:path temp:hasLegalBasis ;
sh:minCount 1 ;
] ;
] ;
sh:object "true"^^xsd:boolean ;
sh:predicate temp:isLawful ;
sh:subject sh:this ;
] ;
sh:targetClass temp:PersonalDataProcessing ;
.
The first rule above states that if someone has given consent to a PersonalDataProcessing, that consent is a legal basis for the PersonalDataProcessing. The second rule (with "sh:order 1 ;") states that every PersonalDataProcessing that has a legal basis is lawful.
Finally I wrote a Java file to execute the rules:
//Load the ontology
Model ontology = JenaUtil.createMemoryModel();
FileInputStream fisOntology = new FileInputStream("./ontology.ttl");
ontology.read(fisOntology, "urn:dummy", FileUtils.langTurtle);
//Load the rules
Model rules = JenaUtil.createMemoryModel();
FileInputStream fisRules = new FileInputStream("./rules.ttl");
rules.read(fisRules, "urn:dummy", FileUtils.langTurtle);
//Executing the rules
Model inferredModel = RuleUtil.executeRules(ontology, rules, null, null);
//Print
System.out.println(ModelPrinter.get().print(inferredModel));
I am writing you because the first rule correctly creates the triple "pdp hasLegalBasis c" via the Java code above:
<http://w3.org/ns/temp#pdp>
<http://w3.org/ns/temp#hasLegalBasis>
<http://w3.org/ns/temp#c> ;
However, the second rule do NOT trigger after this triple is inferred: isLawful is NOT set to true.
On the other hand, if I manually add the triple "pdp hasLegalBasis c" in the ontology, both rules triggers:
<http://w3.org/ns/temp#pdp>
<http://w3.org/ns/temp#hasLegalBasis>
<http://w3.org/ns/temp#c> ;
<http://w3.org/ns/temp#isLawful>
true .
What am I doing wrong? Can any of you help me?
Thank you very much
答案1
得分: 1
FWIW,当在TopBraid Composer中执行示例时,它是有效的,该工具会自动执行多次迭代。因此我怀疑问题可能与规则的顺序有关。sh:order
仅用于同一形状内的规则,但不会影响跨形状的“外部”循环。因此,在您的示例中,sh:order
的值不会产生效果。
作为一种常规替代方法,尝试将规则引擎调用两次,第一次迭代的推理结果作为第二轮的输入。为此,您需要在对 RuleUtil
的调用之外构建推理模型(就像如果将 inferencesModel
设为 null
时 RuleUtil
所做的那样)。请参阅 RuleUtil
类的源代码。
英文:
FWIW your example does work when executed from TopBraid Composer, which does multiple iterations automatically. So I suspect it's about the order of rules. sh:order is only used for the rules within the same shape, but will not inform the "outer" loop across shapes. As a result, the sh:order values in your example have no effect.
As a general alternative, try calling the rule engine twice with the inferences from the first iteration serving as input to the second round. To do that, you need to construct the inferences Model outside of the calls to RuleUtil similar to what RuleUtil does if you leave inferencesModel null. See the source code of the RuleUtil class.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论