dotNetRDF Reasoners 是否应该以这种方式使用?
Are dotNetRDF Reasoners meant to be used this way?
我正在研究是否可以定义游戏的基础 ontology,然后在此基础上定义任意魔法物品,而无需更新使用它的代码或 sparql 查询。
比如我有下面的测试ontology:
@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
我必须按照显示的特定顺序使用两个推理器,这似乎很奇怪。
我做的对吗?
简而言之,是的。
推理者通过将推断的三元组具体化到图中来工作;由于您的 N3 规则依赖于单个 rdfs:subClassOf 属性,因此您需要首先应用 RDFS 推理器,以便 rdfs:subClassOf 层次结构被展平。
您可以稍微简化 N3 规则,因为 RDFS 推理器应该从数据中推断 :Unhan a :elf.
。所以你的 N3 规则可以改为:
{
?entity a :elf;
:isWielding ?weapon;
:isWearing :jetAmulet.
}
=> {?weapon :damageModifier 1.}.
我正在研究是否可以定义游戏的基础 ontology,然后在此基础上定义任意魔法物品,而无需更新使用它的代码或 sparql 查询。
比如我有下面的测试ontology:
@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
我必须按照显示的特定顺序使用两个推理器,这似乎很奇怪。
我做的对吗?
简而言之,是的。
推理者通过将推断的三元组具体化到图中来工作;由于您的 N3 规则依赖于单个 rdfs:subClassOf 属性,因此您需要首先应用 RDFS 推理器,以便 rdfs:subClassOf 层次结构被展平。
您可以稍微简化 N3 规则,因为 RDFS 推理器应该从数据中推断 :Unhan a :elf.
。所以你的 N3 规则可以改为:
{
?entity a :elf;
:isWielding ?weapon;
:isWearing :jetAmulet.
}
=> {?weapon :damageModifier 1.}.