3


私はLispを初めて使用しますが、ここに私の質問があります。
次のようなリストがあります。

((a ((length 3) (size 5))) (b ((length 5) (size 7))))...

上記のリストは単なるサンプルです。
私が試しているのは、findたとえばデータベースクエリのように機能する関数です。

(find (and (gt length 4) (lt size 8)))

この場合、上記の関数がb私に役立つはずです。この関数の条件付き引数は、andまたはで展開できることに注意してくださいor...
私はいくつかの調査を行いeval、これを何らかの形で助けることができることを知っていますが、それが正確にどのように機能するかはわかりません。
誰かが私に例を見せたり、これについてのヒントを教えてもらえますか?

ありがとうございました

4

2 に答える 2

5

これには eval を使用しません。しかし、そうするのは比較的簡単でしょう。

一連のアイテムがあります:

((a ((length 3) (size 5)))
 (b ((length 5) (size 7))))

次のようなテストの説明があります。

(and (> length 4) (< size 8))

今、あなたは

(my-equal '(and (> length 4) (< size 8)) '((length 5) (size 7))

本当です。

したがって、タスクは書くことMY-EQUALです。通常、再帰関数として記述します。

しかし、 でそれを行いたい場合はEVAL、比較的簡単になります。

このフォームを評価したい:

(let ((length 5) (size 7))
  (and (> length 4) (< size 8)))

これで、MY-EQUAL を簡単に記述できるはずです。

その後、次のように使用できます

(find term sequence :test #'my-equal :key #'second)

ストリームから読み取った任意のコードの評価は、セキュリティ リスクであることに注意してください。

ボーナス

COMPILEEVAL の代わりに使用できます。

(defun lookup (v bindings)
  (let ((result (assoc v bindings)))
    (if result
        (second result)
      (error "variable ~a not known" v))))

(defparameter *query-operators* '(and or > < =))

(defun generate-query-code (q bindings)
  (cond ((numberp q) q)
        ((symbolp q) `(lookup ',q ,bindings))
        ((consp q)
         (destructuring-bind (op . args)
             q
           (if (member op *query-operators*)
               `(,op ,@(mapcar (lambda (arg)
                                 (generate-query-code arg bindings))
                               args))
             (error "Unknown op ~a" op))))))

(defun compile-query (q)
  (compile nil
           (let* ((bindings (gensym "bindings"))
                  (code (generate-query-code q bindings)))
             `(lambda (,bindings)
                ,code))))

(defun find-query (query descriptions)
  (find-if (compile-query query)
           descriptions
           :key #'second))

例:

CL-USER 39 > (find-query '(and (> length 4) (< size 8))
                         '((a ((length 3) (size 5)))
                           (b ((length 5) (size 7)))))
(B ((LENGTH 5) (SIZE 7)))
于 2012-12-09T06:44:24.847 に答える
4

このブログ投稿はあなたの問題に関連しているようです: http://xach.livejournal.com/131456.html

length(レコードごとにとと 実際の値の間の小さなマッピングで展開する必要があるsizeため、各レコードでクロージャ チェーンを呼び出すことができます)

于 2012-12-09T09:12:12.563 に答える