Generalized rules
We are now able to execute rules.
However, what's the benefit of a long rule when we could have written a simple triple?
We need reusable rules
Looking back at the “Cindy knows” rule, we might realize that it was not that great after all.
Suppose Cindy also knows Eliza and Kate. Do you think the rule will work out?
Example: “Cindy also knows Eliza and Kate”
Execute this command if you have downloaded the example files:
eye cindy-eliza-kate.n3 cindy-rule.n3 --query query-all.n3 --nope
Alternatively, execute this command to use the online example files:
eye http://n3.restdesc.org/n3/cindy-eliza-kate.n3 http://n3.restdesc.org/n3/cindy-rule.n3 --query http://n3.restdesc.org/n3/query-all.n3 --nope
Well, the rule does work out, but only as much as it can. The reasoner returns our 3 initial facts, and the only additional thing it could deduce: that John knows Cindy.
Variables enable reusable rules
But it shouldn't be just John. Eliza and Kate also know Cindy.
In fact, everyone that Cindy knows, also knows her. (At least in the foaf
sense of "knows".)
To state this, we need a way to express "everyone".
In predicate logic, an operator called the universal quantificator exists, which looks like this:
The above reads "for all x, P of x implies Q of x" or, more naturally: "if P is true for x, so is Q".
We can also express this in N3.
{
ppl:Cindy foaf:knows ?someone.
}
=>
{
?someone foaf:knows ppl:Cindy.
}.
In this snippet, ?someone
is a variable which will be filled in when the rule is executed. Variables in N3 can be recognized by a leading question mark ?
.
Note: you may have seen I sometimes omit namespace declarations from snippets. This is only for clarity — a valid Notation3 document requires all used namespaces be declared.
Example: the “Cindy knows” rule with variable
Execute this command if you have downloaded the example files:
eye cindy-eliza-kate.n3 cindy-rule-var.n3 --query query-all.n3 --nope
Alternatively, execute this command to use the online example files:
eye http://n3.restdesc.org/n3/cindy-eliza-kate.n3 http://n3.restdesc.org/n3/cindy-rule-var.n3 --query http://n3.restdesc.org/n3/query-all.n3 --nope
This is where rules really get interesting. Variables open the gate to lots of new facts.
You may have wondered why Cindy is still part of the rule.
After all, if John would know Eliza, she also knows John, right? Let's fix that.
{
?personA foaf:knows ?personB.
}
=>
{
?personB foaf:knows ?personA.
}.
We have now generalized the rule for all persons. Note there is no limit to the number of variables you can use, and you can choose their name. Try to play around with the next example, which shows the generalized rule.
Example: generalized "knows" rule
Execute this command if you have downloaded the example files:
eye friends.n3 knows-rule.n3 --query query-all.n3 --nope
Alternatively, execute this command to use the online example files:
eye http://n3.restdesc.org/n3/friends.n3 http://n3.restdesc.org/n3/knows-rule.n3 --query http://n3.restdesc.org/n3/query-all.n3 --nope
Next
We continue to the next level and reason about predicate classes.