dotNetRDF推理器是这样使用的吗



我正在研究是否有可能定义游戏的基本本体,然后在此基础上定义任意魔法项,而不需要更新代码或使用它的sparql查询。

例如,我有以下测试本体:

@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
@prefix : <http://rpg#>.
:underdarkElf rdfs:subClassOf :darkElf.
:darkElf rdfs:subClassOf :elf.
:scimitar :damageModifier 3.
:Unhan a :underdarkElf;
    :name "Unhan";
    :isWielding :scimitar;
    :isWearing :jetAmulet.

Unhan佩戴着一个喷气式护身符,只要持用者是精灵,任何武器的伤害修正值都会增加+1,而Unhan就是精灵

{
    ?entity a ?race;
        :isWielding ?weapon;
        :isWearing :jetAmulet.
    ?race rdfs:subClassOf :elf.
}
    => {?weapon :damageModifier 1.}.

这个想法是,当Unhan佩戴护身符时,他的弯刀伤害修正值从3增加到4。

为了让推理机从暗黑精灵爬上rdfs:subClassOf的链条,我不得不使用两个推理机,顺序如下:

var data = new Graph();
data.LoadFromFile(ontologyFilePath);
var rdfReasoner = new RdfsReasoner();
rdfReasoner.Initialise(data);
rdfReasoner.Apply(data);
var simpleReasoner = new SimpleN3RulesReasoner();
simpleReasoner.Initialise(data);
simpleReasoner.Apply(data);
var queryStr = @"
    PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
    PREFIX : <http://rpg#>
    SELECT ?name (SUM(?dm) as ?damageModifier)
    WHERE
    {
        ?entity :name ?name.
        ?entity :isWielding [:damageModifier ?dm].
    }
    GROUP BY ?name
";
var resultSet = data.ExecuteQuery(queryStr) as SparqlResultSet;
foreach (var u in resultSet)
{
    Console.WriteLine(u.ToString());
}

输出我想要的东西:

?name = Unhan , ?damageModifier = 4^^http://www.w3.org/2001/XMLSchema#integer

奇怪的是,我必须按照显示的特定顺序使用两个推理器。

我做得对吗?

简而言之,是的。

推理者通过将推断出的三元组物化到图中来工作;由于N3规则依赖于单个rdfs:subClassOf属性,因此需要首先应用rdfs推理器,以便展平rdfs:sub ClassOf层次结构。

您可以稍微简化N3规则,因为RDFS推理器应该从数据中推断出:Unhan a :elf.。所以你的N3规则可以是:

{
    ?entity a :elf;
        :isWielding ?weapon;
        :isWearing :jetAmulet.
}
    => {?weapon :damageModifier 1.}.

最新更新