Ontology理論研究和應用建模


此為幾年前剛開始學本體時查到的資料,目前感覺還是有參考作用

作者未知
《Ontology研究綜述》、w3c Ontology研究組文檔以及Jena編程應用總結

其中代碼僅供參考。Jena已為Apache項目,版本已更新

目錄

1 關於Ontology

1.1 Ontology的定義

Ontology最早是一個哲學的范疇,后來隨着人工智能的發展,被人工智能界給予了新的定義。然后最初人們對Ontology的理解並不完善,這些定義也出在不斷的發展變化中,比較有代表性的定義列表如下:

范疇 提出時間/提出人 定義
哲學 客觀存在的一個系統的解釋和說明,客觀現實的一個抽象本質
計算機 1991/Neches等 給出構成相關領域詞匯的基本術語和關系,以及利用這些術語和關系構成的規定這些詞匯外延的規則的定義
1993/Gruber 概念模型的明確的規范說明
1997/Borst 共享概念模型的形式化規范說明
1998/Studer 共享概念模型的明確的形式化規范說明

關於最后一個定義的說明體現了Ontology的四層含義:

  • 概念模型(cerptualization)

通過抽象出客觀世界中一些現象(Phenomenon)的相關概念而得到的模型,其表示的含義獨立於具體的環境狀態

  • 明確(explicit)

所使用的概念及使用這些概念的約束都有明確的定義

  • 形式化(formal)

Ontology是計算機可讀的。

  • 共享(share)

Ontology中體現的是共同認可的知識,反映的是相關領域中公認的概念集,它所針對的是團體而不是個體。

Ontology的目標是捕獲相關的領域的知識,提供對該領域知識的共同理解,確定該領域內共同認可的詞匯,並從不同層次的形式化模式上給出這些詞匯(術語)和詞匯之間相互關系的明確定義。

1.2 Ontology的建模元語

Perez等人用分類法組織了Ontology,歸納出5個基本的建模元語(Modeling Primitives):

  • (classes)或概念(concepts)指任何事務,如工作描述、功能、行為、策略和推理過程。從語義上講,它表示的是對象的集合,其定義一般采用框架(frame)結構,包括概念的名稱,與其他概念之間的關系的集合,以及用自然語言對概念的描述。

  • 關系(relations)在領域中概念之間的交互作用,形式上定義為n維笛卡兒積的子集:R:C1×C2×…×Cn。如子類關系(subclass-of)。在語義上關系對應於對象元組的集合。

  • 函數(functions)一類特殊的關系。該關系的前n-1個元素可以唯一決定第n個元素。形式化的定義為F:C1×C2×…×Cn-1→Cn。如Mother-of就是一個函數,mother-of(x,y)表示y是x的母親。

  • 公理(axioms)代表永真斷言,如概念乙屬於概念甲的范圍。

  • 實例(instances)代表元素。從語義上講實例表示的就是對象。

另外,從語義上講,基本的關系共有4種:

關系名 關系描述
part-of 表達概念之間部分與整體的關系。
kind-of 表達概念之間的繼承關系,類似於面向對象中的父類與子類之間的關系。
instance-of 表達概念的實例與概念之間的關系,類似於面向對象中的對象和類之間的關系。
attribute-of 表達某個概念是另一個概念的屬性。如“價格”是桌子的一個屬性。

在實際建模過程中,概念之間的關系不限於上面列出的4種基本關系,可以根據領域的具體情況定義相應的關系。

1.3 Ontology和語義網絡

Ontology和語義網絡的聯系和區別列表如下:

  • 聯系:它們都是知識表示的形式,均可以通過帶標記的有向圖來表示,適合於邏輯推理。
  • 區別
比較方面 Ontology 語義網絡
描述的對象和范圍 是對共享概念模型的規范說明,即其概念在某個特定領域是公認的,是面向特定領域的概念模型。 從數學上講是一種帶有標記的有向圖,最初用於表示命題信息,現廣泛用於專家系統表示知識。其節點表示物理實體、概念或狀態,邊用於表示關系,但是對節點和邊都沒有特殊規定,所以描述的范圍比Ontology廣。
表示的深度上 有5個要素“元語,類,關系,函數,公理和實例”,它通過這5個要素來嚴格、正確地刻畫所描述的對象。 深度上不如Ontology,對建模沒有特殊要求。
建模條件 建立必須有專家的參與,相對更加嚴格和困難,這也是Ontology目前的主要缺點之一。 不必有專家的參與。

【例子】:語義網絡中可以表達“我的汽車是紅色的”,而Ontology則適合表達如“團體組織的內部構成”等整體內容。

1.4 Ontology的描述語言

目前在具體應用中Ontology的表示方式主要有4類:

  • 非形式化語言
  • 半非形式化語言
  • 半形式化語言
  • 形式化語言

可以用自然語言來描述Ontology,也可以用框架語義網絡邏輯語言來描述。

目前普遍使用的方法列表如下:

名稱 描述 特點
Ontolingua 一種基於KIF(knowledge interchange format)的提供統一的規范格式來構建Ontology的語言。 ü 為構造和維護Ontology提供了統一的、計算機可讀的方式;ü 由其構造的Ontology可以方便地轉換到各種知識表示和推理系統(Prolog、CORBA的IDL、CLIPS、LOOM、Epikit、Algernon和KIF),從而將Ontology的維護與使用它的目標系統隔開;ü 主要用於Ontology服務器。
CycL Cyc系統的描述語言,一種體系龐大而非常靈活的知識描述語言。 ü 在一階謂詞演算的基礎上擴充了等價推理、缺省推理等功能;ü 具備一些二階謂詞演算的能力;ü 其語言環境中配有功能很強的可進行推理的推理機。
Loom Ontosaurus的描述語言,一種基於一階謂詞邏輯的高級編程語言,屬於描述邏輯體系。后來發展為PowrLoom語言(采用前后鏈規則(backward and forward chainer)作為推理機制)。 ü 提供表達能力強、聲明性的規范說明語言;ü 提供強大的演繹推理能力;ü 提供多種編程風格和知識庫服務。

1.5 已有的Ontology及其分類

目前廣泛使用的Ontology列表如下:

名稱 描述
Wordnet 基於心理語言規則的英文詞典,以synsets(在特定的上下文環境中可互換的同義詞的集合)為單位組織信息。
Framenet 英文詞典,采用稱為Frame Semantics的描述框架,提供很強的語義分析能力,目前發展為FramenetII。
GUM 面向自然語言處理,支持多語種處理,包括基本概念及獨立於各種具體語言的概念組織方式。
SENSUS 面向自然語言處理,為機器翻譯提供概念結構,包括7萬多概念。
Mikrokmos 面向自然語言處理,支持多語種處理,采用一種語言中間的中間語言TMR表示知識。

Guarino提出以詳細程度和領域依賴度兩個維度對Ontology進行划分。具體說明如下:

維度 說明 分類級別
詳細程度 描述或刻畫建模對象的程度 高的稱作參考(Reference)Ontologies
低的稱作共享(share)Ontologies
領域依賴程度 頂級(top-level)Ontologies描述的是最普遍的概念及概念之間的關系,如空間、時間、事件、行為等,與具體的應用無關,其他Ontologies均為其特例。
領域(domain)Ontologies描述的是特定領域中的概念和概念之間的關系。
任務(task)Ontologies描述的是特定任務或行為中的概念及概念之間的關系。
應用(application)Ontologies描述的是依賴於特定領域和任務的概念和概念之間的關系。

1999年Perez和Benjamins歸納出了10種Ontologies:

  • 知識表示Ontologies
  • 普通Ontologies
  • 頂級Ontologies
  • 元(核心)Ontologies
  • 領域Ontologies
  • 語言Ontologies
  • 任務Ontologies
  • 領域-任務Ontologies
  • 方法Ontologies
  • 應用Ontologies

但它們之間有交叉,層次不夠清晰。

1.6 構造Ontology的規則

出於對各自問題域和具體工程的考慮,構造Ontology的過程各不相同。目前沒有一個標准的Ontology的構造方法。最有影響的是Gruber在1995年提出的5條規則:

  • 明確性和客觀性:Ontology應該用自然語言對所定義的術語給出明確、客觀的語義定義。
  • 完全性:所給出的定義是完整的,完全能表達所描述的術語的含義。
  • 一致性:由術語得出的推論與術語本身的含義是相容的,不會產生矛盾。
  • 最大單調可擴展性:向Ontology中添加通用或專用的術語時,不需要修改已有的內容。
  • 最小承諾:對待建模對象給出盡可能少的約束。

目前大家公認在構造特定領域的Ontology的過程中需要領域專家的參與。

2 Ontology的研究和應用

Ontology的研究和應用主要包括以下3方面:

  • 理論上的研究,主要研究概念及其分類,Ontology上的代數;
  • 信息系統中的應用,主要包括處理信息組織、信息檢索和異構信息系統互操作問題;
  • Ontology作為一種能在知識層提供知識共享和重用的工具在語義Web中的應用。

2.1 Ontology的理論研究

Ontology的理論研究包括概念和概念分類、Ontology上的代數。最有代表性的是Guarino等人對概念的分類所做的深入和細致的研究,他們從一般的意義上分析了什么是概念、概念的特性、概念之間的關系以及概念的分類,提出了一套用於指導概念分類的可行理論。基於這個理論,他又提出了Ontology驅動的建模方法,在理論上為建模提供了一個通用的模式。

Guarino認為概念之間的差別不僅體現在概念的定義上,同時也體現在概念的某些特性上。從這些特性出發,歸納出概念的元特性(最基本的特性),從而用公式給出元特性的嚴格的形式定義。在此基礎上,他們又討論了元特性之間的關系和約束,最終把研究結果作為概念分類的基本理論工具並提出一套完成的概念分類體系結構。

Guarino的理論可以歸納如下:

概念分類理論的基礎是概念的元特性。以概念的元特性為出發點,按照一定的規則,把具有相同元特性組合的概念歸為一類,進而給出一般意義上的概念分類體系。概念的基本元特性包括:持久特性、非持久特性、反持久特性、半持久特性、載體標識特性、支持標識特性、外部依賴特性等。

以下是對各種特性的說明:

名稱 描述 舉例
持久特性 嚴格定義為:![img](file:///C:\Users\HOUZHI1\AppData\Local\Temp\ksohtml\wps47F3.tmp.png)。![img](file:///C:\Users\HOUZHI1\AppData\Local\Temp\ksohtml\wps47F4.tmp.png)代表某個概念,![img](file:///C:\Users\HOUZHI1\AppData\Local\Temp\ksohtml\wps4804.tmp.png)代表x是![img](file:///C:\Users\HOUZHI1\AppData\Local\Temp\ksohtml\wps4805.tmp.png)的一個實例,![img](file:///C:\Users\HOUZHI~1\AppData\Local\Temp\ksohtml\wps4806.tmp.png)表示其后的斷言永遠為真。 Person具有持久性,而Student不具有持久性。
非持久特性 對某個概念而言,存在某些實例不會永遠屬於該概念。 Student具有非持久性。
反持久特性 對概念的任何一個實例,這個實例不會永遠屬於該概念。 Youth具有反持久性。
半持久特性 非持久性和反持久性的差集。 ——
載體標識特性 —— 如Student具有載體標識特性,因為學生之間的區別不是靠學生,而是作為人來區分的。
支持標識特性 每個實例相互之間是可以區分的。 Person具有支持標識特性,人和人之間可由標識(人的指紋)來區分。
外部依賴特性 一個概念對另外一個概念的某種依賴關系。概念A對概念B的外在依賴關系表現為概念A中的任何一個實例a必蘊涵屬於概念B的實例b,而b不是a的一部分。 Parent外在依賴於Child,某人的父母蘊涵他(她)有小孩,而他的小孩當然不是他身體的一部分。

2.2 Ontology在信息系統中的應用

目前信息檢索技術的分類和對他們的描述列舉如下:

分類 特點 缺點
全文(Text retrieval) 把用戶的查詢請求和全文中的每一個詞進行比較,不考慮查詢請求和文件語義上的匹配。 雖然可以保證查全率,但是查准率大大降低。
數據(Data retrieval) 查詢要求和信息系統中的數據都遵循一定的格式,具有一定的結構,允許對特定字段檢索。需要有標識字段的方法。 性能取決於所使用的字段標識方法和用戶對方法的理解,具有很大的局限性,支持語義匹配的能力較差。
知識(Knowledge retrieval) 基於知識的、語義上的匹配,在查准率和查全率上有更好的保證。是信息檢索的重點,特別是面向Web信息的知識檢索的重點。 ——

Ontology具有良好的概念層次結構和對邏輯推理的支持,在知識檢索中有廣泛應用。基於Ontology的信息檢索的基本思想有:

  • 在領域專家的幫助下,建立相關領域的Ontology;
  • 收集信息源中的數據,並參照已建立的Ontology把收集來的數據按規定格式存儲在元數據庫(RDB,KDB等)中;
  • 對用戶檢索界面獲取的查詢請求,查詢轉換器按照Ontology把查詢請求轉換成規定的格式,在Ontology的幫助下從元數據庫中匹配出符合條件的數據集合;
  • 檢索的結果經過定制處理返回給用戶。

關於Ontology的表達,主要分為兩種情況進行處理:

  • 檢索系統如不需要太強的推理能力,Ontology可用概念圖的形式表示並存儲,數據可以保存在一般的關系數據庫中,采用圖匹配技術完成檢索;
  • 如要求較強的推理能力,一般需要一種描述語言(Loom等)表示Ontology,數據保存在知識庫中,采用描述語言的邏輯推理能力完成檢索。

目前Ontology用於信息檢索的項目列舉如下:

項目名稱 說明
(Onto)2Agent 為了幫助用戶檢索所需要的WWW上已有的Ontology,主要采用參照Ontology,即以WWW上已有的Ontology為對象建立起來的Ontology,保存各類Ontology的元數據。
Ontobroker 面向WWW上的網頁資源,目的是幫助用戶檢索所需的網頁,這些網頁含有用戶關心的內容。
SKC 解決信息系統語義異構的問題,實現異構的自治系統間的互操作。希望通過在Ontology上的一個代數系統來實現Ontology之間的互操作,從而實現異構系統之間的互操作。

2.3 Ontology和語義Web

提高Web信息檢索的質量包括兩方面的內容:

  • 如何在現有的資源上面設計更好的檢索技術;
  • 如何為Web上的資源附加上計算機可以理解的內容,便於計算機處理,即給出一種計算機能夠理解的表示資源的手段。

基於后一種考慮,Berners-Lee在2000-12-18的XML2000的會議上提出了語義Web。語義Web的目標是使得Web上的信息具有計算機可以理解的語義,滿足智能軟件代理(Agent)對WWW上異構和分布信息的有效訪問和檢索。下面是Berners-Lee為未來Web發展提出的基於語義的體系結構-語義Web體系結構

![img](file:///C:\Users\HOUZHI~1\AppData\Local\Temp\ksohtml\wps4807.tmp.png) 層數 名稱 描述
第一層 UNICODE和URI 整個語義網絡的基礎,Unicode處理資源的編碼,URI負責標識資源。
第二層 XML+NS+xmlschema 用於表示數據的內容和結構。
第三層 RDF+rdfschema 用於描述Web上的資源及其類型。
第四層 Ontology vocabulary 用於描述各種資源之間的聯系。
第五層 Logic 在下面四層的基礎上進行的邏輯推理操作。
第六層 Proof
第七層 Trust

* 核心層,用於表示Web信息的語義。

​ XML和RDF都能為所表述的資源提供一定的語義。但是XML中的標簽(tags)和RDF中的屬性(properties)集都沒有任何限制。一個例子是:XML可以用“<Author>TOM</Author>”表示TOM是教師。而“<rdf:Description about=http://www.w3.org/Home/Lassila><s:Creator>Ora Lassila</s:Creator></rdf:Description> ”這個RDF片斷描述了Web頁的創建者問題。而上面的Author和Creator完全可以用Writer來代替。另一個例子是:某醫院和某大學的Web頁上都有<Doctor>,但是不知道它代表醫生還是博士。綜上,XML和RDF在處理語義上存在的問題是:

  • 同一概念有多種詞匯表示(多詞同義);
  • 同一個詞匯有多種概念(含義)(一詞多義)。

Ontology通過對概念的嚴格定義和概念之間的關系來確定概念精確含義,表示共同認可的、可共享的知識,從而解決上面的問題。因此在語義Web中,Ontology具有非常重要的地位,是解決語義層次上Web信息共享和交換的基礎

為了便於Web上應用程序使用方便,需要有一個通用的標准語言來表示Ontology,就像XML作為標准的數據交換語言一樣。目前正在開發中的語言有:SHOE、OML、XOL、Riboweb、RDFS和OIL。下面將就w3c提出的OWL(Web Ontology Language)做進一步的分析。

目前語義Web是一個新興的研究方向,Ontology在其中的應用剛剛起步。

3 Web Ontology Language (OWL)概述

3.1 OWL簡介

OWL(Web Ontology Language)適用於這樣的應用,在這些應用中,不僅僅需要提供給用戶可讀的文檔內容,而且希望處理文檔內容信息。OWL能夠被用於清晰地表達詞匯表中的詞條(term)的含義以及這些詞條之間的關系。而這種對詞條和它們之間的關系的表達就稱作Ontology。OWL相對XML、RDF和RDFSchema擁有更多的機制來表達語義,從而OWL超越了XML、RDF和RDFSchema僅僅能夠表達網上機器可讀的文檔內容的能力。

3.2 OWL在語義網中的地位

語義網是對未來網絡的一個設想,在這樣的網絡中,信息都被賦予了明確的含義,機器能夠自動地處理和集成網上可用的信息。語義網使用XML來定義定制的標簽格式以及用RDF的靈活性來表達數據,下一步需要的就是一種Ontology的網絡語言(比如OWL)來描述網絡文檔中的術語的明確含義和它們之間的關系。

OWL是w3c推薦的語義網絡“棧”中的一部分,這個“棧”被表達如下:

名稱 描述
XML 結構化文檔的表層語法,對文檔沒有任何語義約束。
XML Schema 定義XML文檔的結構約束的語言。
RDF 對象(或者資源)以及它們之間關系的數據模型,為數據模型提供了簡單的語義,這些數據模型能夠用XML語法進行表達。
RDF Schema 描述RDF資源的的屬性和類型的詞匯表,提供了對這些屬性和類型的普遍層次的語義。
OWL 添加了更多的用於描述屬性和類型的詞匯,例如類型之間的不相交性(disjointness),基數(cardinality),等價性,屬性的更豐富的類型,屬性特征(例如對稱性,symmetry),以及枚舉類型(enumerated classes)。

下圖給出了w3c的Ontology語言棧描述:

W3C2002年7月31日透露了發行OWL Web 本體論語言(OWL Web Ontology Language) 工作草案的細節,其目的是為了更好地開發語義網(Semantic Web)。

W3C 發言人Ian Jacobs說,開發語義網的目的是能夠在互聯網上進行更結構化的智能處理,例如,當一個人確定要參加某個城市的會議后,就可以自動查找有關航班和酒店的信息。

W3C稱,W3C Web 本體論工作小組正在對OWL Web本體論語言進行設計,OWL是本體論Web 語言(Ontology Web Language)的字母縮寫。設計的最終目的是為了提供一種可以用於各種應用的語言,這些應用需要理解內容,從而代替只是采用人類易讀的形式來表達內容。作為語義網的一部分,XML、RDF和RDF-S支持通過提供針對術語描述的詞匯表,共同推進了機器的可靠性。

W3C發行的三種工作草案名為《特色大綱》(Web Ontology Language (OWL) Guide Version 1_0)、《抽象句法》(OWL Web Ontology Language 1_0 Abstract Syntax)和《語言參考》。

W3C本周還發行了其Web 服務架構使用方案集合的工作草案,目的是為下一代的Web服務提供使用案例和方案。

W3C Web服務架構工作小組特別發行的方案包括諸如旅行社使用案例和類似電子數據交換的采購等情形。Jacobs說:“W3C官員正在制定有關Web服務架構范圍的文件。”

3.3 OWL的三個子語言——OWL LiteOWL DLOWL Full

3.3.1 子語言描述

OWL的三個子語言描述列表如下:

子語言 描述 例子
OWL Lite 用於提供給那些只需要一個分類層次和簡單的屬性約束的用戶。 支持基數(cardinality),只允許基數為0或1。
OWL DL 支持那些需要在推理系統上進行最大程度表達的用戶,這里的推理系統能夠保證計算完全性(computational completeness,即所有地結論都能夠保證被計算出來)和可決定性(decidability,即所有的計算都在有限的時間內完成)。它包括了OWL語言的所有約束,但是可以被僅僅置於特定的約束下。 當一個類可以是多個類的一個子類時,它被約束不能是另外一個類的實例。
OWL Full 支持那些需要在沒有計算保證的語法自由的RDF上進行最大程度表達的用戶。它允許在一個Ontology在預定義的(RDF、OWL)詞匯表上增加詞匯,從而任何推理軟件均不能支持OWL FULL的所有feature。 一個類可以被同時表達為許多個體的一個集合以及這個集合中的一個個體。

3.3.2 子語言間以及子語言和RDF的關系

這三種子語言之間的關系是:

  • 每個合法的OWL Lite都是一個合法的OWL DL;

  • 每個合法的OWL DL都是一個合法的OWL Full;

  • 每個有效的OWL Lite結論都是一個有效的OWL DL結論;

  • 每個有效的OWL DL結論都是一個有效的OWL Full結論。

用戶在選擇使用哪種語言時的主要考慮是:

  • 選擇OWL Lite還是OWL DL主要取決於用戶需要整個語言在多大程度上給出了約束的可表達性;

  • 選擇OWL DL還是OWL Full主要取決於用戶在多大程度上需要RDF的元模型機制(如定義類型的類型以及為類型賦予屬性);

  • 在使用OWL Full而不是OWL DL時,推理的支持不可預測,因為目前還沒有完全的OWL Full的實現。

這三種子語言與RDF的關系是:

  • OWL Full可以看成是RDF的擴展;

  • OWL Lite和OWL Full可以看成是一個約束化的RDF的擴展;

  • 所有的OWL文檔(Lite,DL,Full)都是一個RDF文檔;

  • 所有的RDF文檔都是一個OWL Full文檔;

  • 只有一些RDF文檔是一個合法的OWL Lite和OWL DL文檔。

3.4 OWL語言大綱

【說明】:以下用斜體標出的為OWL中的詞條(term),rdf:和rdfs:前綴表示這些詞條已經在RDF和RDF Schema中出現。

3.4.1 OWL Lite語言大綱

分類 詞條
RDF Schema Features · Class · rdf:Property · rdfs:subClassOf · rdfs:subPropertyOf · rdfs:domain · rdfs:range · Individual
(In)Equality · equivalentClass · equivalentProperty · sameIndividualAs · differentFrom · allDifferent
Property Characteristics · inverseOf · TransitiveProperty · SymmetricProperty · FunctionalProperty · InverseFunctionalProperty
Property Type Restrictions · allValuesFrom · someValuesFrom
Restricted Cardinality · minCardinality (only 0 or 1) · maxCardinality (only 0 or 1) · cardinality (only 0 or 1)
Header Information · imports · versionInfo · priorVersion · backwardCompatibleWith · incompatibleWith
Class Intersection · intersectionOf
Datatypes

3.4.2 OWL DL和OWL Full大綱

下面給出了在OWL Lite基礎上添加的OWL DL和OWL Full語言架構

分類 詞條
Class Axioms · oneOf · disjointWith · equivalentClass (applied to class expressions) · rdfs:subClassOf (applied to class expressions)
Boolean Combinations of Class Expressions · unionOf · intersectionOf · complementOf
Arbitrary Cardinality · minCardinality · maxCardinality · cardinality
Filler Information · hasValue

3.5 OWL Lite語言描述

和OWL DL和OWL Full相比,OWL Lite只是使用了OWL語言的一些feature,並且做了限制。

  • Class只能根據命名了的superclass(它不能是任意的邏輯表達式)進行定義,而且只能使用特定類型的class restriction。

  • 類之間的Equivalence以及子類關系只能在命名了的class上做聲明,不能應用於任意的類型表達式。

  • OWL Lite只允許屬性限制應用於命名類型。

  • OWL Lite對cardinality的概念也有限制——它的取值范圍只能是0和1。

以下列出了OWL Lite大綱中各類feature的描述。

3.5.1 OWL Lite RDF Schema Features

名稱 描述 實例
Class 定義了一組共享了某些相同屬性的individual。Class能夠通過subClassOf定義出一個特定的類層次。有一個內置的公共類Thing,它是所有individual的Class,也是所有Class的superclass。 Deborah 和Frank都是Person這個Class的成員。
rdfs:subClassOf 類層次可以通過給出諸如一個類是另一個或多個類的子類這樣的聲明來創建。 Person可以被定義為是Mammal的一個subclass,這樣我們就能夠推斷:如果X是一個Person,那么X一定也是一個Mammal。
Rdfs:Property 表達了individual之間的關系。 例如hasChild,hasRelative,,hasSibling,和hasAge都是Property的例子。前三個例子用於表達Person之間的關系,最后一個把一個Person和一個Datatype Integer關聯起來。
rdfs:subPropertyOf 屬性層次可以通過給出諸如一個屬性是另一個或多個屬性的子屬性這樣的聲明來創建。 hasSibling是hasRelative的子屬性。通過這一點我們就可以推理出:如果X和Y通過hasSibling進行了關聯,那么它們一定也通過hasRelative進行了關聯。
rdfs:domain 一個property的domain是能夠應用該property的individual的集合。如果property P把class X和class Y關聯起來,P的domain是class Z,那么X一定是Z的一個實例。Domain是一個全局約束,因為它就property而言,但是當它與一個特定的class關聯時也不只是就property而言。 Property hasChild可以被說擁有domain Mammal,從這一點我們就能夠推理出如果Frank hasChild Anna,那么Frank一定是一個Mammal。
rdfs:range 一個property的range是該property所必須有的值的individual的集合。如果proerty P將class X和class Y關聯,P的range是class Z,那么Y一定是Z的一個實例。 Property hasChild可以被說擁有range Mammal,從這一點我們就能夠推理出如果Louise hasChild Deborah,那么Deborah一定是一個Mammal。
Individual Class的實例,property可以被用來把一個individual和另一個individual關聯起來。 一個名叫Deborah的individual可以被描述為是Person這個class的實例,而property hasEmployer可以把individual Deborah和individual StanfordUniversity關聯起來。

3.5.2 OWL Lite Equality 和Inequality

名稱 描述 實例
equivalentClass 兩個類可以被聲明為相同,即它們擁有不同的名字但是卻擁有相同的individual的集合。它被用來創建同義類。 Car可以被說成是Automobile的equivalentClass。從這一點我們能推理得到任何Car的實例都是Automobile的實例,反之也一樣。
equivalentProperty 兩個類也可以被聲明為相同。它可以被用來創建同義屬性。 HasLeader可以被說成是hasHead的equivalentProperty。從這一點我們能夠推理得到:如果X通過HasLeader與Y關聯,那么X也通過hasHead與Y關聯。我們也能夠推理得到:HasLeader是hasHead的子屬性,同時hasHead也是HasLeader的子屬性。
sameIndividualAs 兩個individual也可以被聲明為相同。它可以被用來創建一系列指向同一個individual的名字。 Deborah被說成與DeborahMcGuinness是同一個individual。
differentFrom 一個individual可被聲明為與其他一些individual不同,這在使用如OWL(RDF)等語言時表達individual有而且只有一個名字時非常重要。 l Frank可被說成與Deborah以及Jim是不同的individual,這樣當Frank和Deborah都被說成是一個functional(最多只有一個值)的property的值時,就會出現矛盾;l 沒有特別指出的話,我們不能推理說Deborah和Frank指的是不同的individual。
allDifferent 在一個allDifferent聲明中,我們可以指出一定數量的individual兩兩不同。這在表達一個不同對象的集合而建模者側重於強調這些對象的唯一的名字時尤其有用。 可以在一個allDifferent聲明中說明Frank、Deborah、Jim兩兩不同。

3.5.3 OWL Lite Property Characteristics

名稱 描述 實例
inverseOf 一個屬性可以被聲明為另一個屬性的翻轉屬性。如果P1被聲明為P2的翻轉屬性,那么如果X通過P1關聯到Y,那么Y通過P1關聯到X。 如果hasChild是hasParent的翻轉屬性,Deborah hasParent Louise,那么我們就能夠推理出Louise hasChild Deborah。****
TransitiveProperty 屬性可以被聲明為傳遞的。如果(x,y)是傳遞屬性P的一個實例,(y,z)也是傳遞屬性P的一個實例,那么(x,z)是傳遞屬性P的一個實例。OWL Lite給出了關於傳遞屬性的一個邊界條件:傳遞屬性和它的superproperty不能有maxCardinality為1的限制,否則OWL Lite和OWL DL都將成為不確定語言。 如果ancestor被聲明為傳遞的,(Sara,Louise)是它的一個實例,(Louise,Deborah)也是他的一個實例,那我們就能夠推理出(Sara,Deborah)是他的一個實例。
SymmetricProperty 屬性可以被聲明為是對稱的。如果(x,y)是對稱屬性P的一個實例,那么(y,x)也是它的一個實例。被聲明為對稱的屬性不能有任意的domain和range。 Friend可以被說成是一個對稱屬性,如果Frank 是 Deborah的Friend,那我們可以推斷出Deborah 是Frank的Friend。
FunctionalProperty 屬性可以被聲明為只有一個值。即一個individual如果被聲明為FunctionalProperty,那么對於這樣的一個實例它最多只有一個值。這可以被方便的用來說明一個屬性的cardinality最小為0,最大為1。 l Frank可被說成與Deborah以及Jim是不同的individual,這樣當Frank和Deborah都被說成是一個functional(最多只有一個值)的property的值時,就會出現矛盾;l 沒有特別指出的話,我們不能推理說Deborah和Frank指的是不同的individual。
InverseFunctionalProperty 如果一個屬性被聲明為inverse functional,則意味着它的翻轉屬性是functional的,也就是說該屬性的翻轉屬性的每個individual最多只有一個值。 HasUSSocialSecurityNumber(SecurityNumber是美國居民的唯一標識符)可以被聲明為inverse functional。該屬性的翻轉屬性isTheSocialSecurityNumberFor在社會保險號這個class中任何一個individual至多只有一個值。由此我們可以推斷出任何兩個Person的實例都不能有相同的SecurityNumber。還可以推斷出:如果兩個Person的實例有相同的SecurityNumber,那么他們一定是表示同一個individual。

3.5.4 OWL Lite Property Type Restriction

該約束針對某個屬性,屬於局部約束。

名稱 描述 實例
allValuesFrom 該約束將一個屬性的取值和一個class相關。也就是說,如果一個class的實例通過這個屬性和另外一個individual相關,那么后一個individual則能夠被認為是改約束類的一個實例。 Class Person有一個屬性hasOffspring,該屬性被約束在allValuesFrom上取值為Person類。這就是說如果Person的一個實例Louise通過屬性hasOffspring和另一個individual Deborah相關,從這一點我們能推斷出 Deborah是Person的一個實例。這種約束允許hasOffspring屬性被其他class使用,例如被class Cat使用,從而做出相應的約束。
someValuesFrom 和上面類似,該約束也將一個屬性的取值和一個class相關。只不過此時要求該屬性的取值至少有一個是該class類型的。 Class SemanticWebPaper在property hasKeyword上的someValuesFrom 約束值SemanticWebTopic說明hasKeyword存在某個取值應該是class SemanticWebTopic的一個實例。但是我們不能就此推斷說hasKeyword的所有取值都是SemanticWebTopic的實例。

3.5.5 OWL Lite Restricted Cardinality

同上,該約束也是局部約束,而且OWL Lite在Cardinality上的局部約束只允許Cardinality的取值為0和1(這不同於其他兩類OWL允許任意數目的Cardinality)。

名稱 描述 實例
minCardinality Cardinality是依據一個特定的class在一個property上做的聲明。如果就一個class而言某個property的minCardinality為1,則該class的任何一個實例都通過該property至少和一個individual相關。這也是一種用來表達某property必須在某class的任何一個實例中有一個值的辦法。在OWL Lite中,minCardinality的值只能為0或者1。0表示的意思是對於某個class而言這個proerty是可選的。 l Class Person在property hasOffspring並沒有minCardinality約束,因為不是所有的Person都有Offspring的。l Class Parent則在property hasOffspring上有minCardinality為1。l Class Person在property hasOffspring上的minCardinality值可以為0。根據上面的前兩條信息我們可以推斷出,如果Louise是一個Person,我們並不能得到任何有關他后代的信息;但是一旦發現他是一個Parent,則Louise通過property hasOffspring至少和一個individual相關。但是我們不能得到他最多和幾個individual相關。
maxCardinality 如果就一個class而言某個property的maxCardinality為1,則該class的任何一個實例都通過該property至多和一個individual相關。MaxCardinality值為1的約束property有時也叫做functional或者unique property。通過它我們不能得到有關minCardinality的任何信息,但是這對於我們表達某些class在某些property上沒有值是很重要的。 l Class UnitedStatesCitizens上的property hasRegisteredVotingState的MaxCardinality值為1(因為一個公民只能在一個州投票)。l Class UnmarriedPerson實例不能通過property hasSpouse和任何individual相關,這時只要把hasSpouse的maxCardinality設為0就可以了。
cardinality 它用於方便表達在一個class上的property同時擁有約束minCardinality 0 和 maxCardinality 0 或者 minCardinality 1 和 maxCardinality 1。 Class person在property hasBirthMother上只有一個值,可以設定該property的Cardinality。

3.5.6 OWL Lite Class Intersection

名稱 描述 實例
intersectionOf: OWL Lite允許在class和約束之間存在交集。 Class EmployedPerson可以被定義為intersectionOf class Person和EmployedThings(后者可以被定義為擁有hasEmployer屬性並在該屬性上的minCardinality為1)。

3.5.7 Datatypes

OWL 使用了RDF的datatype schema,而后者又參考了XML Schema的datatype。這些datatype能夠通過URI被識別。每當有一個datatype的實例出現時,必須有一個RDF屬性rdf:datatype,它的值為URI引用的XML Schema datatype。

3.5.8 OWL Lite Header Information

OWL支持ontology引用、包含以及元信息描述。上面提到的三個層次的OWL都包含了用於指定導入的ontology、ontology版本信息和前版本信息、可向后兼容的ontology信息以及不兼容的ontology信息等一系列信息的方法。

3.6 增量語言OWL DL和OWL Full描述

盡管OWL DL添加了一些約束,它和OWL Lite實際上共享了詞匯表。總的來講,OWL DL引入了類型分割(一個class不能是一個property或者一個individual,一個property也不能是一個class或者individual);它要求property或者是ObjectProperties,或者是DatatypeProperties。后者RDF literal、XML Datatype以及class實例之間的關系。前者是兩個class實例之間的關系。下面繼續列出了OWL DL和OWL Full的擴展詞匯

名稱 描述 實例
One of(枚舉類型) Class可以通過枚舉構成該class的individual來描述。 Class daysOfTheWeek可以簡單地通過枚舉Sunday、Monday、Tuesday、Wednesday,、Thursday、Friday、 Saturday這7個individual來表達。我們可以由此推斷出任何擁有allValuesFrom約束於daysOfTheWeek的property的maxcardinality為7。
HasValue(屬性值) 一個property可以被要求擁有一個特定的individual作為它的值。 Class dutchCitizens的實例可以在property nationality上以theNetherlands最為它的值。
disjointWith OWL Full允許在class定義不相交性。 Man和Woman可以被定義為是不相交的,這樣我們就能夠推斷出如果已知A為Man,那么A一定不是Woman。
unionOf, complementOf, intersectionOf(布爾連接) OWL Full允許class之間任意的布爾連接。 l 通過unionOf,我們能夠聲明或者是USCitizens或者是DutchCitizens的事物;l 通過complementOf,我們能夠聲明children不是SeniorCitizens。
minCardinality, maxCardinality, cardinality(全cradinality) OWL Full允許取值為任意非負整數的cardinality。 Class DINKs(Dual Income)在property hasIncome上的mincardinality約束為2
complex classes 由於OWL Full引入了上面的詞條,實際上它已經支持了復雜類。它還包括了一個底層class名為Nothing,它沒有任何實例。OWL允許class被用作實例(另兩種不可以)。

4 OWL文檔結構舉例

4.1 命名空間

這是使用OWL的一系列詞條的前提,我們必須准確說明正在使用的特定的詞匯表。一個Ontology的標准的初始模塊是包含在rdf:RDF標簽中的一系列命名空間(namespace)的聲明。這些聲明用以准確解釋文檔中的標識符,從而使得Ontology的其他部分具有可讀性。以下是一個典型的命名空間聲明的例子:


<rdf:RDF 
    xmlns ="http://www.example.org/wine#" 
    xmlns:vin ="http://www.example.org/wine#"       
    xmlns:food="http://www.example.org/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-schema#"
    xmlns:xsd ="http://www.w3.org/2000/10/XMLSchema#"
    xmlns:dte ="http://www.example.org/wine-dt#"> 
命名標識符 描述
xmlns ="http://www.example.org/wine#" 說明了缺省的命名空間,也就是當文檔中出現沒有前綴的標簽時所引用的命名空間。
xmlns:vin ="http://www.example.org/wine#" 說明了和當前的Ontology相關的具有前綴vin的命名空間。
xmlns:food="http://www.example.org/food#" 指出了支持表達本Ontology的food這一Ontology的命名空間,它們以前綴food出現。
xmlns:owl ="http://www.w3.org/2002/07/owl#" 說明了出現owl前綴的詞條應該尋找的命名空間。這是通常的OWL聲明,用以在文檔中加入OWL詞匯表。
xmlns:rdf ="http://www.w3.org/1999/02/22-rdf-syntax-ns#" 說明了在文檔中出現的以rdf為前綴的詞條的命名空間,這是為了引入RDF定義的詞匯。
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" 說明了在文檔中出現的以rdfs為前綴的詞條的命名空間,這是為了引入RDF Schema定義的詞匯。
xmlns:xsd ="http://www.w3.org/2000/10/XMLSchema#" 說明了在文檔中出現的以xsd為前綴的詞條的命名空間,這是為了引入XML Schema定義的詞匯。
xmlns:dte ="http://www.example.org/wine-dt#" > 說明了在文檔中出現的以dte為前綴的詞條的命名空間,這是為了引入包含XML Schema Datatype定義的詞匯。

我們也可以在Ontology定義之前在文檔類型定義DocType一節中通過定義一些實體來給出命名空間的說明。例如:

<!DOCTYPE owl [
    <!ENTITY vin  "http://www.example.org/wine#" >
    <!ENTITY food "http://www.example.org/food#" > ]>

​ 另外,命名空間只是對標簽的說明,對屬性沒有約束。但是在OWL文檔中我們又經常要用到和命名空間相關的詞條,這時就必須寫清楚整個URI。例如http://www.example.org/owl/wine#merlot。但是如果有了類似上面的實體定義,我們也可以簡寫成“&vin;merlot”。

4.2 Ontology頭

完成了命名空間的定義,我們必須以下面的斷言來開始一個OWL Ontology:

<owl:Ontology rdf:about="http://www.example.org/wine">

接下來可以以一些標簽標明注釋、版本控制、以及對其他Ontology的引入等信息。例如:

<owl:Ontology rdf:about="http://www.example.org/wine"> 
  <rdfs:comment>An example OWL ontology</rdfs:comment>
  <owl:versionInfo>
      $Id: Overview.html,v 1.2 2002/11/08 16:42:25 connolly Exp $
  </owl:versionInfo>
  <owl:imports rdf:resource="http://www.w3.org/TR/2002/WD-owl-guide-20021104/food.owl"/> 
標簽 說明
rdfs:comment 給出了本Ontology的主要功能。
owl:versionInfo 標准標簽,給出了供版本控制系統掛鈎用的信息,OWL本身並沒有什么結構上的約束。
owl:imports 提供了引入機制,只給出了一個參數rdf:resource。

其中引入另外一個Ontology將會將它的整個定義的集合加入到知識庫中來。需要注意的是,這個標簽只是說明了引入一個Ontology的意圖,但不總是成功的。在語義網上對網上資源的訪問不總是成功的,這需要依照工具實現的情況而定。

最后,給出相應的Ontology頭的結束標簽:

</owl:Ontology>

4.3 基本定義

4.3.1 簡單的Classe和Individual

所有用戶定義的class都缺省是owl:Thing的subclass。而領域相關的根class的定義只要給出一個命名的類聲明就可以了。例如在制酒業的三個根class定義如下:

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

這時我們只是用ID為類起了名字,並沒有指定有關類的其他任何信息,例如該類的成員等等。rdf:ID屬性類似於XML中的ID屬性,這樣我們能夠通過類似“documentURI#Region”在其他的Ontology中引用region這一class。也可以采用類似“rdf:about="#x”的方法引用。

​ Class的基本的分類構造器是subclassof。例如:

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

這里我們定義了PotableLiquid是ConsumableThing的subclass。

​ 類定義除了包括命名和引用以外,還包括限制。上面的subclassof就是一個限制。下面給出了Wine這個class的簡單定義:

<owl:Class rdf:ID="Wine"> 
  <rdfs:subClassOf rdf:resource="#PotableLiquid"/> 
  <rdfs:label xml:lang="en">wine</rdfs:label> 
  <rdfs:label xml:lang="fr">vin</rdfs:label> 
  ...  
</owl:Class> 

rdfs:label標簽給出了人們可讀的類名。屬性lang表示支持多語言表達。

一個Individual可以通過聲明它是某個類的成員得以表達。例如:

<Region rdf:ID="CentralCoastRegion" />

下面的表達是等價的:

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

type這個RDF詞條將一個Individual和一個class的成員綁定起來。

下面的例子給出了一個grape分類,並用一個individual表達了Cabernet Sauvignon品種的grape:

<owl:Class rdf:ID="Grape">
<owl:Class rdf:ID="WineGrape">
  <rdfs:subClassOf rdf:resource="#Grape"/>
</owl:Class>

<WineGrape rdf:ID="CabernetSauvignonGrape" />

4.3.2 簡單的Property

property可以被用來說明class的共同特征以及某些individual的專有特征。一個property是一個二元關系。有兩類property:

  • datatype property:class元素和XML datatype之間的關系;

  • object property:兩個類元素之間的關系。

可以通過指定property的domain和range以及定義subproperty來約束一個property。下面是一個例子:

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

通過上面的定義property madeFromGrape給出了class Wine的元素和WineGrape的元素之間的關系。下面的例子給出了property的層次定義:

<owl:ObjectProperty 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>

​ 下面是locatedIn property的定義:

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

該定義允許locatedIn的domain為任何一個thing。

​ 下面是Vintage這個class的定義:

<owl:Class rdf:ID="Vintage"> 
  <rdfs:subClassOf rdf:resource="http://www.w3.org/2002/07/owl#Thing"/> 
  <rdfs:subClassOf>
    <owl:Restriction> 
      <owl:onProperty rdf:resource="#vintageOf"/>
      <owl:minCardinality>1</owl:minCardinality>
    </owl:Restriction>
  </rdfs:subClassOf>
</Class>

property vintageOf 將Vintage關聯到wine。

​ Datatype利用XML Schema datatype定義的簡單類型完成定義。如果我們想把vintage的年限約束到1700以后,我們需要在其他文件中創建幾個XML Schema datatype定義:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
       xmlns="http://www.example.org/wine-dt.xsd">
  <xsd:simpleType name="year"> 
    <!-- year is an XMLS datatype based on integer --> 
    <xsd:restriction base="xsd:decimal"/> 
  </xsd:simpleType>

  <xsd:simpleType name="wineYear"> 
    <!-- wineYear is an XMLS datatype based on year --> 
    <!-- with the added restriction that values must be GEQ 1700 --> 
    <xsd:restriction base="year"> 
    <xsd:minInclusive value="1700"/>
  </xsd:restriction> 
  </xsd:simpleType>
</xsd:schema> 

而后我們再給出WineYear這個class的定義:

<owl:Class rdf:ID="WineYear" />
<owl:DataTypeProperty rdf:ID="yearValue">
  <rdfs:domain rdf:resource="#WineYear" />    
  <rdfs:range  rdf:resource="&dt;wineYear"/>
</owl:DataTypeProperty>

關於individual的property定義,一個例子如下:

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

下面創建了一個WineYear的實例並將它和一個特殊的datatype dte:wineYear關聯起來:

<WineYear rdf:ID="Year1998">
  <yearValue rdf:datatype="&dte;wineYear">1998</yearValue>
</WineYear> 

4.3.3 Property特征

下面給出了用於擴展定義property的各類特征。

  • TransitiveProperty

被標記為Transitive的property P滿足下面的公理:

P(x,y) and P(y,z) -> P(x,z)

例如:

<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>

其中locatedIn就是Transitive的。

  • SymmetricProperty

被標記為symmetric的property P滿足下面的公理:

P(x,y) iff P(y,x)

例如:

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

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

adjacentRegion就是symmetric的。

  • Functional Property

被標記為functional的property P滿足下面的公理:

P(x,y) and P(x,z) -> y = z

例如:

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

hasVintageYear就是functional的,因為每種wine只有一個VintageYear。

  • inverseOf

一個property P1被標記為inverseof 一個property P2,滿足下面的公理:

P1(x,y) iff 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>
  • InverseFunctionalProperty

一個被標記為InverseFunctional的property P滿足下面的公理:

P(y,x) and P(z,x) -> y = z

例如:

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

​ producesWine就是InverseFunctional的。

4.3.4 Property 約束

還可以進一步通過約束來規定property的range在某些范圍內。

  • allValuesFrom, someValuesFrom

上面已經給出的property都是全局的屬性約束。而這兩個約束相對包含它們的類定義而言是局部的。例如:

<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>

其中在hasMaker這個property上的allValuesFrom約束只是對wine這個class有意義。上面的allValuesFrom可以被替換為someValuesFrom,約束范圍也是類似的。

  • Cardinality

我們可以通過Cardinality直接指定於一個class相關的class的數目,例如:

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

在OWL Lite中只能指定Cardinality為0或者1,而在OWL Full中,可以使用owl:maxCardinality來指定一個上界。

  • hasValue [OWL DL]

hasValue允許我們定義基於特定property的值存在的class。一個individual要成為一個類的成員,它在這個property上的取值必須滿足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>

4.4 Ontology映射

我們需要在Ontology上定義映射關系來重用已有的Ontology的class和property。

  • sameClassAs, samePropertyAs

下面是重用類的一個例子:

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

下面是重用一個類並在其基礎上進行約束的例子:

<owl:Class rdf:ID="TexasThings"> 
  <owl:sameClassAs>
    <owl:Restriction>
      <owl:onProperty rdf:resource="#locatedIn" />
      <owl:allValuesFrom rdf:resource="#TexasRegion" />
    </owl:Restriction>
  </owl:sameClassAs>
</owl:Class>   
  • sameIndividualAs

它的定義和class類似,說明了兩個individual是同一的,例如:

  • differentIndividualFrom

該定義與sameIndividualAs的效果正好相反

4.5 復雜的Class【OWL DL】

OWL通過下面的機制給出了定義類表達式的基本方法,從而能夠通過嵌套定義給出一個復雜的class。

4.5.1 集合操作符

  • Intersection [OWL DL]

下面給出了操作符intersectionOf的用法:

<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>

注意類操作符是封閉的。

下面是一個通過兩次嵌套定義的例子:

<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" />
    </owl:Restriction>
  </owl:intersectionOf>
</owl:Class>

<owl:Class rdf:ID="WhiteBurgundy">
  <owl:intersectionOf rdf:parseType="Collection">
    <owl:Class rdf:about="#Burgundy" />
    <owl:Class rdf:about="#WhiteWine" />
  </owl:intersectionOf> 
</owl:Class>
  • Union [OWL DL]

下面是一個使用UnionOf的例子:

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

可以將它和下面的定義作比較:

<owl:Class rdf:ID="Fruit">
  <rdfs:subClassOf rdf:resource="#SweetFruit" />
  <rdfs:subClassOf rdf:resource="#NonSweetFruit" />
</owl:Class>
  • Complement [OWL DL]

下面是一個使用complementOf的例子:

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

下面是一個混和使用了各種集合操作符的例子:

<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>   

4.5.2 枚舉Class

  • oneOf [OWL DL]

OWL通過one of操作符給出了枚舉一個class的成員的基本方法,例如下面的例子定義了WineColor這個class擁有3個成員:

<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>

​ 我們也可以通過直接指定每個成員的類型進行定義:

<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>

4.5.3 不交的Class

  • disjointWith [OWL DL]

它用於表達一個individual是一個class的成員,同時不能是另外一個class的成員。

例如:

<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>

定義一個class是幾個不交的subclass的union的例子如下:

<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>

定義的規模隨着不相交類的數目(n)的增長是n2級的。

5 一個完整的制酒行業的Ontology的OWL建模

這個例子是w3c的Guus Schrieber開發的關於制酒行業的更為精細的Ontology。

5.1 相關背景

對於制酒業而言,“產品地域”(production area)是一個非常重要的feature。根據生產地域的谷類的大小酒的類型存在很大的變化,從一個國家到一個特定的葡萄園。我們可以給出四種不同的產品地域:

  • 國家(country),例如France,Italy

  • 區域(region),例如Bordeaux,Medoc,Tuscany

  • 城鎮(town),例如Margaux, Montalcino, Montepulciano

  • 葡萄園(vineyard),例如Chateau Margaux,Avignonesi

而且我們必須為不同產品地域之間的關系建模:

  • 區域是國家的一部分:Tuscany在Italy

  • 區域有子區域:Medoc是Bordeaux的子區域

  • 城鎮在某區域中:Montalcino在Tuscany

  • 葡萄園在城鎮中:Chateau Margaux在Margaux,Avignonesi在Montepulciano

5.2 建模決策

我們決定去掉“town”,將它們都看作region。這樣做簡化了模型,並且這附和實際中town作為一個產品地域在城鎮周邊,比城鎮面積稍大或稍小的事實。

5.3 模型

5.3.1 Class

<owl:Class rdf:ID="&vin;ProductionArea"/ >

<owl:Class rdf:ID="&vin;Country:">
   <rdfs:subClassOf rdf:resource="&vin;ProductionArea"/>
</owl:Class> 
<owl:Class rdf:ID="&vin;Region:"> 
   <rdfs:subClassOf rdf:resource="&vin;ProductionArea"/> 
</owl:Class> 

<owl:Class rdf:ID="&vin;Vineyard:"> 
   <rdfs:subClassOf rdf:resource="&vin;ProductionArea"/> 
</owl:Class> 

用三元組可以表示為:

vin:ProductionArea rdf:type rdfs:Class.
vin:Country rdfs:subClassOf vin:ProductionArea.
vin:Region rdfs:subClassOf vin:ProductionArea.
vin:Vineyard rdfs:subClassOf vin:ProductionArea.

5.3.2 Property

<owl:ObjectProperty rdf:ID="&vin;hasSubArea">   
 <rdf:type rdf:resource="&owl;TransitiveProperty" />
</owl:ObjectProperty>  

<owl:ObjectProperty rdf:ID="&vin;subAreaOf">   
   <owl:inverseOf rdf:resource="&vin;hasSubArea"/> 
</owl:ObjectProperty>  

<owl:ObjectProperty rdf:ID="&vin;hasRegion">   
   <rdfs:subPropertyOf rdf:resource="&vin;hasSubArea"/> 
   <owl:allValuesFrom rdf:resource="&vin;Region"/>
</owl:ObjectProperty>  

<owl:ObjectProperty rdf:ID="&vin;regionOf">   
   <owl:inverseOf rdf:resource="&vin;hasRegion"/> 
   <owl:allValuesFrom rdf:resource="&vin;Country"/>
   <owl:cardinality>1</owl:cardinality>
</owl:ObjectProperty>  

<owl:ObjectProperty rdf:ID="&vin;hasSubRegion">   
   <rdfs:subPropertyOf rdf:resource="&vin;hasSubArea"/> 
   <owl:allValuesFrom rdf:resource="&vin;Region"/>
</owl:ObjectProperty>  

<owl:ObjectProperty rdf:ID="&vin;subRegionOf">   
   <owl:inverseOf rdf:resource="&vin;hasSubRegion"/> 
  <owl:allValuesFrom rdf:resource="&vin;Region"/>
   <owl:cardinality>1</owl:cardinality>
</owl:ObjectProperty>  

<owl:ObjectProperty rdf:ID="&vin;hasVineyard">   
   <rdfs:subPropertyOf rdf:resource="&vin;hasSubArea"/> 
   <owl:allValuesFrom rdf:resource="&vin;Vinyard"/>
</owl:ObjectProperty>  

<owl:ObjectProperty rdf:ID="&vin;vineyardRegion">   
   <owl:inverseOf rdf:resource="&vin;hasVineyard"/> 
   <owl:allValuesFrom rdf:resource="&vin;Region"/>
   <owl:cardinality>1</owl:cardinality>
</owl:ObjectProperty>

用三元組表示為:

vin:hasSubArea rdf:type rdfs:Property.  
vin:hasSubArea rdf:type owl:TransitiveProperty. 
vin:subAreaOf owl:inverseOf vin:hasSubArea. 
vin:hasRegion rdfs:subPropertyOf vin:hasSubArea.
vin:hasRegion owl:allValuesFrom vin:Region.
vin:regionOf owl:inverseOf vin:hasRegion.
vin:regionOf owl:allValuesFrom vin:Country.
vin:regionOf owl:cardinality 1.
vin:hasSubRegion rdfs:subPropertyOf vin:hasSubArea.
vin:hasSubRegion owl:allValuesFrom vin:Region.
vin:subRegionOf owl:inverseOf vin:hasSubRegion.
vin:subRegionOf owl:allValuesFrom vin:Region.
vin:subRegionOf owl:cardinality 1.
vin:hasVineyard rdfs:subPropertyOf vin:hasSubArea.
vin:hasVineyard owl:allValuesFrom vin:Vineyard.
vin:vineyardRegion owl:inverseOf vin:hasVineyard..
vin:vineyardRegion owl:allValuesFrom vin:Region.
vin:vineyardRegion owl:cardinality 1.

5.3.3 UML注釋

6 緊急聯動的一個簡單建模

6.1 UML模型(應急聯動機構)

6.2 Ontology模型

<?xml version="1.0" encoding="GB2312"?>

<rdf:RDF 
    xmlns     ="http://gis.pku.edu.cn/應急聯動機構#" 
    xmlns: 應急聯動機構="http://www.example.org/應急聯動機構#"      
    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-schema#"
xmlns:xsd =http://www.w3.org/2000/10/XMLSchema#>

<owl:Ontology rdf:about=" http://gis.pku.edu.cn/應急聯動機構"> 
  <rdfs:comment>中國城市應急聯動機構的Ontology</rdfs:comment>
  <owl:versionInfo>
      $Id: test.html,v 1.0 2003/03/20 22:22:00 Lxp $
  </owl:versionInfo>
</owl:Ontology>

<owl:Class rdf:ID="&應急聯動機構;聯動單位"/ >
<owl:Class rdf:ID="&應急聯動機構;消防局:">
    <rdfs:subClassOf rdf:resource="&應急聯動機構;聯動單位"/>
</owl:Class>

<owl:Class rdf:ID="&應急聯動機構;聯動單位調度中心"/ >
<owl:Class rdf:ID="&應急聯動機構;處置力量分支"/ >
<owl:Class rdf:ID="&應急聯動機構;消防指揮調度中心:">
    <rdfs:subClassOf rdf:resource="&應急聯動機構;聯動單位調度中心"/>
</owl:Class>

<owl:Class rdf:ID="&應急聯動機構;消防支隊:">
    <rdfs:subClassOf rdf:resource="&應急聯動機構;處置力量分支"/>
</owl:Class>

<owl:Class rdf:ID="&應急聯動機構;處置力量部門"/ >

<owl:Class rdf:ID="&應急聯動機構;消防中隊:">
    <rdfs:subClassOf rdf:resource="&應急聯動機構; 處置力量部門"/>
</owl:Class>

<owl:Class rdf:ID="&應急聯動機構;消防車"/ >

<owl:ObjectProperty rdf:ID="&應急聯動機構;包含中心">   
  <rdf:type rdf:resource="&owl;FunctionalProperty" />
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="&應急聯動機構;包含分支">   
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="&應急聯動機構;包含聯動調度中心">   
<rdfs:subPropertyOf rdf:resource="&應急聯動機構;包含中心"/> 
	<rdfs:domain rdf:resource="&應急聯動機構;聯動單位" />
<rdfs:range rdf:resource="&應急聯動機構;聯動單位調度中心" />
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="&應急聯動機構;包含力量分支">   
<rdfs:subPropertyOf rdf:resource="&應急聯動機構;包含分支"/> 
	<rdfs:domain rdf:resource="&應急聯動機構;聯動單位" />
<rdfs:range rdf:resource="&應急聯動機構;處置力量分支" />
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="&應急聯動機構;包含力量部門">   
    <rdfs:subPropertyOf rdf:resource="&應急聯動機構;包含分支"/> 
	<owl:allValuesFrom rdf:resource="&應急聯動機構;處置力量部門"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="&應急聯動機構;包含消防調度中心">   
<rdfs:subPropertyOf rdf:resource="&應急聯動機構;包含中心"/> 
	<rdfs:domain rdf:resource="&應急聯動機構;消防局" />
<rdfs:range rdf:resource="&應急聯動機構;消防指揮調度中心" />
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="&應急聯動機構;包含消防支隊">   
<rdfs:subPropertyOf rdf:resource="&應急聯動機構;包含分支"/> 
	<rdfs:domain rdf:resource="&應急聯動機構;消防局" />
<rdfs:range rdf:resource="&應急聯動機構;消防支隊" />
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="&應急聯動機構;包含中隊">   
    <rdfs:subPropertyOf rdf:resource="&應急聯動機構;包含分支"/> 
	<owl:allValuesFrom rdf:resource="&應急聯動機構;消防中隊"/>
</owl:ObjectProperty>

<owl:ObjectProperty rdf:ID="&應急聯動機構;包含車">   
<rdfs:subPropertyOf rdf:resource="&應急聯動機構;包含分支"/> 
	<rdfs:domain rdf:resource="&應急聯動機構;消防中隊" />
<rdfs:range rdf:resource="&應急聯動機構;消防車" />
</owl:ObjectProperty>
</rdf:RDF>

7 一個比較復雜的應急聯動的建模

8 Jena—語義網建模的Java API

8.1 簡介——幾個RDF建模的實例

【例一】: 給出下面的RDF有向圖:

其中,橢圓中的URI給出了一個resource,有向邊給出了該resource的一個property:FN(Full Name)。vcard是一個命名空間的前綴。該property的值在方框中給出,是一個literral類型的“John Smith”。

​ Jena一組能夠用來創建和操縱諸如此種類型的有向圖的Java API。Jena用對象類來表示圖、resource、property和literal,用於表達后三者的接口分別叫做Resource、Property和Literal,而圖被表示為一個model。用於創建上面的圖的代碼如下:

// some definitions
static String personURI    = "http://somewhere/JohnSmith";
static String fullName     = "John Smith";

// create an empty graph
Model model = new ModelMem();

// create the resource 
Resource johnSmith = model.createResource(personURI);

// add the property
johnSmith.addProperty(VCARD.FN, fullName);

ModelMem是實現了接口Model的類。Jena還包括了其他用於實現Model的類,它們可以被存儲在Berklay的DB數據庫以及關系數據庫中。VCARD是一個常數類,里面定義了所有VCARD Schema的常數。Jena還提供了其他常數類,如RDF、RDF Schema、Dublin Core 和DAML。其中,創建resource和添加property的兩條語句可以被壓縮為下面的一句:

Resource johnSmith = model.createResource(personURI).addProperty(VCARD.FN, fullName);

【例二】:下面給出了在例一的基礎上得到的一個相對復雜的有向圖:

與上面不同的是,vcard:N屬性以一個resource作為它的值,而該resource沒有名字,稱作一個空結點(blank Node)。

下面是Jena的創建代碼:

// some definitions
String personURI    = "http://somewhere/JohnSmith";
String givenName    = "John";
String familyName   = "Smith";
String fullName     = givenName + " " + familyName;

// create an empty graph
Model model = new ModelMem();

// create the resource
//   and add the properties cascading style
Resource johnSmith = model.createResource(personURI)
         .addProperty(VCARD.FN, fullName)
         .addProperty(VCARD.N, 
                      model.createResource()
                          .addProperty(VCARD.Given, givenName)
                          .addProperty(VCARD.Family, familyName));

8.2 Jena與整個建模流程

8.2.1 陳述(statement)

如上面的兩個例子所示,RDF有向圖中的每條邊就是一個陳述,它肯定了resource的一個事實。一個陳述包含三個部分:

  • subject,即有向邊離開的resource;主語

  • predicate,即帶標記的有向邊;謂詞

  • object,有向邊指向的resource或者literal。賓語

所以陳述又叫做三元組。一個RDF有向圖包含了一系列的陳述(statement),他是陳述的集合,所以重復的陳述可以被加進一個圖中。Jena的model接口提供了一個listStatements()方法用於得到一個在這個集合上的迭代器,它的返回類型為Statement。Statement接口提供了用於訪問該陳述的subject、predicate和object的方法。一個例子如下:

// list the statements in the graph
StmtIterator iter = model.listStatements();            

// print out the predicate, subject and object of each statement
while (iter.hasNext()) {
    Statement stmt      = iter.next();         // get next statement
    Resource  subject   = stmt.getSubject();   // get the subject
    Property  predicate = stmt.getPredicate(); // get the predicate
    RDFNode   object    = stmt.getObject();    // get the object
               
    System.out.print(subject.toString());
    System.out.print(" " + predicate.toString() + " ");
    if (object instanceof Resource) {
       System.out.print(object.toString());
    } else {
        // object is a literal
        System.out.print(" \"" + object.toString() + "\");
    }

    System.out.println(" .");
} 

由於object可以為一個resource或者一個literal,所以getObject() 方法返回一個類型為RDFNode的對象,該類是resource和literal的公共超類。

8.2.2 書寫RDF

Jena提供了用XML格式讀寫RDF的方法,這就使得我們能夠將一個RDF model存為一個文件並在以后將它讀出來。

下面的代碼片斷給出了如何將一個model存入文件的方法:

// now write the model in XML form to a file
model.write(new PrintWriter(System.out));

即調用model的write方法通過一個PrintWriter寫入文件中。

對於上面的例子,調用這樣的輸入語句可能得到下面的輸出結果:

<rdf:RDF
  xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
  xmlns:vcard='http://www.w3.org/2001/vcard-rdf/3.0#'>

  <rdf:Description rdf:about='http://somewhere/JohnSmith'>
    <vcard:FN>John Smith</vcard:FN>
    <vcard:N rdf:resource='#A0'/>
  </rdf:Description>
  
  <rdf:Description rdf:about='#A0'>
    <vcard:Given>John</vcard:Given>
    <vcard:Family>Smith</vcard:Family>
  </rdf:Description>
</rdf:RDF>

不過該表達並不完全與我們上面給出的例子相符。在XML表達中不能描述一個空的節點,在原圖中的空結點被賦予了一個URI。

Jena還提供了擴展接口用於支持可插入的新的writer來序列化RDF。上面使用的是標准的“dumb”writer,Jena還支持一個更為成熟的RDF/XML writer:

model.write(new PrintWriter(System.out), "RDF/XML-ABBREV");// now write the model in XML form to a file

這個writer也叫做PrettyWriter,它能夠使用RDF/XML feature的縮寫語法更為緊湊的將一張圖輸出到文件。它同時也支持空結點。但是對於很大的圖則不太適用,因為這樣做的性能不能接收。要想輸出很大的文件並且維持空結點,則使用N-Triples格式:

// now write the model in XML form to a file
model.write(new PrintWriter(System.out), "N-TRIPLE");

8.2.3 讀取RDF

下面的代碼給出了用於讀取一個RDF文件並且將它另外寫回的方法:

// create an empty model
 Model model = new ModelMem();           

 // use the class loader to find the input file
 InputStream in = Tutorial05.class
                               .getClassLoader()
                               .getResourceAsStream(inputFileName);
if (in == null) {
    throw new IllegalArgumentException(
                                 "File: " + inputFileName + " not found");
}

           
// read the RDF/XML file
model.read(new InputStreamReader(in), "");

// write it to standard out
model.write(new PrintWriter(System.out));

其中,read方法的第二個參數應該是相對的URI,因為這里沒有引用相對URI,所以可以為空。

8.2.4 關於Jena的RDF包

最新版本已不再使用使用com.hp.hpl.mesa命名空間

l 語義網應用開發人員使用Jena時的最重要的包是com.hp.hpl.mesa.rdf.jena.model。這個包包含了用於表達model、resource、property、literal、statements以及其他RDF的關鍵的接口;

l com.hp.hpl.mesa.rdf.jena.tutorial包包含了與Jena一同發布的指南中所使用的例子的源代碼;

l com.hp.hpl.mesa.rdf.jena.mem包包含了用於將整個模型狀態裝入內存的Jena API的實現。凡是創建基於內存的模型(最典型的是創建ModelMem類的實例)的實現都在本包中;

l com.hp.hpl.mesa.rdf.jena.common包包含了對於諸多實現通用的實現類。例如,它定義了類ResourceImpl, PropertyImpl, LiteralImpl。開發者一般不要直接使用這里的方法,例如不直接使用ResourceImpl,而使用createResource方法。這是為了保證在實現發生優化后不需要進行類型轉換;

l com.hp.hpl.jena.rdf為RDF包。

8.2.5 在RDF有向圖中的導航

給出一個resource的URL,可以使用Model.getResource(String uri)方法從圖中得到該資源所對應的對象。如果對應的resource存在,則返回該resource的對象,否則將創建一個新的對象。例如:

Resource vcard = model.getResource(johnSmithURI);// retrieve the John Smith vcard resource from the model

​ Resource接口定義了一系列方法用於訪問一個Resource的Property。Resource.getProperty(Property p)方法用於訪問一個resource的一個property。同以往的Java API不同的是該方法返回的是整個Statement對象,然后通過該對象的訪問方法來得到Property的值。例如想得到vcard:N這個property的值所對應的resource,代碼如下:

Resource name = (Resource) vcard.getProperty(VCARD.N).getObject();// retrieve the value of the N property

​ 由於property的值可能為resource或者literal,而我們已經知道上面得到的值為resource,所以進行了強制類型轉換。Jena也提供了特定類型的訪問方法,從而不需要在編譯時進行類型轉換。所以上面的代碼也可以寫成:

Resource name = vcard.getProperty(VCARD.N).getResource();// retrieve the value of the FN property

類似,如果property的值為literal,則可以寫成:

String fullName = vcard.getProperty(VCARD.FN) .getString();// retrieve the given name property

​ 上面的property VCARD.FN只有一個,但RDF允許一個resource有重復的property。例如Adam可能有多於一個的nickname:

// add two nick name properties to vcard

vcard.addProperty(VCARD.NICKNAME, "Smithy")
     .addProperty(VCARD.NICKNAME, "Adman");

​ 當調用getProperty方法時,Jena並沒有定義要返回哪一個property,所以vcard.getProperty(VCARD.NICKNAME)的結果是不確定的。Jena只是返回其中任意一個,但並不保證連續兩條調用都有可能返回同一個值。

​ 這樣,當proeprty連續出現時,可以使用Resource.listProperties(Property p)方法來得到一個迭代器從而列舉出它們。例如下面的代碼能夠列舉出上面添加的nickname:

// set up the output
System.out.println("The nicknames of \""+ fullName + "\" are:");

// list the nicknames
StmtIterator iter = vcard.listProperties(VCARD.NICKNAME);

while (iter.hasNext()) {
    System.out.println("    " + iter.next().getObject().toString());
}

​ 該代碼的輸出結果是:

The nicknames of "John Smith" are:
    Smithy
    Adman

8.2.6 關於圖的查詢

Jena核心只是提供了有限的查詢元語。另外對RDF還有更為強大的RDQL查詢語言。

Model.listStatements()方法用於列舉一個model中的所有statement,可能是最為原始的對一個model的查詢。該查詢不適於在很大的圖上面做查詢。Model.listSubjects()方法類似,只是返回在所有有property的resource上的迭代器。Model.listSubjectsWithProperty(Property p, RDFNode o)則返回所有在property p上有值o的resource的迭代器。例如:

// retrieve all resource of type Vcard.
ResIterator iter = model.listSubjectsWithProperty(RDF.type, VCARD.Vcard);

如果我們使用的vcard schema並沒有為vcard定義一個類型,那我們可以假定只有類型為vcard的resource有property vcard:FN,而且在我們的數據中,所有這樣的resource都有一個這樣的property,那我們可以這樣進行查詢:

// list vcards
ResIterator iter = model.listSubjectsWithProperty(VCARD.FN);

while (iter.hasNext()) {
    Resource r = iter.next();
    ...
}

所有上面的查詢都基於這樣一個查詢元語:model.listStatements(Selector s)。該方法返回建立在經過s選擇得到的statement上的迭代器。Selector被定義為可擴展的,目前只有一個實現:com.hp.hpl.mesa.rdf.jena.common包中的SelectorImpl類。SelectorImpl構造函數有三個參數:

Selector selector = new SelectorImpl(subject, predicate, object)

顯然它返回匹配參數給出的三元組的statement。如果在這三個參數的位置上任意一個為null,則認為匹配所有。所以

Selector selector = new SelectorImpl(null, null, null);

返回一張圖中的所有statement。

Selector selector = new SelectorImpl(null, VCARD.FN, null);

返回滿足predicate為VCARD.FN的statement而不論其他兩個參數的值為什么。以下的代碼列出了數據庫中所有vcard的full name:

// select all the resources with a VCARD.FN property
ResIterator iter = model.listSubjectsWithProperty(VCARD.FN);

if (iter.hasNext()) {
    System.out.println("The database contains vcards for:");
    while (iter.hasNext()) {
        System.out.println("  " + iter.next()
                                      .getProperty(VCARD.FN)
                                      .getString());
    }
} else {
    System.out.println("No vcards were found in the database");
}

輸出結果可以是:

The database contains vcards for:
  Sarah Jones
  John Smith
  Matt Jones
  Becky Smith

下面的例子是采用SelectorImpl來實現查詢的例子:

// select all the resources with a VCARD.FN property
// whose value ends with "Smith"

StmtIterator iter = model.listStatements(
  new SelectorImpl(null, VCARD.FN, (RDFNode) null) {
          public boolean selects(Statement s) {
          try {
              return s.getString()
                      .endsWith("Smith");
          } catch (RDFException e) {
            throw new RDFError(e);
          }
     }
 });

以上的代碼使用了Java的內置代理方法定義技術。其中select方法確保full name以“Smith”結束,而該過濾只是對subject起作用。

以下的兩段代碼可被認為是有着相同的功能:

//【1】
// do all filtering in the selects method

StmtIterator iter = model.listStatements(
  new SelectorImpl(null, null, (RDFNode) null) {
          public boolean selects(Statement s) {
          try {
              return (subject == null   || s.getSubject().equals(subject))
                  && (predicate == null || s.getPredicate().equals(predicate))
                  && (object == null    || s.getObject().equals(object))
          } catch (RDFException e) {
            throw new RDFError(e);
          }
     }
 });

//【2】
	StmtIterator iter = 
  	model.listStatements(new SelectorImpl(subject, predicate, object)

前者列出圖中所有的statement而后依次測試之,而后者允許使用應用實現本身維護的索引來提高性能。

8.2.7 對圖的操作

Jena提供了3種針對圖這一整體進行的操作——即典型的集合操作:並(union)、叫(intersection)和差(different)。

對兩張圖取並就是對兩張圖所包含的statement取並,這是為了支持RDF所給出的一個關鍵操作,它使得不同數據源的數據能夠被合並。給出下面的兩張圖:

它們可以被合並為:

上面的操作的代碼是:

// read the RDF/XML files
model1.read(new InputStreamReader(in1), "");
model2.read(new InputStreamReader(in2), "");

// merge the graphs
Model model = model1.union(model2);           

// print the graph as RDF/XML
model.write(new PrintWriter(System.out), "RDF/XML-ABBREV");

生成的RDF為:

<?xml version='1.0'?>
<rdf:RDF
    xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
    xmlns:RDFNsId1='http://www.w3.org/2001/vcard-rdf/3.0#'>
    <rdf:Description rdf:about='http://somewhere/JohnSmith/'>
        <RDFNsId1:N
             RDFNsId1:Given='John'
             RDFNsId1:Family='Smith'/>
        <RDFNsId1:FN>John Smith</RDFNsId1:FN>
        <RDFNsId1:EMAIL
             rdf:value='John@somewhere.com'
             rdf:type='http://www.w3.org/2001/vcard-rdf/3.0#internet'/>
    </rdf:Description>
</rdf:RDF>

交和差操作與此類似。

8.2.8 相關異常

目前Jena的異常機制不很受歡迎,它將在將來得到改進。由於Jena被設計成具有很高的靈活性並且支持不同的存儲系統,所以存儲管理器可以在任何時候給出一個非預期的錯誤。所以幾乎所有的Jena方法在結尾都要注明要拋出RDFException異常。經驗證明這不是一個好方法,當拋出異常時,通常這些異常都應該被忽略,檢查出這些異常沒有任何好處。

8.2.9 容器(Containers)

RDF給出了表達事物集合的特殊類型的resource。這些resource叫做容器。容器的成員或者是resource,或者是literal。共有3類容器:

  • BAG是一個無序的容器;
  • ALT是一個用於表達選擇的無序的容器;
  • SEQ是一個有序的集合。

下圖是一個含有BAG的RDF有向圖的示意:

注意BAG的成員標號rdf:_1rdf:_2的順序並不重要,它們可以被交換。而ALT的成員標號除了第一個是重要的(它是缺省的選擇)外,也是順序無關的。

Jena提供了明確的類接口和類實現用於表達容器,例如:

// create a bag
Bag smiths = model.createBag();

// select all the resources with a VCARD.FN property
// whose value ends with "Smith"

StmtIterator iter = model.listStatements(
    new SelectorImpl(null, VCARD.FN, (RDFNode) null) {
        public boolean selects(Statement s) {
            try {
                return s.getString()
                        .endsWith("Smith");
            } catch (RDFException e) {
                throw new RDFError(e);
            }
        }
    });

// add the Smith's to the bag
while (iter.hasNext()) {
    smiths.add(iter.next().getSubject());
}

​ 由它得到的RDF為:

<rdf:RDF
  xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
  xmlns:vcard='http://www.w3.org/2001/vcard-rdf/3.0#' >
...

  <rdf:Description rdf:about='#A3'>
    <rdf:type rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#Bag'/>
    <rdf:_1 rdf:resource='http://somewhere/JohnSmith/'/>
    <rdf:_2 rdf:resource='http://somewhere/RebeccaSmith/'/>
  </rdf:Description>

</rdf:RDF>

容器接口提供了一個迭代器用於列舉它的成員:

// print out the members of the bag
NodeIterator iter2 = smiths.iterator();
if (iter2.hasNext()) {
    System.out.println("The bag contains:");
    while (iter2.hasNext()) {
        System.out.println("  " +
            (Resource) iter2.next())
                            .getProperty(VCARD.FN)
                            .getString());
    }
} else {
    System.out.println("The bag is empty");
}

上面的輸出為:

The bag contains:
  John Smith
  Becky Smith

Jena類提供的用於操縱容器的方法包括:添加新成員、插入成員到容器的成員中部、刪除成員等。

8.2.10 有關Literal和DataType的細節

RDF的literal不是簡單的string。它可以包含一個語種標簽來說明該literal的語種。語種標簽為English的Literal“chat”和語種標簽為“French”的Literal “chat”被認為是不同的literal。

進一步說,一共有兩類literal:一種是普通的string,一種是一個定義良好的XML片斷。例如下面的代碼:

// create the resource
Resource r = model.createResource();                                     

// add the property
r.addProperty(RDFS.label, model.createLiteral("chat", "en"))
 .addProperty(RDFS.label, model.createLiteral("chat", "fr"))
 .addProperty(RDFS.label, model.createLiteral("<em>chat</em>", true));
 
// write out the graph
model.write(new PrintWriter(System.out));

它產生的RDF為:

<rdf:RDF
  xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'
  xmlns:rdfs='http://www.w3.org/2000/01/rdf-schema#'>
  <rdf:Description rdf:about='#A0'>
    <rdfs:label xml:lang='en'>chat</rdfs:label>
    <rdfs:label xml:lang='fr'>chat</rdfs:label>
    <rdfs:label xml:lang='en' rdf:parseType='Literal'><em>chat</em></rdfs:label>
  </rdf:Description>
</rdf:RDF>

兩個literal可以被看作相等的條件是:或者都是簡單的literal,或者都是XML literal。而且要么都沒有語種標簽,要么有的話標簽相同。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM