О реализации Пролога
Я просто хочу добавить возможность обрабатывать 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))))