2

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.
4

1 に答える 1