我正在使用Apache Jena开发一个应用程序来处理RDF三元组和OWL本体。
问题
我目前要做的是从TDB三元组中获取模型,推断出该模型,并在推断模型中找到一些语句。这要归功于StmtIterator listStatements(Resource s, Property p, RDFNode o)
方法。然后使用一个非常简单的while(iter.hasNext())
循环来迭代语句。
比萨本体的一个例子
在此示例中,我使用的是Pizza本体here。代码如下:
public class TestInferedModel {
private static final String INPUT_FILE_NAME = "path/to/file";
private static final String URI = "http://www.co-ode.org/ontologies/pizza/pizza.owl#";
private static final Logger logger = Logger.getLogger(TestInferedModel.class);
public static void main(String[] args) {
Model model = ModelFactory.createOntologyModel();
model.read(INPUT_FILE_NAME);
Reasoner reasoner = ReasonerRegistry.getOWLReasoner();
reasoner = reasoner.bindSchema(model);
Model infmodel = ModelFactory.createInfModel(reasoner, model);
logger.debug("Model size : " + model.size() + " and inferred model size : " + infmodel.size());
// prints Model size : 2028 and inferred model size : 4881
StmtIterator iter = infmodel.listStatements();
while (iter.hasNext()) { // <----- Performance issue seems to come from this line
// Operations with the next statement
Statement stmt = iter.nextStatement();
logger.info(stmt);
}
model.close();
}
}
此处,模型大小约为两千三倍,而推断模型则由少于五千三倍组成。但是,在将StmtIterator iter = infmodel.listStatements();
编辑为StmtIterator iter = model.listStatements();
之后运行上面的代码比运行相同的代码要花费更多的时间。另外,当尝试添加参数来限制语句时,程序似乎在无限循环中运行。
我尝试添加一些logger.debug()
消息,以查看程序浪费了多少时间,而且问题似乎来自while(iter.hasNext())
行。
问题
我认为listStatements()
方法是多项式(或线性)复杂,而不是指数,不是吗?推断模型花费这么多时间是正常的吗?我怎么能避免这种情况?
我希望能够列出语句并操纵推断的模型,而无需用户等待十分钟才能得到答案......
此问题与this one类似。然而答案并没有真正帮助我理解。