It seems that you're hoping to "change" a value. Something similar is possible but it's important to understand that Datalog cannot change property values that have been asserted, that is, that have been added as explicit facts, only add new facts derived from applying the Datalog rules to the explicit facts. This explains why you get both values in your query results: xsd:False
because you added it explicitly and xsd:True
because you added a rule that derives that value.
As described in @valerio-cocchi 's answer, facts added by reasoning are modelled as belonging to the derived
domain whereas base facts added by loading RDF graphs belong to the explicit
domain. While you could restrict your query to one or other of those domains, I think what you want is to continue querying against the domain that contains both types of fact together (the default behaviour) and to instead ensure that the property whose value you want to change is always set by Datalog rules and never asserted explicitly. That way you can achieve a change from false to true when the relevant condition is met. To do this requires a feature of RDFox's Datalog called negation-as-failure.
Using negation-as-failure to model defaults
The following example is loosely based on the Expressing Defaults and Exceptions example from the Common Uses of Rules in Practice section of the RDFox documentation. I highly recommend reading that entire section to get a feel for what rules do.
We'll start with the following explicit fact in Turtle format which just states that Tweety (who has URI :tweety
) is a citizen of the UK:
:tweety a :UKCitizen .
We would like to ensure that for each such citizen in our data store, we have a boolean property indicating whether or not they pass a basic information check. This property should be false unless we have an explicit fact to say that the citizen is vaccinated. The following pair of rules achieves this:
[?citizen, :basicInformationCheck, xsd:False] :-
[?citizen, a, :UKCitizen],
NOT [?citizen, :isVaccinated, xsd:True] .
[?citizen, :basicInformationCheck, xsd:True] :-
[?citizen, a, :UKCitizen],
[?citizen, :isVaccinated, xsd:True] .
If we load the facts and rules above into an RDFox data store and then run the SPARQL query:
SELECT ?citizen ?passesCheck
WHERE {
?citizen a :UKCitizen ;
:basicInformationCheck ?passesCheck .
}
we will see the following answer:
:tweety xsd:False .
If we then add the following triple to the data store:
:tweety :isVaccinated xsd:True
and re-run the query, we will instead see:
:tweety xsd:True .
Other issues
There are a couple of other apparent misunderstandings in your question which I hope it will help to point out.
First, you are using the predicate rdf:type
with values of xsd:True
and xsd:False
. This implies that xsd:True
is a class, which is not so. Likewise for xsd:False
. I have avoided this in the example given above by using :basicInformationCheck
in the predicate position only.
Second, your Datalog rule does not have any variables. This is perfectly valid but highly unusual. It just adds one exact triple if and only if another exact triple is present. The exact same effect could be achieved by ensuring that the base triples contain both of those exact triples or neither of them. Real-world useful Datalog rules will almost always contain variables as shown in the example.
The final (minor) thing to note is that the predicate a
is a synonym for rdf:type
. Your data uses a mixture of the two. It would be better to use one or the other consistently.