我应该将 rdf:Statement 子类化以进行具体化吗?

Should I subclass rdf:Statement for reification?

我想具体化 'statement about a statement',说我有 userX memberOf groupY 并想就此发表声明(例如,他们于 5 月 11 日加入)。

所以,我有这样的东西:

statementX a rdf:statement
statementX subject userX
statementX predicate memberOf
statementX object groupY
statementX since "2022-05-11T11:32:52"^^xsd:dateTime

我的问题是,子类化 rdf:statement 值得吗?说 UserGroupStatement rdf:subClassOf rdf:statement,然后说 statementX a UserGroupStatement

这有意义吗,这是人们做的事情吗?或者人们只是使用 rdf:statement,还是创建自己的加入 类?有什么好处和坏处?

在我看来,它至少可以让我模拟某种类型的陈述具有某些属性,例如UserGroupStatement 有一个 'since' 属性(域 UserGroupStatement,范围 xsd:datetime)。但是后来我发现它并不能帮助我指定任何其他内容,因为 UserGroupStatement 的 subject/predicate/object 仍然可以是任何 Resource。或者出于建模目的,我应该只创建一个新的类似语句的链接对象,而完全忘记 rdf:statement 吗?

如果适合您的用例,您可以子类化 rdf:Statement 但要注意大写字母 S,因为 URI 区分大小写。

然后您可以使用 OWL 进一步限制该子类的属性,但这只会帮助您进行推理。我假设您想验证您的数据,因为该用例 SHACL 或 ShEx 更适合。

SHACL 示例

@prefix : <http://example.org/>.
@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#>.
@prefix sh: <http://www.w3.org/ns/shacl#>.
    
# Ontology
:UserStatement rdfs:subClassOf rdf:Statement.

## Knowledge Base
:GroupY a :Group.
:UserX a :User; :memberOf :GroupY.
:AdminX a :Admin; :memberOf :GroupY.    

:CorrectStatement a :UserStatement;
    rdf:subject :UserX;
    rdf:predicate :memberOf;
    rdf:object :GroupY;
    :since "2022-05-11T11:32:52"^^xsd:dateTime.

:IncorrectStatement1 a :UserStatement;
    rdf:subject :AdminX;
    rdf:predicate :memberOf;
    rdf:object :GroupY;
    :since "2022-05-11T11:32:52"^^xsd:dateTime.

:IncorrectStatement2 a :UserStatement;
    rdf:subject :UserX;
    rdf:predicate :schmemberOf;
    rdf:object :GroupY;
    :since "2022-05-11T11:32:52"^^xsd:dateTime.

:InorrectStatement3 a :UserStatement;
    rdf:subject :UserX;
    rdf:predicate :memberOf;
    rdf:object :GroupY.

# SHACL Shape
:UserStatementShape a sh:NodeShape;
    sh:targetClass :UserStatement;  
    sh:property                                       
        [sh:path rdf:type; sh:hasValue :UserStatement; sh:minCount 1; sh:maxCount 1],
        [sh:path rdf:subject; sh:class :User; sh:minCount 1; sh:maxCount 1],
        [sh:path rdf:predicate; sh:hasValue :memberOf; sh:minCount 1; sh:maxCount 1],
        [sh:path rdf:object; sh:class :Group; sh:minCount 1; sh:maxCount 1],
        [sh:path :since; sh:nodeKind sh:Literal; sh:datatype xsd:dateTime; sh:minCount 1; sh:maxCount 1];
    sh:closed true.

输出

将示例保存为test.ttl,安装pySHACL和运行pyshacl test.ttl,您将得到以下内容:

$ pyshacl test.ttl
Validation Report
Conforms: False
Results (3):
Constraint Violation in MinCountConstraintComponent (http://www.w3.org/ns/shacl#MinCountConstraintComponent):
    Severity: sh:Violation
    Source Shape: [ sh:datatype xsd:dateTime ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:nodeKind sh:Literal ; sh:path :since ]
    Focus Node: :InorrectStatement3
    Result Path: :since
    Message: Less than 1 values on :InorrectStatement3->:since
Constraint Violation in HasValueConstraintComponent (http://www.w3.org/ns/shacl#HasValueConstraintComponent):
    Severity: sh:Violation
    Source Shape: [ sh:hasValue :memberOf ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:predicate ]
    Focus Node: :IncorrectStatement2
    Result Path: rdf:predicate
    Message: Node :IncorrectStatement2->rdf:predicate does not contain a value in the set: [':memberOf']
Constraint Violation in ClassConstraintComponent (http://www.w3.org/ns/shacl#ClassConstraintComponent):
    Severity: sh:Violation
    Source Shape: [ sh:class :User ; sh:maxCount Literal("1", datatype=xsd:integer) ; sh:minCount Literal("1", datatype=xsd:integer) ; sh:path rdf:subject ]
    Focus Node: :IncorrectStatement1
    Value Node: :AdminX
    Result Path: rdf:subject
    Message: Value does not have class :User