▼ |  | Datalog: Deductive Database Programming

1 | Datalog Module Language
2 | Tutorial
3 | Parenthetical Datalog Module Language
4 | Racket Interoperability
5 | Acknowledgments

On this page:

theory/ c
make-theory
write-theory
read-theory
datalog
datalog!
!
~
: -
?

top ← prev up next →

### 4`` Racket Interoperability

(require datalog) | package: datalog

The Datalog database can be directly used by Racket programs through this API.

Examples:

> > (define family (make-theory))
> > (datalog family
> (! (parent joseph2 joseph1))
> (! (parent joseph2 lucy))
> (! (parent joseph3 joseph2)))
> '()
> > (datalog family
> (? (parent X joseph2)))
> '(#hasheq((X . joseph3)))
> > (datalog family
> (? (parent X (string->symbol "joseph2"))))
> '(#hasheq((X . joseph3)))
> > (let ([atom 'joseph2])
> (datalog family
> (? (parent X #,atom))))
> '(#hasheq((X . joseph3)))
> > (let ([table 'parent])
> (datalog family
> (? (#,table X joseph2))))
> '(#hasheq((X . joseph3)))
> > (datalog family
> (? (parent joseph2 X)))
> '(#hasheq((X . joseph1)) #hasheq((X . lucy)))
> > (datalog family
> (? (parent joseph2 X))
> (? (parent X joseph2)))
> '(#hasheq((X . joseph3)))
> > (datalog family
> (! (:- (ancestor A B)
> (parent A B)))
> (! (:- (ancestor A B)
> (parent A C)
> (= D C)
> (ancestor D B))))
> '()
> > (datalog family
> (? (ancestor A B)))
> '(#hasheq((A . joseph3) (B . joseph2))
> #hasheq((A . joseph2) (B . lucy))
> #hasheq((A . joseph2) (B . joseph1))
> #hasheq((A . joseph3) (B . lucy))
> #hasheq((A . joseph3) (B . joseph1)))
> > (let ([x 'joseph2])
> (datalog family
> (? (parent x X))))
> '(#hasheq((X . joseph1)) #hasheq((X . lucy)))
> > (datalog family
> (? (add1 1 :- X)))
> '(#hasheq((X . 2)))
> > (datalog family
> (? (add1 X :- 2)))
> '()
> > (datalog family
> (? (#,(λ (x) (+ x 1)) 1 :- X)))
> '(#hasheq((X . 2)))

> value theory/c : contract?

A contract for Datalog theories.

> procedure (make-theory) → theory/c

Creates a theory for use with datalog.

> procedure (write-theory t) → void
> t : theory/c

Writes a theory to the current output port. Source location information is lost.

> procedure (read-theory) → theory/c

Reads a theory from the current input port.

> > syntax
> > (datalog thy-expr
> > stmt ...)
> | thy-expr |  | : |  | theory/c

Executes the statements on the theory given by thy-expr. Returns the answers to the final query as a list of substitution dictionaries or returns empty.

> > syntax
> > (datalog! thy-expr
> > stmt ...)
> | thy-expr |  | : |  | theory/c

Executes the statements on the theory given by thy-expr. Prints the answers to every query in the list of statements. Returns (void).

Statements are either assertions, retractions, or queries.

> syntax (! clause)

Asserts the clause.

> syntax (~ clause)

Retracts the literal.

> syntax (:- literal question ...)

A conditional clause.

> syntax (? question)

Queries the literal and prints the result literals.

Questions are either literals or external queries.

Literals are represented as identifier or (table term ...).

A table is either an identifier or #,expr where expr evaluates to a symbol.

External queries are represented as (ext-table term ... :- term ...), where ext-table is an identifier bound to a procedure or #,expr where expr evaluates to a procedure that when given the first set of terms as arguments returns the second set of terms as values.

A term is either a non-capitalized identifiers for a constant symbol, a Racket expression for a constant datum, or a capitalized identifier for a variable symbol, or #,expr where expr evaluates to a constant datum. Bound identifiers in terms are treated as the datum they are bound to.

External queries fail if any logic variable is not fully resolved to a datum on the Datalog side. In other words, unbound logic variables never flow to Racket.

External queries invalidate Datalog’s guaranteed termination. For example, this program does not terminate:

> (datalog (make-theory)
> (! (:- (loop X)
> (add1 X :- Z)
> (loop Z)))
> (? (loop 1)))

top ← prev up next →