Jason
Jason

Reputation: 65

Are dotNetRDF Reasoners meant to be used this way?

I'm investigating if it's possible to define a game's base ontology and then on top of that define arbitrary magic items without requiring updates to the code or sparql queries that consume it.

For example, I have the following test 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 is wearing a jet amulet which adds +1 to the damage modifier of any weapon wielded, provided the wielder is an elf, which Unhan is. This is defined by:

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

The idea is that Unhan's scimitar's damage modifier goes up from 3 to 4 while he's wearing the amulet.

In order for the reasoner to climb up the chain of rdfs:subClassOf from underdark-elf to dark-elf to elf, I had to use two reasoners in the order shown:

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());
}

Which outputs what I'm after:

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

It seems strange that I have to use two reasoners in the specific order shown.

Am I doing it right?

Upvotes: 0

Views: 189

Answers (1)

Kal
Kal

Reputation: 1932

In short, yes you are.

The reasoners work by materializing the inferred triples into the graph; as your N3 rule relies on a single rdfs:subClassOf property you need the RDFS reasoner to be applied first so that the rdfs:subClassOf hierarchy is flattened out.

You can simplify your N3 rule a bit, as the RDFS reasoner should infer :Unhan a :elf. from the data. So your N3 rule could instead be:

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

Upvotes: 2

Related Questions