关于 Prolog 的实现
about the Prolog implementation
我只想将处理 lisp 查询的功能添加到 OnLisp 文本中的初始 Prolog 实现中。
由于此功能在后面的章节中介绍(新实现),我只是从新实现中复制并进行了一些修改。
这里是 functions/macros 我 modified/added.
(=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))) ;
对此有什么想法吗?
顺便说一句,这里是 complete code
https://drive.google.com/file/d/0B7t_DLbSmjMNRVh5SDBXdUVheDg/view?usp=sharing
提前致谢。
(eval form)
在 null 词法环境 中计算 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))))
我只想将处理 lisp 查询的功能添加到 OnLisp 文本中的初始 Prolog 实现中。 由于此功能在后面的章节中介绍(新实现),我只是从新实现中复制并进行了一些修改。
这里是 functions/macros 我 modified/added.
(=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))) ;
对此有什么想法吗?
顺便说一句,这里是 complete code
https://drive.google.com/file/d/0B7t_DLbSmjMNRVh5SDBXdUVheDg/view?usp=sharing
提前致谢。
(eval form)
在 null 词法环境 中计算 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))))