RDF、RDFS、OWL

    RDF是语义网体系的基础技术,那么到底什么是RDF呢?RDF的英文全称是Resource Description Framework,它的核心就是三元组,(资源,关系,资源),也就是(节点,边,节点)的结构。,本质上,RDF图是节点和边均带有标签的有向图结构,在RDF中,每个资源都有一个URI(URI是用来标识资源的字符串,而我们通常所说的网址叫做URL,它是URI的一种。)来标识,RDF是允许插入不包含任何URI标识的资源的,被称为空白节点或匿名资源,但是为了区分RDF解析器一般会为每个节点分配一个系统生成的内部名。

    RDF的表示方法就是指我们是怎样存储和传输RDF数据的,目前,RDF序列化的方式主要有RDF/XML, N-Triple, Turtle, RDFa, JSON-LD等。所以到底RDF是怎么写的呢?

1 <http://www.kg.com/person/2> <http://www.kg.com/ontology/chineseName> "川普"^^string.
2 <http://www.kg.com/person/2> <http://www.kg.com/ontology/position> "美利坚第45任总统"^^string.
3 <http://www.kg.com/person/2> <http://www.kg.com/ontology/wife> "梅拉尼娅-特朗普"^^string.
4 <http://www.kg.com/person/2> <http://www.kg.com/ontology/nation> "USA"^^string.
5 <http://www.kg.com/person/2> <http://www.kg.com/ontology/age> "72"^^int.
6 <http://www.kg.com/person/2> <http://www.kg.com/ontology/belongparty> <http://www.kg.com/Party/2018>.
7 <http://www.kg.com/party/2018> <http://www.kg.com/ontology/name> "republic"^^string.
8 <http://www.kg.com/party/2018> <http://www.kg.com/ontology/fonder> "汉尼巴尔·哈姆林"^^string.
9 <http://www.kg.com/party/2018> <http://www.kg.com/ontology/born> "1854"^^data.

    同一个实体拥有多个属性或关系,我们可以用一个subject来表示,使其更紧凑,所以我们可以改为:

 1 @prefix person: <http://www.kg.com/person/> .
 2 @prefix party: <http://www.kg.com/party/> .
 3 @prefix : <http://www.kg.com/ontology/> .
 4 
 5 person:1   :chineseName "川普"^^string;
 6            :position "美利坚第45任总统"^^string;
 7            :wife "梅拉尼娅-特朗普"^^string;
 8            :nation "USA"^^string;
 9            :age "72"^^int;
10 party:2018 :name "汉尼巴尔·哈姆林"^^string;
11            :born "1854"^^data.

    这两种便是RDF的两种表现形式,但是RDF的表达能力是有限的,它不能表达面向对象里的类的概念,而类(相当于抽象概念)和对象(相当于实例概念)是面向对象中非常常用的两个概念,所以就有了对RDF的改进——RDFS。

    RDFS/OWL是RDF的“衣服”,因为它们都是用来描述RDF数据的,我们可以将其与关系数据库中的概念进行类比,Mysql中的database被用作schema,我们可以认为数据库中的每一张表都是一个类,表中的每一行都是该类的一个实例或对象,表中的每一列都是这个类所包含的属性。RDFS/OWL本质上是一些预定义词汇的集合,用于对RDF进行类似的类定义及其属性的定义。

    RDFS在RDF的基础上增加了一些词汇扩展了RDF的能力,这些词汇包括类、实例、子集、包含关系等具体概念。在RDFS中,类是一组个体资源的抽象,每个个体资源被称作一个类的实例。

rdfs:class   所有类的类 ;
rdfs:resource   所有资源的类,每个资源都是rdfs:resource的实例 ;
rdfs:property  RDF资源的子集,用来表示资源属性 ;
rdfs:subclassof   类之间的继承关系 ;
rdfs:subpropertyof   属性之间的继承关系  ;
rdfs:domain   描述属性的定义域  ;
rdfs:range  属性的值域  ;

    由于一个RDFS类就是一个RDF资源,所以我们可以把RDFS类写成资源的形式,可以更加的简单清晰。

     以上是一个RDFS的示例,包括了Person、Animal、MaritalStatus类,ssn、age、maritalStatus属性以及John、married、divorced等实例,(习惯用大写首字母标识一个类名,小写首字母标识属性名)。

    对上述RDFS实例进行解释:

    1-3行定义了命名空间;4-7行定义了Person类,a相当于rdf:type;8-9行定义了MaritalStatus类;10-14行描述了属性ssn,表明属性是一个社会保险号;15-22行分别描述了属性age和maritalStatus;23-26行描述了类Person的一个实例john;27-30行描述了实例married、divorced;

    OWL是终极本体语言,它也是对RDF词汇的扩充,不仅有类和实例的词汇表示,还增加了更多关系的表示,OWL具有丰富的知识表示和推理能力。OWL有两个主要的功能:1.提供快速、灵活的数据建模能力;2.高效的自动推理。

    OWL提供了三种表达能力递增的子语言,分别用于特定的实现者和用户团体:(1)OWL Lite;(2)OWL DL;(3)OWL Full;

1.命名空间

    在我们开始一组术语之前,我们需要精确的指出哪些具体的词汇表将会被用到,一个标准的本体开头部分里包括了一组XML命名空间,这些命名空间声明提供了一种无歧义地解释标识符的方式,并使得剩余的本体表示具有更强的可读性。一个典型的OWL本体以一个命名空间声明开始:

1  <rdf:RDF 
2      xmlns     ="http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine#" 
3      xmlns:vin ="http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine#"       
4      xml:base  ="http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine#"       
5      xmlns:food="http://www.w3.org/TR/2004/REC-owl-guide-20040210/food#"   
6      xmlns:owl ="http://www.w3.org/2002/07/owl#"
7      xmlns:rdf ="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8      xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
9      xmlns:xsd ="http://www.w3.org/2001/XMLSchema#"> 

(1)第一个声明指定了缺省命名空间,也就是所有无前缀的限定名都出自该本体;

(2)第二个声明为当前本体指定了前缀vin;

(3)第三个声明为当前文档指定了基准URI;

(4)第四个声明指定了食物(food)本体将用food来标识;

(5)第五个声明表示对出自http://www.w3.org/2002/07/owl#中事物的引用,这是引入OWL词汇表的惯例用法;

(6)因为OWL要依赖RDF、RDFS、XML Schema数据类型中的构词,rdf:前缀表示事物出自命名空间http://www.w3.org/1999/02/22-rdf-syntax-ns#,而后两个命名空间分别为RDF Schema和XML Schema数据类型的指定前缀rdfs:和xsd:。

    为了帮助书写冗长的URI,在本体的定义之前,在文档类型声明中可以提供一些实体的定义,这些被命名空间声明定义的名称仅当作为XML标签的一部分时才具有意义,因为属性值是不具有命名空间的,但是我们在OML中经常要用属性值来引用本体标识符,所以我们可以写出他们完整的URI形式或者可以利用实体定义来简略URI的书写。例如:

1  <!DOCTYPE rdf:RDF [
2      <!ENTITY vin  "http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine#" >
3      <!ENTITY food "http://www.w3.org/TR/2004/REC-owl-guide-20040210/food#" > ]>

    所以这样rdf:RDF的命名空间可以被简化,并且只需对实体声明做简单的修改就可以在整个本体范围内应用URI的变化,简化后的rdf:RDF命名空间为:

1  <rdf:RDF 
2      xmlns     ="&vin;" 
3      xmlns:vin ="&vin;" 
4      xml:base  ="&vin;" 
5      xmlns:food="&food;"
6      xmlns:owl ="http://www.w3.org/2002/07/owl#"
7      xmlns:rdf ="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
8      xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
9      xmlns:xsd ="http://www.w3.org/2001/XMLSchema#"> 

2.本体头部

    在建立完命名空间后,我们就要在owl:Ontology标签里给出一组关于本体的声明,这些标签支持一些重要的工作,例如:注释、版本控制、其他本体的嵌入等。例如:

1  <owl:Ontology rdf:about=""> 
2    <rdfs:comment>An example OWL ontology</rdfs:comment>
3    <owl:priorVersion rdf:resource="http://www.w3.org/TR/2003/PR-owl-guide-20031215/wine"/> 
4    <owl:imports rdf:resource="http://www.w3.org/TR/2004/REC-owl-guide-20040210/food"/> 
5    <rdfs:label>Wine Ontology</rdfs:label> 
6    <owl:AnnotationProperty rdf:about="&dc:creator"/>
7    ......
8  </owl:Ontology> 

    rdfs:comment提供了显然必须的为本体添加注解的能力;

    owl:priorVersion是一个为用于本体的版本控制系统提供相关信息的标准标签;

    owl:imports接收一个用rdf:resource属性标识的参数,提供嵌入机制。导入另一个本体将把那个本体中的全部声明引入到当前本体中,为了充分利用好这一机制,通常要与命名空间声明结合使用,命名空间声明提供的是一种方便对其他本体定义的名称进行引用的方法。在概念上,owl:imports用于表明包含目标本体的声明。

    被用作注解的属性应该用owl:AnnotationProperty来声明。

    本体的头部定义在</owl:Ontology>标签处结束,之后由</rdf:RDF>终止对于本体的实际定义。

3.基本元素

    一个OWL本体中的大部分元素是与类、属性、类的实例以及这些实例间的关系有关的。

3.1简单的类和个体

     许多情况下,使用本体是为了用它进行关于个体的推理,为了在一种有效的方式下做到这一点,我们需要一种机制来描述个体所属的类以及这些个体通过类成员关系而继承得到的属性,尽管我们总能为个体声明特定的属性,但是个体的大部分能力在于基于类的推理。

     3.1.1简单的具名类

     具名类(named class),一个领域中最基本的概念应分别对应于各个分类层次树的根,OWL中所有个体都是类owl:Thing的成员,因此,各个用户自定义的类都隐含地是owl:Thing的一个子类,要定义特定领域的根类,要将他们声明为一个具名类。OWL也可以定义空类。

     对于葡萄酒领域的例子中创建三个根类:Winery、Region、ConsumableThing。

    

<owl:Class rdf:ID="Winery"/>
<owl:Class rdf:ID="Region"/>
<oel:Class rdf:ID="ConsumableThing"/>

     语法rdf:ID="Region"被用于引入一个名称,在这一文档中,我们现在可以用#Region来引用Region类,例如rdf:resource="#Region",而其他的本体可以通过“http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine#Region”这一完整形式来引用该名称。另一种引用类的形式是用语法rdf:about="#Region"来扩展对一个资源的定义,语法rdf:about="&ont;#x"的使用在分布式本体的创建中是一个关键要素,它允许导入x类的定义对它进行扩展,而不需要修改源定义文档,从而支持增量构建更大的本体。

     在前面关于命名空间和实体的定义是这样的:

   

<?xml version="1.0"?>
<!DOCTYPE rdf:RDF>[
    <!ENTITY vin "http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine#">
    <!ENTITY food "http://www.w3.org/TR/2004/REC-owl-guide-20040210/food#"> ]>
<rdf:RDF
    xmlns="&vin;"
    xmlns:vin="&vin;"
    xml:base="&vin;"
    xmlns:food="&food;"
    xmlns:owl="http://www.w3.org/2002/07/owl#"
    xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
    xmlns:rdfs="http://www.w3.org/2000/01/rdf-schama#"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema#">

<owl:Ontology rdf:about="">
    <rdfs:comment>An example OWL ontology</rdfs:comment>
    <owl:priorVersion rdf:resource="http://www.w3.org/TR/2003/PR-owl-guide-20031215/wine"/>
    <owl:imports rdf:resource="http://www.w3.org/TR/2004/REC-owl-guide-20040210/food"/>
    <rdfs:lable>Wine Ontology</rdfs:lable>
</owl:Ontology>
</rdf:RDF>  

     在给出上述定义之后,我们就可以使用XML标签vin:Winery或属性值&vin;Winery来引用Winery类,或者更确切地说,我们总可以用资源的完整URL来引用他们,比如这里我们可以用“http://www.w3.org/TR/2004/REC-owl-guide-20040210/wine#Winery”来引用Winery类。

     一个类的定义由两部分组成:引入或引用一个名称,以及一个限制列表。被直接包含在类定义中的各个表达式进一步限制了该类的实例,该类的实例属于所有这些限制的交集。

     (1)rdfs:subClassOf是用于类的基本分类构造fu,它将一个较具体的类与一个较一般的类关联,如果X是Y的一个子类(subClass),那么X的每个实例同时也是Y的实例。比如:

    

<owl:Class rdf:ID="PotableLiquid">
    <rdfs:subClassOf rdf:resource="#ConsumableThing"/>
    ......
</owl:Class>

     那么PotableLiquid定义为ConsumableThing的子类。

     (2)rdfs:lable是可选的,它为该类提供一个人类可读的名称,“lang”属性为多语言提供了支持。一个lable就像一个注释,不向本体的逻辑解释添加任何内容。

     我们先为Wine类创建一个简单的定义:

   

 1 <owl:Class rdf:ID="Wine">
 2     <rdfs:subClassOf rdfs:resource="&food;PotableLiquid"/>
 3     <rdfs:lable xml:lang="en">wine</rdfs:lable>
 4     <rdfs:lable xml:lang="fr">vin</rdfs:lable>
 5     ......
 6 </owl:Class>
 7 
 8 <owl:Class rdf:ID="Pasta">
 9     <rdfs:subClassOf rdf:resource="#EdibleThing"/>
10     ......
11 </owl:Class>

  下面整理下对上述类的定义:

  • 第一行:创建了一个根类Wine,利用rdf:ID来指定类的名称;
  • 因为一个类是由两部分组成:引入或引用一个名称,以及一个限制列表,所以接下来便是对该类的一些限制,该类的实例属于所有这些限制的交集;
  • rdfs:subClassOf是用于类的基本分类构造符,表示了类Wine是food本体中的PotableLiquid子类。
  • rdfs:lable为该类提供了一个人类可读的名称,lang属性为多语言提供了支持,一个lable就像一个注释,不向本体的逻辑解释添加任何内容。

    

     至此,葡萄酒的定义仍然是不完整的,我们除了知道葡萄酒是一种食物并且适于饮用之外,对它别无所知,但是我们有足够的信息来创建个体和对个体进行推理。

     3.1.2 个体

     关于OWL中类与个体的区别,有一些重要的问题就是,一个类仅是一个名称和一些描述某集合内个体的属性,而个体是该集合的成员,因此,类应自然的对应于与某论域中的事物的出现集合,而个体应对应于可被归入这些类的实际的实体。

     除了描述类,我们还希望能够描述类的成员,我们通常认为类的成员是我们所关心的范畴中的一个个体(而不是另一个类或属性),要引入一个个体,只需将它们声明为某个类的成员。举例来说:

    

<Region rdf:ID="CentralCoastRegion"/>

     这是将CentralCoastRegion设定为Region的成员。也可以写作:

    

<owl:Thing rdf:ID="CentralCoastRegion"/>
<owl:Thing rdf:about="#CentralCoastRegion">
    <rdf:type rdf:resource="#Region"/>
</owl:Thing>

     这里rdf:type是一个RDF属性,用于关联一个个体和它所属的类。

     为了得到更多的类用于将在下一节引入的属性,我们定义了一个Grape的层次分类以及一个代表Cabernet Sauvignon品种的葡萄的个体,Grape在食物本体中的定义是:

   

 <owl:Class rdf:ID="Grape">
  ......
</owl:Class>

     然后我们在葡萄酒本体中定义(在这里Cabernet Sauvignon是一个个体,它代表的是某个单个葡萄品种):

    

<owl:Class rdf:ID="WineGrape">
    <rdfs:subClassOf rdf:resource="&food;Grape"/>
</owl:Class>
<WineGrape rdf:ID="CabernetSauvignonGrape">

3.2简单属性

     如果仅允许定义层次分类,那么这个类和个体的世界也许会变得无趣,属性使得我们可以断言关于类成员的一般事实以及关于个体的具体事实。

     3.2.1定义属性

     一个属性是一个二元关系,有两种类型的属性:

     (1)数据类型属性:类实例与RDF文字或XML Schema数据类型间的关系;

     (2)对象属性:两个类的实例间的关系。

     在定义属性时,有一些对该二元关系施加限定的方法,我们可以指定定义域和值域。在下面的例子中,madeFromGrape的定义域(domain)为Wine,值域(range)为WineGrape,也就是说,它把Wine类的实例关联到WineGrape类的实例,为同一属性声明多个定义域表明该属性的定义域是所有这些类的交集(多个值域声明也类似这样),同样的,属性course将一个Meal和MealCourse相关联。

    

<owl:ObjectProperty rdf:ID="madeFromGrape">
    <rdfs:domain rdf:resource="#Wine"/>
    <rdfs:range rdf:resource="#WineGrape"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="course">
    <rdfs:domain rdf:resource="#Meal"/>
    <rdfs:range rdf:resource="#MealCourse"/>
</owl:ObjectProperty>

     注意:OWL中值域和定义域信息的使用与程序设计语言中的类型信息有所不同,在程序设计语言中,类型被用来检查程序设计语言的一致性,而在OWL中,一个值域可以被用来推断一个类型。比如:

    

<owl:Thing rdf:ID="LindemansBin65Chardonnay">
    <madeFromGrape rdf:resource="#ChardonnayGrape"/>
</owl:Thing>

     我们可以推断出LindemansBin65Chardonnay是一种葡萄酒,因为madeFromGrape的定义域是Wine。

     属性也可以像类一样按照层次结构来组织,例如:

    

<owl:Class rdf:ID="WineDescriptor"/>
<owl:Class rdf:ID="WineColor">
    <rdfs:subClassOf rdf:resource="#WineDescriptor"/>
    ......
</owl:Class>

<owl:ObjectProperty rdf:ID="hasWineDescriptor">
    <rdfs:domain rdf:resource="#Wine"/>
    <rdfs:range rdf:resource="#WineDescriptor"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="hasColor">
    <rdfs:subPropertyOf rdf:resource="#hasWineDescriptor"/>
    <rdfs:range rdf:resource="#WineColor"/>
    ......
</owl:ObjectProperty>

      WineDescriptor属性将葡萄酒与它们的颜色和味觉成分相关联,hasColor是hasWineDescription的子属性,hasColor与hasWineDescriptor的不同在于它的值域被进一步限定为WineColor。rdfs:subPropertyOf关系表示:任何事物如果具有一个值为X的hasColor属性,那么它同时具有一个值为X的hasWineDescription属性。

      下面,我们介绍locatedln属性,它将事物和事物所在的地区相关联,它的定义是:

    

<owl:ObjectProperty rdf:ID="locatedIn">
    ......
    <rdfs:domain rdf:resource="http://www.w3.org/2002/07/owl#Thing"/>
    <rdfs:range rdf:resource="#Region"/>
</owl:ObjectProperty>

     该定义域定义允许任何事物被值域某个区域中,包括该区域本身,这一关系的传递的组合在本质上构建了一个包含子区域和事物的地理网络,没有包含其它事物于其中的那些事物可以属于任意类,而包含其他事物或者区域的那些事物则必须是区域。

     现在我们可以扩展Wine的定义来表达“一个葡萄酒是由至少一种WineGrape制成的”,和属性的定义一样,类定义也由多个隐含相联的部分组成。

    

<owl:Class rdf:ID="Wine">
    <rdfs:subClassOf rdf:resource="&food;PotableLiquid"/>
    <rdfs:subClassOf>
        <owl:Restriction>
            <owl:onProperty rdf:resource="#madeFromGrape"/>
            <owl:minCardinality rdf:datatpe="&xsd;nonNegativeIntger">1
            </owl:minCardinalty>
        </owl:Restriction>
    </rdfs:subClassOf>
    ......
</owl:Class>

     在<owl:Restriction>中定义了一个无名类,该无名类代表至少具有一个madeFromGrape属性的事物集合,我们称这些类为匿名类。在Wine类的定义中包含该限定表明属于Wine类的事物,也是该匿名类的成员,也就是说,任何葡萄酒都必须参与至少一个madeFromGrape关系。

     然后我们定义Vintage类:

    

<owl:Class rdf:ID="Vintage">
    <rdfs:subClassOf>
        <owl:Restriction>
            <owl:onProperty rdf:resource="#vintageOf"/>
            <owl:minCardinality rdf:datatype="&xsd;nonNegativeInteger">1
            </owl:minCardinality>
        </owl:Restriction>
    </rdfs:subClassOf>
</owl:Class>

     vintageOf属性将一个Vintage关联到Wine:

    

<owl:ObjectProperty rdf:ID="vintageOf">
    <rdfs:domain rdf:resource="#Vintage"/>
    <rdfs:range rdf:resource="#Wine"/>
</owl:ObjectProperty>

     3.2.2 属性和数据类型

     根据是将个体关联到个体还是将个体关联到数据类型,我们可以区分两类属性:前者称为对象属性,后者称为数据类型属性。那些数据类型属性的值域范围是RDF文字或者是XML Schema数据类型中定义的那些简单类型,对这些数据类型的引用是通过对http://www.w3.org/2001/XML Schema这个URI引用进行的。

      下列数据类型是推荐在OWL中使用的:

    

 xsd:string         xsd:normalizedString     xsd:boolean

 xsd:decimal     xsd:float    xsd:double

 xsd:integer     xsd:nonNegativeInteger     xsd:positiveInteger

 xsd:nonPositiveInteger     xsd:negativeInteger

 xsd:long     xsd:int     xsd:short     xsd:byte

 xsd:unsignedLong xsd:unsignedInt xsd:unsignedShort xsd:unsignedByte

 xsd:hexBinary xsd:base64Binary

 xsd:dateTime xsd:time xsd:date xsd:gYearMonth

 xsd:gYear xsd:gMonthDay xsd:gDay xsd:gMonth

 xsd:anyURI xsd:token xsd:language

 xsd:NMTOKEN xsd:Name xsd:NCName

     上面的数据类型,连同rdfs:Literal构成了OWL的内嵌数据类型,所有的OWL推理机都应支持xsd:integer和xsd:string数据类型。

    

<owl:Class rdf:ID="VintageYear"/>

<owl:DatatypeProperty rdf:ID="yearValue">
    <rdfs:domain rdfs:resource="#VintageYear"/>
    <rdfs:range rdf:resource="&xsd;positiveInteger"/>
</owl:DataTypeProperty>

     yearValue属性将VintageYear与一个整数值相关联,我们下面将引入hasVintageYear属性,将一个Vintage关联到一个VintageYear。

     3.2.3 个体的属性

     首先我们描述Region和Winery个体,然后我们定义第一个葡萄酒CabernetSauvignon:

    

 <Region rdf:ID="SantaCruzMountainsRegion">
   <locatedIn rdf:resource="#CaliforniaRegion" />
 </Region>

 <Winery rdf:ID="SantaCruzMountainVineyard" />

 <CabernetSauvignon rdf:ID="SantaCruzMountainVineyardCabernetSauvignon" >
   <locatedIn   rdf:resource="#SantaCruzMountainsRegion"/>  
   <hasMaker    rdf:resource="#SantaCruzMountainVineyard" />   
 </CabernetSauvignon>  

     我们描述一个VintageYear的实例,并将它关联到一个特定的&xsd;positiveInteger类型的值。

    

 <VintageYear rdf:ID="Year1998">
   <yearValue rdf:datatype="&xsd;positiveInteger">1998</yearValue>
 </VintageYear>

3.3 属性特性

     进一步说明属性的机制,我们可以对属性的特性进行详细的说明,这就提供了一种强有力的机制以增强对于一个属性的推理。

     3.3.1 TransitiveProperty(传递属性)

    

<owl:ObjectProperty rdf:ID="locatedIn">
    <rdf:type rdf:resource="&owl;TransitiveProperty"/>
    <rdfs:domain rdf:resource="&owl;Thing"/>
    <rdfs:range rdf:resource="#Region"/>
</owl:ObjectProperty>

<Region rdf:ID="SantaCruzMountainsRegion">
    <locatedIn rdf:resource="#CaliforniaRegion"/>
</Region>

<Region rdf:ID="CaliforniaRegion">
    <locatedIn rdf:resource="#USRegion"/>
</Region>

     因为圣克鲁斯山地区(SantaCruzMountaionsRegion)位于(locatedIn)加利福尼亚地区(CaliforniaRegion),那么它也位于(locatedIn)美国地区(USRegion),因为属性locatedIn是传递属性。

      3.3.2 SymmetricProperty(对称属性)

    

<owl:ObjectProperty rdf:ID="adjacentRegion">
    <rdf:type rdf:resource="&owl;SymmetricProperty"/>
    <rdf:domain rdf:resource="#Region"/>
    <rdf:range rdf:resource="#Region"/>
</owl:ObjectProperty>

<Region rdf:ID="MendocinoRegion">
    <locatedIn rdf:resource="#CaliforniaRegion"/>
    <adjacentRegion rdf:resource="#SonmaRegion"/>
</Region>

     MendocinoRegion地区与SonmaRegion地区相邻,反过来也是这样;

     MendocinoRegion地区位于CaliforniaRegion地区,但是反过来并不成立。

     3.3.3 FunctionalProperty(函数型属性)

    

<owl:Class rdf:ID="VintageYear"/>

<owl:ObjectProperty rdf:ID="hasVintageYear">
    <rdf:type rdf:resource="&owl;FunctionalProperty"/>
    <rdf:domain rdf:resource="#Vintage"/>
    <rdfs:range rdf:resource="#VintageYear"/>
</owl:ObjectProperty>

     在葡萄酒本体中,hasVintageYear属性是函数型属性,一种葡萄酒有着一个特定的制造年份,也就是说,一个给定的Vintage个体只能使用hasVintageYear属性与单独的一个年份相关联。owl:FunctionalProperty并不要求该属性的定义域的所有元素都有值。

     3.3.4 inverseOf(逆)

     如果一个属性P1被标记为属性P2的逆,那么对于所有的x和y:P1(x,y)当且仅当P2(y,x)。

    

<owl:ObjectProperty rdf:ID="hasMaker">
    <rdf:type rdf:resource="&owl;FunctionalProperty"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="producesWine">
    <owl:inverseOf rdf:resource="#hasMaker"/>
</owl:ObjectProperty>

     各个葡萄酒都有制造商,这些制造商在Wine类的定义中被限制为酿酒厂(Winery),而每一个酿酒厂生产的酒均以该酿酒厂为制造商。

     3.3.5 InverseFunctionalProperty

    

<owl:ObjectProperty rdf:ID="hasMaker"/>

<owl:ObjectProperty rdf:ID="producesWine">
    <rdf:type rdf:resource="&owl;InverseFunctionalProperty"/>
    <owl:inverseOf rdf:resource="#hasMaker"/>
</owl:ObjectProperty>

     因为一个函数型属性的逆必定是反函数型的,对于现在定义的hasMaker和producesWine属性和前例中效果是一样的。反函数型属性的值域中的元素可以看成是在数据库意义上定义一个唯一的键值。owl:InverseFunctional意味着属性的值域中的元素为定义域中的每个元素提供了一个唯一的标识。

3.4 属性限制

     除了能够指定属性特性,我们还可以用多种方法进一步在明确的上下文中限制属性的值域,这是通过属性限制完成的,而下面描述的多种形式仅在owl:Restriction的上下文中才能使用。owl:onProperty元素指出了受限制的属性。

     3.4.1 allValuesFrom, someValuesFrom

     到现在为止,我们所说的机制都是全局的,因为这些机制都会应用到属性的所有实例,而allValuesFrom和someValuesFrom仅仅在包含他们的类的定义中起作用。

     owl:allValuesFrom属性要求:对于每一个有指定属性实例的类实例,该属性的值必须是由owl:allValuesFrom从句指定的类的成员。

    

<owl:Class rdf:ID="Wine">
    <rdfs:subClassOf rdf:resource="&food;PotableLiquid"/>
    ......
    <rdfs:subClassOf>
        <owl:Restriction>
            <owl:onProperty rdf:resource="#hasMaker"/>
            <owl:allValuesFrom rdf:resource="#Winery"/>
        </owl:Restriction>
    </rdfs:subClassOf>
    ......
<owl:Class>

     Wine的制造商必须是Winery,allValuesFrom限制仅仅应用在Wine的hasMaker属性上,Cheese的制造商并不受这一局部限制的约束。

     owl:someValuesFrom限制与之相似,在上一个例子中,如果我们用owl:someValuesFrom代替owl:allValuesFrom,那就意味着至少有一个Wine类实例的hasMaker属性是指向一个Winery类的个体的。

    

<owl:Class rdf:ID="Wine">
    <rdfs:subClassOf rdf:resource="&food;PotableLiquid"/>
    ......
    <rdfs:subClassOf>
        <owl:Restriction>
            <owl:onProperty rdf:resource="#hasMaker"/>
            <owl:someValuesFrom rdf:resource="#Winery"/>
        </owl:Restriction>
    </rdfs:subClassOf>
    ......
<owl:Class>

      这两种限制形式间的不同是全程量词和存在量词间的不同,allValuesFrom含义是对于所有的葡萄酒,如果它们有制造商,那么所有的制造商都是酿酒厂;someValuesFrom是指对于所有的葡萄酒,它们中至少有一个的制造商是酿酒厂。

     3.4.2 基数限制

     基数约束都是关于最小基数所做出的断言,更为直接的方法是使用owl:cardinality,这一约束允许对一个关系中的元素数目做出精确的限制。

    

<owl:Class rdf:ID="Vintage">
    <rdfs:subClassOf>
        <owl:Restriction>
            <owl:onProperty rdf:resource="#hasVintageYear"/>
            <owl:cardinality rdf:datatype="&xsd;nonNegativeInteger">1
            </owl:cardinality>
        </owl:Restriction>
    </rdfs:subClassOf>
</owl:Class>

     hasVintageYear属性为一个函数型属性,也就意味着每个Vintage有至多一个VintageYear,而如果对Vintage类的hasVintageYear属性使用基数限制则是对其做出了更强的断言,它表明每个Vintage有恰好一个VintageYear。

     3.4.3 hasValue

    

<owl:Class rdf:ID="Burgundy">
    ......
    <rdfs:subClassOf>
        <owl:Restriction>
            <owl:onProperty rdf:resource="#hasSugar"/>
            <owl:hasValue rdf:resource="#Dry"/>
        </owl:Restriction>
    </rdfs:subClassOf>
</owl:Class>

     hasValue使得我们能够根据特定的属性值的存在来标识类,因此,一个个体只要至少有一个属性值等于hasValue的资源,这一个体就是该类的成员。这里我们声明了所有的Burgundy酒都是干(dry)的酒,也就是说,它们的hasSugar属性必须至少有个值是等于dry的。

     与allValuesFrom和someValuesFrom类似,是一个局部的限制,它仅仅对Burgundy类的hasSugar属性做出限制。

4.本体映射

     为了让本体发挥最大的作用,就需要让本体得到充分的共享,为了使得在开发本体时尽可能地节省人力,就需要使得开发出地本体能够被重用,最理想的情况是他们能够被组合使用,例如,你可能同时使用来自某一来源的日期本体和来自另一来源地物理位置本体,并将位置地概念加以扩展以包括这个位置所处在的时间段。

4.1 类和属性之间的等价关系

     当我们要把一些本体组合在一起作为另一个新的本体地一部分时,能说明在一个本体中的某个类或者属性与另一个本体中的某个类或者属性时等价的。

     我们在食物本体中定义一个类(&food;Wine),然后在葡萄酒本体中将一个已有的类声明为与这个类是等价的。

    

<owl:Class rdf:ID="Wine">
    <owl:equivalentClass rdf:resource="&vin;Wine"/>
</owl:Class>

     属性owl:equivalentClass被用来表示两个类有着完全相同的实例,但是我们要注意,在OWL DL中,类仅仅代表着个体的集合而不是个体本身,然而在OWL FULL中,我们能够使用owl:sameAs来表示两个类在各方面均完全一致。

    

<owl:Class rdf:ID="TexasThings">
    <owl:equivalentClass>
        <owl:Restriction>
            <owl:onProperty rdf:resource="#locatedIn"/>
            <owl:someValuesFrom rdf:resource="#TexasRegion"/>
        </owl:Restrction>
    </owl:equivalentClass>
</owl:Class>

     TexasThings指的是那些恰好位于Texas地区地事物,使用owl:equivalentClass和使用rdfs:subClassOf的不同就像必要条件和充要条件的不同一样。如果是使用subClassOf的话,位于Texas地区的事物不一定是TexasThings,但是,如果使用owl:equivalentClass,那么位于Texas地区的事物一定属于TexasThings类。

4.2个体间的同一性

     sameAs描述个体间相同的机制与描述类之间的相同的机制类似,仅仅只要将两个个体声明成一致的就可以了。

    

<Wine rdf:ID="MikesFavoriteWine">
    <owl:sameAs rdf:resource="#StGenevieveTexasWhite"/>
</Wine>

     修饰(或引用)两个类用sameAs还是用equivalentClass效果是不同的,用sameAs时,把一个类解释为一个个体,这有利于对本体进行分类。在OWL Full中,sameAs可以用来引用两个东西,如一个类和一个个体、一个类和一个属性等等,无论什么情况,都将被解释为个体。

4.3 不同的个体

    

<WineSugar rdf:ID="Dry">
 
<WineSugar rdf:ID="Sweet">
    <owl:differentFrom rdf:resource="#Dry"/>
</WineSugar>

<WineSugar rdf:ID="OffDry">
    <owl:differentFrom rdf:resource="#Dry"/>
    <owl:differentFrom rdf:resource="#Sweet"/>
</WineSugar>

     这是一种声明这三个值相互不同的方法,但有些时候,更重要的是利用这些定义元素能把这种不同区别开来。没有上述的定义元素,我们可能会定义一种既干又甜的葡萄酒,并且添加hasSugar属性使其取值小于等于某个值来限定该种葡萄酒的甜度。如果我们没有用differentFrom元素来声明既干又甜的葡萄酒,这意味着干葡萄酒和甜葡萄酒是相同的,但是我们从上面声明的元素来推断,这又是矛盾的。还有一种更便利的定义相互不同的个体的机制,例如:

    

<owl:AllDifferent>
    <owl:distinctMembers rdf:parseType="Collection">
        <vin:WineColor rdf:about="#Red"/>
        <vin:WineColor rdf:about="#White"/>
        <vin:WineColor rdf:about="#Rose"/>
    </owl:distinctMembers>
</owl:AllDifferent>

     owl:distinctMembers属性声明只能和owl:AllDifferent属性声明一起结合使用,

5.复杂类

5.1集合运算符

     OWL类外延是由个体组成的集合,而这些个体都是类的成员,OWL使用基本的集合操作算子来处理类的外延。

     5.1.1 交运算

    

<owl:Class rdf:ID="WhiteWine">
    <owl:intersectionOf rdf:parseType="Collection">
        <owl:Class rdf:about="#Wine"/>
        <owl:Restriction>
            <owl:onProperty rdf:resource="#hasColor"/>
            <owl:hasValue rdf:resource="#White"/>
        </owl:Restriction>
    </owl:intersectionOf>
</owl:Class>

     类的成员完全是通过集合操作来说明的,上面的语句说明WhiteWine恰好是类Wine与所有颜色是白色的事物的集合的交集,这就意味着如果某一事物是白色的并且是葡萄酒,那么它就是WhiteWine的实例。

    

<owl:Class rdf:about="#Burgundy">
    <owl:intersectionOf rdf:parseType="Collection">
        <owl:Class rdf:about="#Wine"/>
        <owl:Restriction>
            <owl:onProperty rdf:resource="#locatedIn"/>
            <owl:hasValue rdf:resource="BourgogneRegion"/>
        </owlRestriction>
    </owl:intersectionOf>
</owl:Class>

     在这里我们定义了Burgundy类,这个类包含了那些至少有一个locatedIn关系,而同时这一关系又要联系到Bourgogne地区的葡萄酒。

     WhiteBurgundy类恰好是白葡萄酒和Burgundies的交集,所有满足这些标准的葡萄酒个体都是WhiteBurgundy类的外延的一部分:

    

<owl:Class rdf:ID="WhiteBurgundy">
    <owl:intersectionOf rdf:parseType="Collection">
        <owl:Class rdf:about="#Burgundy"/>
        <owl:Class rdf:about="#WhiteWine"/>
    </owl:intersectionOf>
</owl:Class>

     5.1.2 并运算

    

<owl:Class rdf:ID="Fruit">
   <owl:unionOf rdf:parseType="Collection">
     <owl:Class rdf:about="#SweetFruit" />
     <owl:Class rdf:about="#NonSweetFruit" />
   </owl:unionOf>
 </owl:Class>

     Fruit类既包含了SweetFruit类的外延也包含了NonSweetFruit类的外延,我们可以看一下这种并集类型的结构与下面这个结构是多么的不同(在下面这个例子中,Fruit的实例是SweetFruit和NonSweetFruit的交集的子集,这里我们将得到一个空集):

    

 <owl:Class rdf:ID="Fruit">
   <rdfs:subClassOf rdf:resource="#SweetFruit" />
   <rdfs:subClassOf rdf:resource="#NonSweetFruit" />
 </owl:Class>

     5.1.3 补运算

     complementOf结构是从某个论域选出不属于某个类的所有个体,通常它将指向一个非常大的个体集合。

    

<owl:Class rdf:ID="ConsumableThing"/>

<owl:Class rdf:ID="NonConsumableThing">
    <owl:complementOf rdf:resource="#ConsumableThing"/>
</owl:Class>

    类NonConsumableThing包含了所有不属于ConsumableThing的外延的个体,它实际上是owl:Thing与ConsumableThing的这两个集合的集合差。因此,complementOf典型的用法就是与其他集合运算符联合使用。这个例子中定义了一个NonFrenchWine类,它是Wine类与所有不位于法国的事物的集合的交集。

    

<owl:Class rdf:ID="NonFrenchWine">
    <owl:intersectionOf rdf:parseType="Collection">
        <owl:Class rdf:about="#Wine">
        <owl:Class>
            <owl:complementOf>
                <owl:Restriction>
                    <owl:onProperty rdf:resource="#locatedIn"/>
                    <owl:hasValue rdf:resource="#FrenchRegion"/>
                </owl:Restriction>
            </owl:complementOf>
        </owl:Class>
    </owl:intersectionOf>
</owl:Class>

5.2 枚举类

     OWL提供了一种通过直接枚举类的成员的方法来描述类,这是通过oneOf结构来完成的,这个定义完整地描述了类的外延,因此任何其他个体都不能被声明为属于这个类。

    

<owl:Class rdf:ID="WineColor">
    <rdfs:subClassOf rdf:resource="#WineDescriptor"/>
    <owl:oneOf rdf:parseType="Collection">
        <owl:Thing rdf:about="#White"/>
        <owl:Thing rdf:about="#Rose"/>
        <owl:Thing rdf:about="#Red"/>
    </owl:oneOf>
</owl:Class>

     在上面的定义中,通过枚举定义了WineColor类,成员是White、Rose、Red这三个个体,因此其他任何一个个体都不可能是一个有效的WineColor。oneOf结构的每一个元素都必须是一个有效声明的个体,一个个体必须属于类。在上面这个例子中,每一个个体都是通过名字来引用的,我们可以使用owl:Thing简单的进行引用,也可以根据具体类型Winecolor来引用集合中的元素。

    

<owl:Class rdf:ID="WineColor">
    <rdfs:subClassOf rdf:resource="#WineDescriptor"/>
    <owl:oneOf rdf:parseType="Collection">
        <WineColor rdf:about="#White"/>
        <WineColor rdf:about="#Rose"/>
        <WineColor rdf:about="#Red"/>
    </owl:oneOf>
</owl:Class>

     另外,较复杂的个体描述同样也可以是oneOf结构的有效元素,例如:

    

<WineColor rdf:about="#White">
    <rdfs:label>White</rdfs:label>
</WineColor>

5.3 不相交类

    

<owl:Class rdf:ID="Pasta">
    <rdfs:subClassOf rdf:resource="#EdibleThing"/>
    <owl:disjointWith rdf:resource="#Meat"/>
    <owl:disjointWith rdf:resource="#Fowl"/>
    <owl:disjointWith rdf:resource="#Seafood"/>
    <owl:disjointWith rdf:resource="#Dessert"/>
    <owl:disjointWith rdf:resource="#Fruit"/>
</owl:Class>

     Pasta类中声明了多个不相交的类,注意它只声明了Pasta与其他所有类是不相交的,它并没有保证Meat和Fruit是不相交的。

     一个常见的需求是定义一个类为一组互不相交的子类的联合:

    

<owl:Class rdf:ID="SweetFruit">
    <rdfs:subClassOf rdf:resource="#EdibleThing"/>
</owl:Class>

<owl:Class rdf:ID="NonSweetFruit">
    <rdfs:subClassOf rdf:resource="#EdibleThing"/>
    <owl:disjointWith rdf:resource="#SweetFruit"/>
</owl:Class>

<owl:Class rdf:ID="Fruit">
    <owl:unionOf rdf:parseType="Collection">
        <owl:Class rdf:about="#SweetFruit"/>
        <owl:Class rdf:about="#NonSweetFruit"/>
    </owl:unionOf>
</owl:Class>

6.本体的版本控制

      本体和软件一样需要维护,因此它们将随着时间的推移而改变,属性owl:priorVersion用来跟踪一个本体的版本历史。本体版本可能彼此互不相容,例如,在一个本体以前的版本中可能包含与现在版本中的陈述相矛盾的陈述。

    

<owl:Ontology rdf:about="">
    ......
    <owl:priorVersion rdf:resource="http://www.w3.org/TR/2003/CR-owl-guide-20030818/wine"/>
</owl:Ontology>

 

参考文献:1. http://www.transwiki.org/cn/owlguide.htm

     2.https://www.jianshu.com/p/9e2bfa9a5a06

posted @ 2020-03-29 17:49  飞鸟迷失天空  阅读(1871)  评论(0编辑  收藏  举报