2 Tutorial

Start DrRacket and type

#lang datalog

in the Definitions window. Click Run, then click in the REPL.

>

Facts are stored in tables. If the name of the table is parent, and john is the parent of douglas, store the fact in the database with this:

> parent(john, douglas).

Each item in the parenthesized list following the name of the table is called a term. A term can be either a logical variable or a constant. Thus far, all the terms shown have been constant terms.

A query can be used to see if a particular row is in a table. Type this to see if john is the parent of douglas:

> parent(john, douglas)?

parent(john, douglas).

Type this to see if john is the parent of ebbon:

> parent(john, ebbon)?

The query produced no results because john is not the parent of ebbon. Let’s add more rows.

> parent(bob, john).

> parent(ebbon, bob).

Type the following to list all rows in the parent table:

> parent(A, B)?

parent(john, douglas).

parent(bob, john).

parent(ebbon, bob).

Type the following to list all the children of john:

> parent(john, B)?

parent(john, douglas).

A term that begins with a capital letter is a logical variable.When producing a set of answers, the Datalog interpreter lists all rows that match the query when each variable in the query is substituted for a constant. The following example produces no answers, as there are no substitutions for the variable A that produce a fact in the database. This is because no one is the parent of oneself.

> parent(A, A)?

A deductive database can use rules of inference to derive new facts. Consider the following rule:

> ancestor(A, B) :- parent(A, B).

The rule says that if A is the parent of B, then A is an ancestor of B. The other rule defining an ancestor says that if A is the parent of C, C is an ancestor of B, then A is an ancestor of B.

> ancestor(A, B) :-
    parent(A, C),
    ancestor(C, B).

In the interpreter, DrRacket knows that the clause is not complete, so by pressing Return, it doesn’t interpret the line.

Rules are used to answer queries just as is done for facts.

> ancestor(A, B)?

ancestor(ebbon, bob).

ancestor(bob, john).

ancestor(john, douglas).

ancestor(bob, douglas).

ancestor(ebbon, john).

ancestor(ebbon, douglas).

> ancestor(X,john)?

ancestor(bob, john).

ancestor(ebbon, john).

A fact or a rule can be retracted from the database using tilde syntax:

> parent(bob, john)~

> parent(A, B)?

parent(john, douglas).

parent(ebbon, bob).

> ancestor(A, B)?

ancestor(ebbon, bob).

ancestor(john, douglas).

Unlike Prolog, the order in which clauses are asserted is irrelevant. All queries terminate, and every possible answer is derived.

> q(X) :- p(X).

> q(a).

> p(X) :- q(X).

> q(X)?

q(a).