0

我正在研究是否可以定义游戏的基础本体,然后在此之上定义任意魔法物品,而无需更新使用它的代码或 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 戴着喷气护身符,只要持用者是精灵,Unhan 就是任何武器的伤害修正值 +1。这是由以下定义的:

{
    ?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

我必须按照所示的特定顺序使用两个推理器,这似乎很奇怪。

我做对了吗?

4

1 回答 1

1

简而言之,是的,你是。

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

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

{
    ?entity a :elf;
        :isWielding ?weapon;
        :isWearing :jetAmulet.
}
    => {?weapon :damageModifier 1.}.
于 2020-03-08T11:28:57.863 回答