We are going to learn how to express rules in N3, which will allow us to do all kinds of things. A simple rule might say something like (in some central heating vocabulary) "If the thermostat temperature is high, then the heating system power is zero", or

{ :thermostat :temp :high } log:implies { :heating :power "0" } .

The curly brackets here enclose a set of statements. Until this point, all
statements in each file have been effectively in one bucket. They are all
generated when the file is parsed, and stored in a store on an equal footing.
In a rule, however, we need to talk about hypothetical statements:
*If* this *were* the case *then* that *would* be
the case. The statements within the brackets are not asserted like the other
ones in the file. In the case above, the file does not say that the
thermostat temperature is high. It just says that the left-hand formula
implies the right-hand formula.

You see that, apart from the fact that the subject and object of the
statement are formulae, the line above is just a single statement.
`log:implies`

is a special predicate which links formulae. The
statement is a fact. Rules are in general facts, and on the semantic web they
may or not be used by various programs at various times to figure things
out.

The curly brackets are important. They do take us out of the things we can represent using the current RDF/XML OWL specifications. ((Formulae are (2003/2) a longer-term issue for the RDF Core group). Cwm will in most cases serialize formulae using an XML syntax which is not standard.

In fact, formulae in N3 are more than just sets of statements. They also
allow declarations of variables. A variable is like just a symbol (such as
`:x`

or `var:Y`

) except it is used to stand for other
symbols. There are two types. A "`forAll`

" or universal
variable, declared like this,

@forAll :x.

{ :thermostat :temp :x } log:implies { :cooling :power :x } .

means that all this information is true even if the symbol ":x" is
replaced consistently by something else. This is of course what you want for
a rule which implies something generally about anything. The
`"this"`

indicates the scope of the variable - it in fact stands
for the formula in which it is, in this case the outermost formula of the
document. In most cases for simple rules, the variables are quantified in the
scope of the document, but when things get nested, it is wise to think about
what you mean. We don't deal with it in detail here. Mathematically, the
formula above might be written

$\∀x\left(\mathrm{temp}\right(\mathrm{thermostat},x)\⇒\mathrm{power}(\mathrm{cooling},x\left)\right)$

A formula can also have "`forSome`

", or existential,
variables. They are declared as in

@forSome :a.

:Joe :home :a.

:a :phone "555-1212".

This means that there is something which is Joe's home and has the given phone number. We've been doing this all along, though, surely, with blank nodes. Indeed - most times that an existential variable is used it is actually implicit in the [bracket] syntax.

:Joe :home [ :phone "555-1212" ].

Each pair of square brackets actually stands for an unnamed existential variable. Cwm will generally use square brackets on output when it can - if there are loops then one has to use explicit variables.

@forSome :a.

:Joe :home :a.

:a :owner :Joe.

:a :phone "555-1212".

So far we have introduce variables for rules using
`@forAll`

. We have introduced existential variables (blank
nodes) with `@forSome`

. These are extensions to the RDF world to allow N3 to express rules.
There are shortcuts under certain circumstances, which avoid you having to type
them.

When a variable is universally quantified in not the formula itself but the surrounding formula, then you can just use ?x. This is in fact what you want for rules which don't have nested formulae inside the antecedent.

So instead of

@forAll :x, :y.

{ :x :parent :y } => { :y :child :x }.

you can write

{ ?x parent ?y } => { ?y :child ?x }.

which means just the same. We will use this all the time when writing simple rules. If you need the same variable to appear at several levels, then you can't use this form.

The other shortcut is that if you have existentially qualified variables in the scope of the whole document, then you can use _:a and so on. (This is the same as the ntriples notation)

So instead of writing

@forSome :a, :b.

:a :hates :b. :b :loves :a.

you could just write

_:a :hates _:b. _:b :loves _:a.

In practice this is very often used in ntriples but in N3, you can normally use the [] syntax to avoid using any variables at all.

When it is used as a predicate (verb) in N3, `log:implies`

and
=> are the same; `owl:equivalentTo`

and = are the same.

So, having gone into a few details of universal and existential identifiers, what we are left with is a pretty simple rule language, which is still a fairly straightforward extension of RDF.

{?x family:parent ?y. ?y family:brother ?z} => {?x family:uncle ?z}.

(Always remember the dot after the rule.)

Now let's learn how to process them.