首先,如果您提供了最小本体作为起点,那么回答这个问题会更容易。幸运的是,这很简单。在 Turtle 序列化中:
@prefix : <https://stackoverflow.com/q/22688901/1281433/competitions#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<https://stackoverflow.com/q/22688901/1281433/competitions>
a owl:Ontology .
:Player a owl:Class .
:Team a owl:Class .
:Competition a owl:Class .
:employs a owl:ObjectProperty ;
rdfs:domain :Team ;
rdfs:range :Player .
:competesIn a owl:ObjectProperty ;
rdfs:domain [ a owl:Class ;
owl:unionOf ( :Player :Team )
] ;
rdfs:range :Competition .
我们实际上并不需要属性上的域和范围声明来完成这项工作,但无论如何我已经包含了它们,因为你提到了它们。你试图表达“如果球队雇佣了一名球员,球队在比赛中竞争,那么球员也在比赛中竞争”。从逻辑上讲,我们可以表示为:
雇佣(?team,?player) ∧ CompetitionsIn(?team,?competition) → CompetitionsIn(?player,?competition)
画出我们所拥有的关系以及我们想要得到什么是很有用的:
实线箭头是我们实际拥有的,虚线箭头是我们想要推断的。我们可以使用 OWL 中的子属性链来做到这一点。沿着实线箭头从 ?player 到 ?competition 存在路径或属性链。路径的第一条边沿反向箭头,所以它是一个反向属性(employs-1),第二条边沿正向箭头,它只是competitesIn。我们试图说,只要有这样的路径,就会在路径的起点和终点之间存在竞争关系。链写为“employs-1 • CompetitionsIn”,我们想断言它是competitsIn的子属性:
雇用-1 •竞争在⊑参加比赛
在 Protégé 中,如下所示:
这给我们留下了最终的本体:
@prefix : <https://stackoverflow.com/q/22688901/1281433/competitions#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
:Player a owl:Class .
:Team a owl:Class .
:Competition a owl:Class .
<https://stackoverflow.com/q/22688901/1281433/competitions>
a owl:Ontology .
:employs a owl:ObjectProperty ;
rdfs:domain :Team ;
rdfs:range :Player .
:competesIn a owl:ObjectProperty ;
rdfs:domain [ a owl:Class ;
owl:unionOf ( :Player :Team )
] ;
rdfs:range :Competition ;
owl:propertyChainAxiom ( [ owl:inverseOf
:employs ] :competesIn ) .
限制适用的主题
最初的问题中没有提到,但在 cmets 中透露,除了球员之外的东西可以被团队使用,其中一些东西不应该被推断为参加比赛。这仍然可以处理,但它会变得更加完整。诀窍是意识到你需要一个新的公理形式:
p •雇用-1 •竞争在⊑参加比赛
其中 p 是将每个玩家与他或她自己联系起来的一些特殊属性。构建这样的属性称为 rolification。该技术已在另一个 Stack Overflow 问题OWL 2 rolification 以及与该问题相关联的学术出版物中进行了详细描述。还有一些其他的answers on Stack Overflow 也涉及到 rolification。还有some on answers.semanticweb.com。无论如何,想法是定义一个新的属性,对应于类的RPlayer,并用公理定义类Player :
玩家≡R玩家一些自我
这表示 x 是一个 Player 当且仅当 RPlayer(x,x),而这正是我们p需要填写。这为我们提供了以下本体:
@prefix : <https://stackoverflow.com/q/22688901/1281433/competitions#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix owl: <http://www.w3.org/2002/07/owl#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<https://stackoverflow.com/q/22688901/1281433/competitions>
a owl:Ontology .
:R_Player a owl:ObjectProperty .
:employs a owl:ObjectProperty ;
rdfs:domain :Team ;
rdfs:range :Player .
:competesIn a owl:ObjectProperty ;
rdfs:domain [ a owl:Class ;
owl:unionOf ( :Player :Team )
] ;
rdfs:range :Competition ;
owl:propertyChainAxiom ( :R_Player [ owl:inverseOf
:employs ] :competesIn ) .
:Team a owl:Class .
:Competition a owl:Class .
:Player a owl:Class ;
owl:equivalentClass [ a owl:Restriction ;
owl:hasSelf true ;
owl:onProperty :R_Player
] .