Racket のマクロ システムを使用したことがないので、無知をお許しください。基本的に次のように、Racket の Datalog システムでルールを動的に定義しようとしています。
(datalog rules (! (:- c a b)))
このようなものをコードに直接入れれば、すべてうまくいきます。ただし、これらのルールを動的に生成したいと考えています。通常の関数では、次のようにします。
(datalog rules (! (apply :- conclusion premises)))
しかしdatalog
、!
と:-
はすべてマクロであるため、これは不可能です。
私の解決策は、このマクロを書くことでした:
(define-syntax (make-rule stx)
(syntax-case stx ()
((_ premises conclusion)
#`(datalog rules (! (:- ,conclusion ,@(map (lambda (x) `,x) premises)))))))
次に、次のように呼び出されます。
(make-rule '(a b) 'c)
ただし、これが実行されている間、Datalog データベースにクエリを実行しても、a
との両方b
が true の場合は何もレンダリングされません。
構文オブジェクトを二重引用符で囲んでみました。これにより、何が出力されているかを確認できました。これは次のとおりです。
'(datalog rules (! (:- c a b)))
だから...コードに直接入力するだけで、正確に何が機能し、機能するのでしょうか。ここで何が起こっているのですか?これはある種の衛生的なマクロのことですか?本当にわからない。
ありがとう!
編集:これは、問題の完全な実行可能な例です。
#lang racket
(require datalog)
(define rules (make-theory))
(define-syntax (make-rule stx)
(syntax-case stx ()
((_ premises conclusion)
#`(datalog rules (! (:- ,conclusion ,@(map (lambda (x) `,x) premises)))))))
(make-rule '(a b) 'c)
(datalog rules (? c)) ;;Does not work.
(datalog rules (! (:- c a b)))
(datalog rules (! a) (! b))
(datalog rules (? c)) ;;Works.