在 OWLready2 中创建实例会创建一个全新的类,而不是将其分配给现有类

问题描述

我正在尝试按照官方网站上的教程创建一个简单的本体。 代码运行流畅,运行此代码时一切正常:

import owlready2
owlready2.JAVA_EXE = r"my-path-to-java-exe"          

# new.owl is a non-existing file and therefore onto has no pre-defined classes
# if you kNow of any nicer way to define an ontology,I'd appreciate it

onto = get_ontology("new.owl")

with onto:
    class Drug(Thing): pass
    class number_of_tablets(Drug >> int,FunctionalProperty): pass          # Creating some properties
    class price(Drug >> float,FunctionalProperty): pass
    class price_per_tablet(Drug >> float,FunctionalProperty): pass

    rule = Imp()

    # Rule: "Drug instance ?d     AND     price of ?d is ?p     AND     drug ?d has number_of_tablets = ?n
    #        AND     ?r = ?p/?n     ->      Drug ?d has price_per_tablet = ?r"
    
    rule.set_as_rule("""Drug(?d),price(?d,?p),number_of_tablets(?d,?n),divide(?r,?p,?n) -> price_per_tablet(?d,?r)""")

    # Create an instance "drug" with properties defined in brackets
    drug = Drug(number_of_tablets = 10,price = 25.0)
    #print(drug.iri)

    # Syncing the reasoner infers new info
    sync_reasoner_pellet(infer_property_values = True,infer_data_property_values = True)

    # New property price_per_tablet is Now added to drug and we can use it normally:
    print(drug.price_per_tablet)

# Save this ontology with rules in the same folder,filename: test
onto.save(file = "test",format = "rdfxml")

问题:当我在 Protégé 中打开结果文件“test”时,我的实例“drug1”不是先前定义的类 Drug 的一部分,而是一个同名的新类 药物(我总是用斜体表示这个,以免混淆)。有趣的是,这个新类 Drug 甚至不是 owl:Thing 类的子类。

我不确定是什么问题。根据 Protégé 的说法,定义的类 Drug 具有 IRI:file:/C:/.../new#Drug,另一个Drug 具有 IRI:新#药物

当我在 Python 中检查所有描述对象的 IRI 时,它们都是同步的。

我对这里发生的事情感到非常困惑。

我检查了“测试”文件,关于这个实例的部分是:

<Drug rdf:about="#drug1">
  <rdf:type rdf:resource="http://www.w3.org/2002/07/owl#Namedindividual"/>
  <number_of_tablets rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">10</number_of_tablets>
  <price rdf:datatype="http://www.w3.org/2001/XMLSchema#decimal">25.0</price>
  <price_per_tablet rdf:datatype="http://www.w3.org/2001/XMLSchema#decimal">2.5</price_per_tablet>
</Drug>

这很令人困惑,因为当我打开著名的 Pizza 教程中的 PizzaTutorial.owl 文件时,一个实例是这样定义的:

<owl:Namedindividual rdf:about="http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#AmericanaHotPizza2">
        <rdf:type rdf:resource="http://www.semanticweb.org/pizzatutorial/ontologies/2020/PizzaTutorial#AmericanaHotPizza"/>
        <hasCaloricContent rdf:datatype="http://www.w3.org/2001/XMLSchema#integer">675</hasCaloricContent>
    </owl:Namedindividual>

发生了什么?!

一个问题:当我检查 Protégé 中的个人时,我注意到属性 number_of_tabletsprice 是作为注释添加的,而不是作为数据属性添加的。我认为这就是为什么当我删除 sync_reasoner 行时,我的 swrl 规则(已正确导出)未得出此人的 price_per_tablet 属性的原因。

评论您发现的任何错误,我是本体编程和这两种工具的初学者,非常感谢您的帮助!

解决方法

我找到了答案!

问题出在基础 IRI 中,“new.owl”是不可接受的。

IRI 必须格式化为链接 - 即使它是假的。例如,如果 IRI 是“http://test.org/new.owl”,则我的代码运行良好。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...