本体建立以后,接下来就是考虑怎样去使用本体。之前已经说过,我的主要用途就是找出本体实例中的冲突(inconsistent)以及推导出新的关系,而这两者都要用到规则。笔者主要运用运用Jena提供的基于自定义规则的推理机来实现以上两点,当然你也可以使用Jena+pellet或是通过Jena的dig接口(是这样吧?意会)。
因为添加到本体中的实例数据是中文,所以尝试新建localname为中文的资源,事实证明可以。然而在基于自己编的规则推理中文名称时,如:已知 张三 isFatherOf 李四 推出 李四 hasFather 张三,结果不成功,而英文名称就可以。查了一下Java api发现InputStreamReader(InputStream in, String charsetName)还有个字符集参数,加入“UTF-8"就可以了,代码:
FileInputStream file = new FileInputStream(owl_path);//owl_path当然是owl文件路径InputStreamReader in = new InputStreamReader(file, "UTF-8");//解决中文问题 Model model = ModelFactory.createDefaultModel(); model.read(in, null);
编写推理规则时,觉得对于逆属性(owl:inverse),知道其中一对就可以推出另一对,如上文中的isFatherOf与hasFather,于是便写了如下规则:[owl_inverseOf2:(?pa owl:inverseOf ?pb)(?a ?pa ?b) ->(?b ?pb ?a)],然而测试结果显示:只有部分实现正确推理,还有一部分推理不出来,很是郁闷~于是检查了本体文件(.owl),发现在一对你关系中只有一个使用owl:inverseOf标注了,尽管在protege中两个属性的 inverse Property都标注出了其逆属性~于是又添加了一条规则[owl_inverseOf1:(?pa owl:inverseOf ?pb)->(?pb owl:inverseOf ?pa)]在一对逆属性的声明中都用owl:inverseOf,结果就正确了。
PS.为了检测规则是否能推理出预期的关系,不需要把修改后的Model写入本体,可以通过getDeductionsModel只获取推理出的模型,代码如下:
Model dedumodel=model.getDeductionsModel(); if(dedumodel==null){ System.out.println("error"); } else{ System.out.println("deduced statements:"); StmtIterator stmIter=dedumodel.listStatements(); while(stmIter.hasNext()){ Statement stm=stmIter.nextStatement(); RDFNode object=stm.getObject(); if(object instanceof Resource){ System.out.println(stm.getSubject().getLocalName()+"**"+stm.getPredicate().getLocalName()+"**"+object.asResource().getLocalName()); } else System.out.println(stm.getSubject().getLocalName()+"**"+stm.getPredicate().getLocalName()+"**"+object.toString());//获取取出uri前缀后的 } }
