#lang scribble/doc @(require scribble/manual scribble/eval scribble/basic scribble/bnf (for-label racket/base racket/contract "../main.rkt") "utils.rkt") @title[#:tag "interop"]{Racket Interoperability} @defmodule[datalog] The Datalog database can be directly used by Racket programs through this API. @examples[#:eval the-eval (define family (make-theory)) (datalog family (! (parent joseph2 joseph1)) (! (parent joseph2 lucy)) (! (parent joseph3 joseph2))) (datalog family (? (parent X joseph2))) (datalog family (? (parent joseph2 X))) (datalog family (? (parent joseph2 X)) (? (parent X joseph2))) (datalog family (! (:- (ancestor A B) (parent A B))) (! (:- (ancestor A B) (parent A C) (= D C) (ancestor D B)))) (datalog family (? (ancestor A B))) (let ([x 'joseph2]) (datalog family (? (parent x X)))) (datalog family (? (add1 1 :- X)))] @defthing[theory/c contract?]{ A contract for Datalog theories. } @defproc[(make-theory) theory/c]{ Creates a theory for use with @racket[datalog]. } @defform[(datalog thy-expr stmt ...) #:contracts ([thy-expr theory/c])]{ Executes the statements on the theory given by @racket[thy-expr]. Returns the answers to the final query as a list of substitution dictionaries or returns @racket[empty]. } @defform[(datalog! thy-expr stmt ...) #:contracts ([thy-expr theory/c])]{ Executes the statements on the theory given by @racket[thy-expr]. Prints the answers to every query in the list of statements. Returns @racket[(void)]. } Statements are either assertions, retractions, or queries. @defform[(! clause)]{ Asserts the clause. } @defform[(~ clause)]{ Retracts the literal. } @defform[(:- literal question ...)]{ A conditional clause. } @defform[(? question)]{ Queries the literal and prints the result literals. } Questions are either literals or external queries. Literals are represented as @racket[identifier] or @racket[(identifier term ...)]. External queries are represented as @racket[(identifier term ... :- term ...)], where @racket[identifier] is bound 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 datum for a constant datum, or a capitalized identifier for a variable symbol. Bound identifiers in terms are treated as datums. External queries invalidate Datalog's guaranteed termination. For example, this program does not terminate: @racketblock[ (datalog (make-theory) (! (:- (loop X) (add1 X :- Z) (loop Z))) (? (loop 1))) ]