О реализации Пролога

Я просто хочу добавить возможность обрабатывать lisp-запрос в первоначальной реализации Prolog в тексте OnLisp. Поскольку эта возможность представлена ​​в следующем разделе (новая реализация), я просто скопировал из новой реализации и внес некоторые изменения.

Вот функции / макросы, которые я модифицировал / добавил.

(=defun prove-query (expr binds)
    (case (car expr)
      (and (prove-and (cdr expr) binds))
      (or (prove-or (cdr expr) binds))
      (not (prove-not (cadr expr) binds))
          (lisp (gen-lisp (cadr expr) binds)) ;;; added
      (t (prove-simple expr binds))))

(defmacro with-binds (binds expr)
  `(let ,(mapcar #'(lambda (v) `(,v (fullbind ,v ,binds)))
         (vars-in expr))
     (eval ,expr)))             ;;; copied the whole macro from new implementaion and modified this line.

(=defun gen-lisp (expr binds)  ;;; copied from new implementation but modified
  (if (with-binds binds expr)
       (=values binds)
     (fail)))

Но когда я запускаю код ниже, он жалуется, что переменная не определена.

(<- (ordered (?x)))

(<- (ordered (?x ?y . ?ys))
    (lisp (<= ?x ?y))
    (ordered (?y . ?ys)))

(with-inference (ordered (1 3 6))
  (print t))

*** - EVAL: variable ?G3159 has no value
The following restarts are available:
USE-VALUE      :R1      Input a value to be used instead of ?G3159.
STORE-VALUE    :R2      Input a new value for ?G3159.
ABORT          :R3      Abort main loop

Я проследил = gen-lisp и расширил макрос "with-binds", но ничего интересного не нашел.

(macroexpand '(with-binds '((?G3161 6) (?G3160 . 3) (?G3159 . 1)) '(<= ?G3160 ?G3159)))

(LET
 ((?G3160 (FULLBIND ?G3160 '((?G3161 6) (?G3160 . 3) (?G3159 . 1))))
  (?G3159 (FULLBIND ?G3159 '((?G3161 6) (?G3160 . 3) (?G3159 . 1)))))
 (EVAL '(<= ?G3160 ?G3159))) ;

Есть идеи по этому поводу?

Кстати, вот полный код

https://drive.google.com/file/d/0B7t_DLbSmjMNRVh5SDBXdUVheDg/view?usp=sharing

Заранее спасибо.

1 ответ

Решение

(eval form) оценивает form в нулевой лексической среде, что означает, что ?G3160 а также ?G3159 не связаны внутри звонка. Действительно, символы разрешаются во время компиляции, и больше нет информации о лексических привязках во время выполнения. Я упоминаю компиляцию, но даже если вы запустите свой код в интерпретаторе, не будет lexical-symbol-value Функция, доступная вам для разрешения привязки, заданной символом во время выполнения.

Хорошей новостью является то, что вам не нужно оборачивать форму в eval в твоем случае. Сложность в том, что with-binds вводит другой уровень цитаты (expr цитируется). Вот как бы я написал gen-lisp:

(=defun gen-lisp (expr binds)
  `(let ,(mapcar #'(lambda (v) `(,v (fullbind ,v ,binds)))
         (vars-in expr))
     (if ,expr
         (=values binds)
         (fail))))
Другие вопросы по тегам