Lisp 关于Prolog实现

Lisp 关于Prolog实现,lisp,common-lisp,on-lisp,Lisp,Common Lisp,On Lisp,我只想在OnLisp文本中的初始Prolog实现中添加处理lisp查询的功能。 由于这一功能是在下面的章节(一个新的实现)中引入的,所以我只是从新的实现中复制并做了一些修改 以下是我修改/添加的函数/宏 (=defun prove-query (expr binds) (case (car expr) (and (prove-and (cdr expr) binds)) (or (prove-or (cdr expr) binds)) (not (pr

我只想在OnLisp文本中的初始Prolog实现中添加处理lisp查询的功能。 由于这一功能是在下面的章节(一个新的实现)中引入的,所以我只是从新的实现中复制并做了一些修改

以下是我修改/添加的函数/宏

(=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
(eval form)
在空词汇环境中计算
表单
,这意味着
?G3160
?G3159
不绑定在调用内部。 事实上,符号是在编译期间解析的,并且在运行时不再有关于词法绑定的信息。 我提到编译,但即使您在解释器中运行代码,在运行时给定一个符号,也没有可用于解析绑定的
词法符号值
函数

好消息是,在您的情况下,您不需要将表单包装为
eval
。困难在于带有绑定的
引入了另一个级别的引用(
expr
),下面是我将如何编写
gen lisp

(=defun gen-lisp (expr binds)
  `(let ,(mapcar #'(lambda (v) `(,v (fullbind ,v ,binds)))
         (vars-in expr))
     (if ,expr
         (=values binds)
         (fail))))

你的意思是,即使它在一个LET块中,变量被绑定到某个对象?@user1461328毕竟,表单是被引用的,并且只包含符号:当你调用eval时,你必须在运行时访问绑定到符号的值,而这个值没有关于编译期间生效的词汇绑定的信息(eval不是特别的,它和任何其他函数一样工作)。问题是,如果不使用eval,只使用“expr”,我只得到一个引用列表(当你说“eval不是特别的,它和任何其他函数一样工作时,我感到困惑)。那么
中的“+”函数(let((x1))(+x1))
。如果“+”是在全局环境中计算的,那么符号“x”是如何计算的呢是否找到?可能这已经超出了我原来问题的范围。@user1461328词法范围可以在开始计算之前根据所使用的符号进行解析(如果您的代码被解释,您可以让
eval
调用一个辅助
eval env
,该辅助
eval env
使用它自己的环境数据结构,例如绑定的关联列表,但是没有太大的魔力)
,编译器可能会不断传播,但在一般情况下,内存中的特定位置用于表示由
x
指定的变量,该位置在调用
+
时发出的代码中引用。但请注意,eval通常采用引号形式。。。
(=defun gen-lisp (expr binds)
  `(let ,(mapcar #'(lambda (v) `(,v (fullbind ,v ,binds)))
         (vars-in expr))
     (if ,expr
         (=values binds)
         (fail))))