Antoine Zimmerman 的回答是正确的,因为这种事情在 OWL 中是可以表达的,但是它需要比您预期的更多的工作,因为您正在尝试强制执行一种封闭世界推理和默认推理,而 OWL 使开放世界假设其中,如果您不知道某事,则不会假定它是真或假,只是未知。但是,一旦闭包公理到位,这并不是一个很难编写的场景。我认为值得一步一步地解决这个问题,看看所有需要存在的公理才能做出这个推断,并在 OWL DL 中做到这一点。您没有提到 Protégé,但它是一个非常方便的 OWL 编辑器,并且使编写这些公理变得更加容易。最后我也会展示最终的 OWL(在 RDF/XML 和 Turtle 中)。
为了仅代表一个实例,我将声明一个具有 Alice、Bill、Cindy 和 Dan 作为成员的 Voters 类,然后断言这些人是不同的:
现在,为了将每个 Voter 与他们的投票相关联,我们可以引入一个 hasVote 属性,其中包含域 Voter 和包含字符串“yes”和“no”的枚举范围。
我们仍然需要一些东西这与四个选民有关,将他们联系在一起。从概念上讲,这是一个投票活动,其中唯一的参与者是 Alice、Bill、Cindy 和 Dan,并且每个选民只有一票。让我们介绍一个类 VotingEvent 和一个对象属性 hasVoter,它将 VotingEvent 与其参与者相关联。现在,有一些投票事件,我们将为此引入一个单独的votingEvent1。我们将断言它的参与者是 Alice、Bill、Cindy 和 Dan,而且只有那些,并且在这个事件中的每个选民都只有一票。我们还添加了两个类型约束,表示该事件恰好有 2 个“是”选民。这已经足够了,因为要求只有四个被枚举的选民,他们是不同的,每个人都只有一个投票,并且每个投票要么是“是”
现在,如果我们最终断言爱丽丝和比尔投了“是”票,
正如我们通过在 Protégé 中运行 DL 查询所看到的那样,足以用推理器推断出 Cindy 和 Dan 投了“不”票:
Turtle 和 RDF/XML 序列化都不是特别好看,但我在最后附上了它们,以便于复制和粘贴。现在,这是单个投票事件的合适表示,但请注意,我们引入了投票事件是为了有一些东西,我们添加了关于四个选民及其投票值的限制。但是,如果有多个投票事件,并且一些选民参加了不止一个事件,那么简单地限制一个选民只有一票是有问题的,因为选民可能在一个事件中投票“是”而在另一个事件中投票“否”。“投票者x在事件z中投了y票" 是一个三元关系,如果要出现多个事件,确实需要这样表示。W3C 工作组说明,在语义网上定义 N 元关系描述了一些方法,但基本思想是您将定义一个类,其成员代表个人投票,并与投票事件、选民和投票相关。您仍然可以为这种推理编写适当的限制,尽管它们会有点更复杂,可能涉及属性链或嵌套类表达式。
海龟序列化
@prefix : <http://example.org/voters#> .
@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#> .
@prefix voters: <http://example.org/voters#> .
voters:Voter a owl:Class .
voters:VotingEvent a owl:Class .
voters:hasVote a owl:DatatypeProperty ;
rdfs:domain voters:Voter ;
rdfs:range [ a rdfs:Datatype ;
owl:oneOf [ a rdf:List ;
rdf:first "no" ;
rdf:rest [ a rdf:List ;
rdf:first "yes" ;
rdf:rest ()
]
]
] .
voters:Dan a owl:NamedIndividual , voters:Voter .
<http://example.org/voters>
a owl:Ontology .
voters:Alice a owl:NamedIndividual , voters:Voter ;
voters:hasVote "yes" .
voters:Bill a owl:NamedIndividual , voters:Voter ;
voters:hasVote "yes" .
voters:Cindy a owl:NamedIndividual , voters:Voter .
voters:hasVoter a owl:ObjectProperty ;
rdfs:domain voters:VotingEvent ;
rdfs:range voters:Voter .
voters:votingEvent1 a owl:NamedIndividual , voters:VotingEvent ;
a [ a owl:Restriction ;
owl:onClass [ a owl:Restriction ;
owl:hasValue "yes" ;
owl:onProperty voters:hasVote
] ;
owl:onProperty voters:hasVoter ;
owl:qualifiedCardinality "2"^^xsd:nonNegativeInteger
] ;
a [ a owl:Restriction ;
owl:allValuesFrom [ a owl:Class ;
owl:oneOf ( voters:Dan voters:Bill voters:Cindy voters:Alice )
] ;
owl:onProperty voters:hasVoter
] ;
a [ a owl:Restriction ;
owl:allValuesFrom [ a owl:Restriction ;
owl:onDataRange xsd:string ;
owl:onProperty voters:hasVote ;
owl:qualifiedCardinality "1"^^xsd:nonNegativeInteger
] ;
owl:onProperty voters:hasVoter
] ;
voters:hasVoter voters:Alice , voters:Bill , voters:Cindy , voters:Dan .
[ a owl:AllDifferent ;
owl:distinctMembers ( voters:Alice voters:Bill voters:Cindy voters:Dan )
] .
RDF/XML 序列化
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:owl="http://www.w3.org/2002/07/owl#"
xmlns:voters="http://example.org/voters#"
xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">
<owl:Ontology rdf:about="http://example.org/voters"/>
<owl:Class rdf:about="http://example.org/voters#Voter"/>
<owl:Class rdf:about="http://example.org/voters#VotingEvent"/>
<owl:ObjectProperty rdf:about="http://example.org/voters#hasVoter">
<rdfs:range rdf:resource="http://example.org/voters#Voter"/>
<rdfs:domain rdf:resource="http://example.org/voters#VotingEvent"/>
</owl:ObjectProperty>
<owl:DatatypeProperty rdf:about="http://example.org/voters#hasVote">
<rdfs:domain rdf:resource="http://example.org/voters#Voter"/>
<rdfs:range>
<rdfs:Datatype>
<owl:oneOf>
<rdf:List>
<rdf:first>no</rdf:first>
<rdf:rest>
<rdf:List>
<rdf:first>yes</rdf:first>
<rdf:rest rdf:resource="http://www.w3.org/1999/02/22-rdf-syntax-ns#nil"/>
</rdf:List>
</rdf:rest>
</rdf:List>
</owl:oneOf>
</rdfs:Datatype>
</rdfs:range>
</owl:DatatypeProperty>
<owl:AllDifferent>
<owl:distinctMembers rdf:parseType="Collection">
<owl:NamedIndividual rdf:about="http://example.org/voters#Alice">
<rdf:type rdf:resource="http://example.org/voters#Voter"/>
<voters:hasVote>yes</voters:hasVote>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="http://example.org/voters#Bill">
<rdf:type rdf:resource="http://example.org/voters#Voter"/>
<voters:hasVote>yes</voters:hasVote>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="http://example.org/voters#Cindy">
<rdf:type rdf:resource="http://example.org/voters#Voter"/>
</owl:NamedIndividual>
<owl:NamedIndividual rdf:about="http://example.org/voters#Dan">
<rdf:type rdf:resource="http://example.org/voters#Voter"/>
</owl:NamedIndividual>
</owl:distinctMembers>
</owl:AllDifferent>
<owl:NamedIndividual rdf:about="http://example.org/voters#votingEvent1">
<rdf:type rdf:resource="http://example.org/voters#VotingEvent"/>
<rdf:type>
<owl:Restriction>
<owl:onProperty rdf:resource="http://example.org/voters#hasVoter"/>
<owl:onClass>
<owl:Restriction>
<owl:onProperty rdf:resource="http://example.org/voters#hasVote"/>
<owl:hasValue>yes</owl:hasValue>
</owl:Restriction>
</owl:onClass>
<owl:qualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger"
>2</owl:qualifiedCardinality>
</owl:Restriction>
</rdf:type>
<rdf:type>
<owl:Restriction>
<owl:onProperty rdf:resource="http://example.org/voters#hasVoter"/>
<owl:allValuesFrom>
<owl:Class>
<owl:oneOf rdf:parseType="Collection">
<owl:NamedIndividual rdf:about="http://example.org/voters#Dan"/>
<owl:NamedIndividual rdf:about="http://example.org/voters#Bill"/>
<owl:NamedIndividual rdf:about="http://example.org/voters#Cindy"/>
<owl:NamedIndividual rdf:about="http://example.org/voters#Alice"/>
</owl:oneOf>
</owl:Class>
</owl:allValuesFrom>
</owl:Restriction>
</rdf:type>
<rdf:type>
<owl:Restriction>
<owl:onProperty rdf:resource="http://example.org/voters#hasVoter"/>
<owl:allValuesFrom>
<owl:Restriction>
<owl:onProperty rdf:resource="http://example.org/voters#hasVote"/>
<owl:qualifiedCardinality rdf:datatype="http://www.w3.org/2001/XMLSchema#nonNegativeInteger"
>1</owl:qualifiedCardinality>
<owl:onDataRange rdf:resource="http://www.w3.org/2001/XMLSchema#string"/>
</owl:Restriction>
</owl:allValuesFrom>
</owl:Restriction>
</rdf:type>
<voters:hasVoter rdf:resource="http://example.org/voters#Alice"/>
<voters:hasVoter rdf:resource="http://example.org/voters#Bill"/>
<voters:hasVoter rdf:resource="http://example.org/voters#Cindy"/>
<voters:hasVoter rdf:resource="http://example.org/voters#Dan"/>
</owl:NamedIndividual>
</rdf:RDF>