最近在学习本体和语义网。学习了OWL,也尝试着用了一下jena API对OWL本体进行查询。1.本体简介
“本体”这个术语来自于哲学,它是研究世界上的各种实体以及他们是怎么关联的科学。本体是对应用领域概念化的显示的解释说明,为某领域提供了一个共享通用的理解,从而无论是人还是应用系统之间都能够有效地进行语义上的理解和通讯。studer认为,本体是:“共享概念模型的明确的形式化规范说明”。这包括了4层含义:
概念化(conceptualization)
通过抽象出客观世界中一些现象的相关概念而得到的模型,其表示的含义独立于具体的环境状态
明确(explicit)
所使用的概念及使用这些概念的约束都有明确的定义
形式化(formal)
本体应是计算机可读的。
共享(share)
知识本体中体现的是共同认可的知识,反映的是相关领域中公认的概念集,它所针对的是团体而不是个体。本体的目标是捕获相关的领域的知识,提供对该领域知识的共同理解,确定该陋域内共同认可的词汇,并从不同层次的形式化模式上给出这些词汇和词汇之间相互关系的明确定义。2.OWL简介
2003 年7 月W3C 公布了OWL Web ontology 语言的最初工作草案,2004 年2 月10 日,OWL 正式成为W3C 推荐的标准。OWL 和DAML + OIL 非常相近,只有一些微小的变化。DAML + OIL 和OWL 的语义都基于描述逻辑(descriptionlogic ,DL) 。OWL 作为W3C 推荐的标准本体表示语言,它的最大特点是关联描述逻辑, 通过对概念、概念属性及其相互间关系的描述,构成概念的复杂关系网络,这就意味着描述逻辑推理机可以推理OWL 本体。OWL 有3个表达能力递增的子语言:OWL Lite ,OWL DL , OWL Full[20 ] 。OWL Lite 提供了类层次的能力和简单的约束能力,支持基数为0 或1 的基数约束,包括6 个类别的语言构造子。OWL DL 在保持计算完整性( computational completeness ) 和可判定性(decidability) 的前提下,提供了尽可能大的表达能力,包含了OWL 的全部语言构造成分,但他们的使用受到一些限制(如一个类可以是许多类的子类,但不能是另一个类的实例) 。描述逻辑是OWL 的形式化基础,OWL DL的主要扩充是增加了布尔逻辑运算操作。OWL Full 包含OWL 的全部语言构造成分并取消了OWL DL 的限制,在OWL Full 中一个类可以看成个体的集合,也可以看成是一个个体。由于OWL Full 取消了OWL DL 中的保证可计算的某些限制,在没有计算保证的语法自由的RDF 上进行最大程度表达, 允许一个Ontology 在预定义的(RDF、OWL) 词汇表上增加词汇,从而任何推理软件均不能支持OWL FULL 的所有特点,因此不存在完整的推理算法支持OWL Full 的全部特性。OWL 通过对概念、概念属性及其相互间关系的描述,构成概念的复杂关系网络。
OWL本体的一个优点是会有能够对其做推理的工具。这些工具提供了不特定于某个主题领域的通用支持,而如果要构建一个能对一个特定的工业界标准XML Schema做推理的系统,它往往是特定于一个领域的。构建一个可靠的和有用的推理系统不是一项简单的工作。而创建一个本体则更为容易处理。
3.jena简介
jena是惠普公司的一个项目,jena为应用程序开发人员提供了一套java接口对本体进行操作。这样我们就可以调用jenaAPI,构建我们自己的应用程序,实现对包括RDF,OWL本体进行创建,修改,查询以及推理操作。
这是一个用OWL语言开发的家族本体。
这是本体的数据文件
下面是利用jenaAPI对查询某个人的爸爸,妈妈,兄弟,姐妹,爷爷,祖先和后代。
....
public class SearchFamily {
private final static String FATHER="father";
private final static String MOTHER="mother";
private final static String DAUGHTER="daughter";
private final static String SON="son";
private final static String SISTER="sister";
private final static String BROTHER="brother";
private final static String ANCESTOR="ancestor";
private final static String OFFSPRING="offSpring";
private final static String GRANDPA="grandPa";
private final static String rulePath="E:\\programming\\workspace\\OWLTest\\WebRoot\\WEB-INF\\family.rules";
private final static String pre="http://zhumzhu.com/family#";
public final static String fileSchema="E:\\programming\\workspace\\OWLTest\\WebRoot\\WEB-INF\\familySchema.xml";
public final static String fileData="E:\\programming\\workspace\\OWLTest\\WebRoot\\WEB-INF\\familyData.xml";
public static String getSearchString(String keyWords){
StringBuffer sb=new StringBuffer("PREFIX fa: <http://zhumzhu.com/family#>" +
" PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>" +
" PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> "
);
sb.append(" SELECT ?father ?mother ?son ?daughter ?sister ?brother ?ancestor ?offSpring ?grandPa ");
sb.append("WHERE { ");
sb.append(" OPTIONAL { ");
sb.append(keyWords+" fa:hasFather ?father ");
sb.append(" }. ");
sb.append(" OPTIONAL { ");
sb.append(keyWords+" fa:hasMother ?mother ");
sb.append(" }. ");
sb.append(" OPTIONAL { ");
sb.append(keyWords+" fa:hasSon ?son ");
sb.append(" }. ");
sb.append(" OPTIONAL { ");
sb.append(keyWords +" fa:hasDaughter ?daughter ");
sb.append(" }. ");
sb.append(" OPTIONAL { ");
sb.append(keyWords+" fa:hasSister ?sister ");
sb.append(" }. ");
sb.append(" OPTIONAL { ");
sb.append(keyWords +" fa:hasBrother ?brother ");
sb.append(" }. ");
sb.append(" OPTIONAL { ");
sb.append(keyWords+" fa:hasAncestor ?ancestor ");
sb.append(" }. ");
sb.append(" OPTIONAL { ");
sb.append(keyWords +" fa:hasOffSpring ?offSpring ");
sb.append(" }. ");
sb.append(" OPTIONAL { ");
sb.append(keyWords +" fa:hasGrandPa ?grandPa ");
sb.append(" } ");
sb.append(" }");
System.out.println(sb);
return sb.toString();
}
public static Map getResultsList(String keyWords,String fileSchema,String fileData,String rule){
//Model m=getModel(fileSchema, fileData);//没有使用家族规则
if(rule==null) rule=rulePath;
Model rm=getModelByRules(fileSchema, fileData, rule); //使用了家族规则
String searchString=getSearchString("fa:"+keyWords);
Map map=getResultsList(searchString, rm);
return map;
}
public static Model getModel(String fileSchema,String fileData){
FileManager fm=FileManager.get();
Model schema = fm.loadModel(fileSchema);
Model data = fm.loadModel(fileData);
Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
reasoner = reasoner.bindSchema(schema);
InfModel m = ModelFactory.createInfModel(reasoner, data);
OntModel om=ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, m);
return om;
}
public static Model getModelByRules(String fileSchema,String fileData,String rulePath){
FileManager fm=FileManager.get();
Model schema = fm.loadModel(fileSchema);
Model data = fm.loadModel(fileData);
//设置新的领域规则
List rules = Rule.rulesFromURL(rulePath);
GenericRuleReasoner rea = new GenericRuleReasoner(rules);
rea.setOWLTranslation(true); // not needed in RDFS case
rea.setTransitiveClosureCaching(true);
rea =(GenericRuleReasoner) rea.bindSchema(schema);
InfModel m = ModelFactory.createInfModel(rea, data);
OntModel om=ModelFactory.createOntologyModel(OntModelSpec.OWL_MEM, m);
return om;
}
private static Map getResultsList(String searchString,Model model){
Query q=QueryFactory.create(searchString);
QueryExecution qe=QueryExecutionFactory.create(q, model);
ResultSet rs=qe.execSelect(); //执行查询
System.out.println("rs.getReaultVars--"+rs.getResultVars());
QuerySolution qs;
RDFNode father,mother,son,daughter,sister,ancestor,offSpring,brother,grandPa;
Map<String, Set<RDFNode>> map=new HashMap<String, Set<RDFNode>>();
Set<RDFNode> father_=new HashSet<RDFNode>();
Set<RDFNode> mother_=new HashSet<RDFNode>();
Set<RDFNode> son_=new HashSet<RDFNode>();
Set<RDFNode> sister_=new HashSet<RDFNode>();
Set<RDFNode> ancestor_=new HashSet<RDFNode>();
Set<RDFNode> offSpring_=new HashSet<RDFNode>();
Set<RDFNode> brother_=new HashSet<RDFNode>();
Set<RDFNode> daughter_=new HashSet<RDFNode>();
Set<RDFNode> grandPa_=new HashSet<RDFNode>();
while(rs.hasNext()){
qs= rs.nextSolution();
father=qs.get(FATHER);
mother=qs.get(MOTHER);
son=qs.get(SON);
daughter=qs.get(DAUGHTER);
sister=qs.get(SISTER);
ancestor=qs.get(ANCESTOR);
offSpring=qs.get(OFFSPRING);
brother=qs.get(BROTHER);
grandPa=qs.get(GRANDPA);
if(father!=null)
father_.add(father);
if(mother!=null)
mother_.add(mother);
if(son!=null)
son_.add(son);
if(daughter!=null)
daughter_.add(daughter);
if(sister!=null)
sister_.add(sister);
if(ancestor!=null)
ancestor_.add(ancestor);
if(offSpring!=null)
offSpring_.add(offSpring);
if(brother!=null)
brother_.add(brother);
if(grandPa!=null)
grandPa_.add(grandPa);
}
map.put(FATHER, father_);
map.put(MOTHER, mother_);
map.put(SON, son_);