Demonstrate Racket/Datalog interop more and add unsyntax
This commit is contained in:
parent
d6a3d27e54
commit
744fde1fa8
|
@ -99,7 +99,7 @@
|
||||||
[terms (listof term/c)])]
|
[terms (listof term/c)])]
|
||||||
[literal-equal? (literal? literal? . -> . boolean?)]
|
[literal-equal? (literal? literal? . -> . boolean?)]
|
||||||
[struct external ([srcloc srcloc/c]
|
[struct external ([srcloc srcloc/c]
|
||||||
[predicate-sym symbol?]
|
[predicate-sym any/c]
|
||||||
[predicate procedure?]
|
[predicate procedure?]
|
||||||
[arg-terms (listof term/c)]
|
[arg-terms (listof term/c)]
|
||||||
[ans-terms (listof term/c)])]
|
[ans-terms (listof term/c)])]
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
The Datalog database can be directly used by Racket programs through this API.
|
The Datalog database can be directly used by Racket programs through this API.
|
||||||
|
|
||||||
@examples[#:eval the-eval
|
@examples[#:eval the-eval
|
||||||
|
#:escape UNSYNTAX-NOT
|
||||||
(define family (make-theory))
|
(define family (make-theory))
|
||||||
|
|
||||||
(datalog family
|
(datalog family
|
||||||
|
@ -25,6 +26,17 @@ The Datalog database can be directly used by Racket programs through this API.
|
||||||
(datalog family
|
(datalog family
|
||||||
(? (parent X joseph2)))
|
(? (parent X joseph2)))
|
||||||
|
|
||||||
|
(datalog family
|
||||||
|
(? (parent X (string->symbol "joseph2"))))
|
||||||
|
|
||||||
|
(let ([atom 'joseph2])
|
||||||
|
(datalog family
|
||||||
|
(? (parent X #,atom))))
|
||||||
|
|
||||||
|
(let ([table 'parent])
|
||||||
|
(datalog family
|
||||||
|
(? (#,table X joseph2))))
|
||||||
|
|
||||||
(datalog family
|
(datalog family
|
||||||
(? (parent joseph2 X)))
|
(? (parent joseph2 X)))
|
||||||
|
|
||||||
|
@ -48,7 +60,9 @@ The Datalog database can be directly used by Racket programs through this API.
|
||||||
(? (parent x X))))
|
(? (parent x X))))
|
||||||
|
|
||||||
(datalog family
|
(datalog family
|
||||||
(? (add1 1 :- X)))]
|
(? (add1 1 :- X)))
|
||||||
|
(datalog family
|
||||||
|
(? (#,(λ (x) (+ x 1)) 1 :- X)))]
|
||||||
|
|
||||||
@defthing[theory/c contract?]{ A contract for Datalog theories. }
|
@defthing[theory/c contract?]{ A contract for Datalog theories. }
|
||||||
|
|
||||||
|
@ -75,9 +89,23 @@ Statements are either assertions, retractions, or queries.
|
||||||
@defform[(? question)]{ Queries the literal and prints the result literals. }
|
@defform[(? question)]{ Queries the literal and prints the result literals. }
|
||||||
|
|
||||||
Questions are either literals or external queries.
|
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.
|
Literals are represented as @racket[identifier] or @racket[(table term ...)].
|
||||||
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.
|
|
||||||
|
A table is either an identifier or @RACKET[#,expr] where @racket[expr]
|
||||||
|
evaluates to a symbol.
|
||||||
|
|
||||||
|
External queries are represented as @racket[(ext-table term ... :-
|
||||||
|
term ...)], where @racket[ext-table] is an identifier bound to a
|
||||||
|
procedure or @RACKET[#,expr] where @racket[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 @RACKET[#,expr] where @racket[expr]
|
||||||
|
evaluates to a constant datum. Bound identifiers in terms are treated
|
||||||
|
as the datum they are bound to.
|
||||||
|
|
||||||
External queries invalidate Datalog's guaranteed termination. For example, this program does not terminate:
|
External queries invalidate Datalog's guaranteed termination. For example, this program does not terminate:
|
||||||
@racketblock[
|
@racketblock[
|
||||||
|
|
|
@ -139,44 +139,53 @@
|
||||||
(define-syntax (datalog-literal/bind stx) (datalog-literal/b stx #t))
|
(define-syntax (datalog-literal/bind stx) (datalog-literal/b stx #t))
|
||||||
(define-syntax (datalog-literal/ref stx) (datalog-literal/b stx #f))
|
(define-syntax (datalog-literal/ref stx) (datalog-literal/b stx #f))
|
||||||
|
|
||||||
(define-for-syntax (datalog-literal/b stx binding?)
|
(begin-for-syntax
|
||||||
|
(define-syntax-class table-id
|
||||||
|
#:literals (unsyntax)
|
||||||
|
(pattern sym:id
|
||||||
|
#:attr ref #''sym
|
||||||
|
#:attr val #'sym)
|
||||||
|
(pattern (unsyntax sym:expr)
|
||||||
|
#:attr ref #'sym
|
||||||
|
#:attr val #'sym))
|
||||||
|
(define (datalog-literal/b stx binding?)
|
||||||
(syntax-parse
|
(syntax-parse
|
||||||
stx
|
stx
|
||||||
#:literals (:-)
|
#:literals (:-)
|
||||||
[(_ sym:id)
|
[(_ sym:table-id)
|
||||||
(syntax-property
|
(syntax-property
|
||||||
(quasisyntax/loc #'sym
|
(quasisyntax/loc #'sym
|
||||||
(literal #,(srcloc-list #'sym) 'sym empty))
|
(literal #,(srcloc-list #'sym) sym.ref empty))
|
||||||
(if binding? 'disappeared-binding 'disappeared-use)
|
(if binding? 'disappeared-binding 'disappeared-use)
|
||||||
(syntax-local-introduce #'sym))]
|
(syntax-local-introduce #'sym))]
|
||||||
[(_ (~and tstx (sym:id arg ... :- ans ...)))
|
[(_ (~and tstx (sym:table-id arg ... :- ans ...)))
|
||||||
(quasisyntax/loc #'tstx
|
(quasisyntax/loc #'tstx
|
||||||
(external #,(srcloc-list #'tstx) 'sym sym
|
(external #,(srcloc-list #'tstx) 'sym sym.val
|
||||||
(list (datalog-term arg) ...)
|
(list (datalog-term arg) ...)
|
||||||
(list (datalog-term ans) ...)))]
|
(list (datalog-term ans) ...)))]
|
||||||
[(_ (~and tstx (sym:id e ...)))
|
[(_ (~and tstx (sym:table-id e ...)))
|
||||||
(syntax-property
|
(syntax-property
|
||||||
(quasisyntax/loc #'tstx
|
(quasisyntax/loc #'tstx
|
||||||
(literal #,(srcloc-list #'tstx) 'sym
|
(literal #,(srcloc-list #'tstx) sym.ref
|
||||||
(list (datalog-term e)
|
(list (datalog-term e)
|
||||||
...)))
|
...)))
|
||||||
(if binding? 'disappeared-binding 'disappeared-use)
|
(if binding? 'disappeared-binding 'disappeared-use)
|
||||||
(syntax-local-introduce #'sym))]))
|
(syntax-local-introduce #'sym))])))
|
||||||
|
|
||||||
(define-syntax (datalog-literal-var-selector stx)
|
(define-syntax (datalog-literal-var-selector stx)
|
||||||
(syntax-parse
|
(syntax-parse
|
||||||
stx
|
stx
|
||||||
#:literals (:-)
|
#:literals (:-)
|
||||||
[(_ sym:id)
|
[(_ sym:table-id)
|
||||||
(quasisyntax/loc #'sym (λ (l) (hasheq)))]
|
(quasisyntax/loc #'sym (λ (l) (hasheq)))]
|
||||||
[(_ (~and tstx (sym:id arg ... :- ans ...)))
|
[(_ (~and tstx (sym:table-id arg ... :- ans ...)))
|
||||||
(quasisyntax/loc #'tstx
|
(quasisyntax/loc #'tstx
|
||||||
(match-lambda
|
(match-lambda
|
||||||
[(external _srcloc _predsym _pred args anss)
|
[(external _srcloc _predsym _pred args anss)
|
||||||
(terms->hasheq (list (datalog-term arg) ...
|
(terms->hasheq (list (datalog-term arg) ...
|
||||||
(datalog-term ans) ...)
|
(datalog-term ans) ...)
|
||||||
(append args anss))]))]
|
(append args anss))]))]
|
||||||
[(_ (~and tstx (sym:id e ...)))
|
[(_ (~and tstx (sym:table-id e ...)))
|
||||||
(quasisyntax/loc #'tstx
|
(quasisyntax/loc #'tstx
|
||||||
(match-lambda
|
(match-lambda
|
||||||
[(literal _srcloc _predsym ts)
|
[(literal _srcloc _predsym ts)
|
||||||
|
@ -194,6 +203,7 @@
|
||||||
(define-syntax (datalog-term stx)
|
(define-syntax (datalog-term stx)
|
||||||
(syntax-parse
|
(syntax-parse
|
||||||
stx
|
stx
|
||||||
|
#:literals (unsyntax)
|
||||||
[(_ sym:id)
|
[(_ sym:id)
|
||||||
(cond
|
(cond
|
||||||
[(identifier-binding #'sym 0)
|
[(identifier-binding #'sym 0)
|
||||||
|
@ -205,6 +215,9 @@
|
||||||
[else
|
[else
|
||||||
(quasisyntax/loc #'sym
|
(quasisyntax/loc #'sym
|
||||||
(constant #,(srcloc-list #'sym) 'sym))])]
|
(constant #,(srcloc-list #'sym) 'sym))])]
|
||||||
|
[(_ (unsyntax sym:expr))
|
||||||
|
(quasisyntax/loc #'sym
|
||||||
|
(constant #,(srcloc-list #'sym) sym))]
|
||||||
[(_ sym:expr)
|
[(_ sym:expr)
|
||||||
(quasisyntax/loc #'sym
|
(quasisyntax/loc #'sym
|
||||||
(constant #,(srcloc-list #'sym) sym))]))
|
(constant #,(srcloc-list #'sym) sym))]))
|
||||||
|
|
|
@ -16,6 +16,23 @@
|
||||||
=>
|
=>
|
||||||
(list (hasheq 'X 'joseph3))
|
(list (hasheq 'X 'joseph3))
|
||||||
|
|
||||||
|
(datalog parent
|
||||||
|
(? (parent X (string->symbol "joseph2"))))
|
||||||
|
=>
|
||||||
|
(list (hasheq 'X 'joseph3))
|
||||||
|
|
||||||
|
(let ([atom 'joseph2])
|
||||||
|
(datalog parent
|
||||||
|
(? (parent X #,atom))))
|
||||||
|
=>
|
||||||
|
(list (hasheq 'X 'joseph3))
|
||||||
|
|
||||||
|
(let ([table 'parent])
|
||||||
|
(datalog parent
|
||||||
|
(? (#,table X joseph2))))
|
||||||
|
=>
|
||||||
|
(list (hasheq 'X 'joseph3))
|
||||||
|
|
||||||
(datalog parent
|
(datalog parent
|
||||||
(? (parent joseph2 X)))
|
(? (parent joseph2 X)))
|
||||||
=>
|
=>
|
||||||
|
@ -59,6 +76,11 @@
|
||||||
=>
|
=>
|
||||||
(list (hasheq 'X 2))
|
(list (hasheq 'X 2))
|
||||||
|
|
||||||
|
(datalog parent
|
||||||
|
(? (#,(λ (x) (+ x 1)) 1 :- X)))
|
||||||
|
=>
|
||||||
|
(list (hasheq 'X 2))
|
||||||
|
|
||||||
(let ()
|
(let ()
|
||||||
(define new-parent
|
(define new-parent
|
||||||
(with-input-from-bytes
|
(with-input-from-bytes
|
||||||
|
|
Loading…
Reference in New Issue
Block a user