无法在本地声明常量变量错误在Ubuntu Trusty Tahr上安装人工智能现代方法代码 - Common Lisp

时间:2014-03-08 03:50:41

标签: variables ubuntu artificial-intelligence common-lisp

我安装了人工智能和现代方法这本书的代码我在这里http://aima.cs.berkeley.edu/lisp/doc/install.html它的lisp版本即时安装btw

我在Ubuntu Trusty上使用Emacs SBCL粘液,我将代码放在〜/ .emacs.d

所以根据上面链接的说明我运行(加载“/home/w/.emacs.d/aima/code/aima.lisp”)

加载很好我得到“T”作为输出

我运行(aima-load'all)有效我得到“T”作为输出

但是当我运行(aima-compile)时,我收到了错误

Can't declare constant variable locally special: +NO-BINDINGS+
   [Condition of type SIMPLE-ERROR]

我不确定我是否理解我在声明和特殊情况下阅读Hyperspec的错误但这没有帮助。我并不反对黑客做这项工作,所以如果有人可以帮我修改代码或弄清楚它是否有emacs设置或sbcl设置我可以改变以宣布上述变量很好。错误消息是指此文件/home/w/.emacs.d/aima/code/logic/algorithms/tell-ask.lisp

本节

(defmethod ask-each ((kb literal-kb) query fn)
  "For each proof of query, call fn on the substitution that 
  the proof ends up with."
  (declare (special +no-bindings+))
  (for each s in (literal-kb-sentences kb) do
       (when (equal s query) (funcall fn +no-bindings+))))

我验证了我的aima文件夹中所有文件的所有权限都设置为读取我的用户名作为所有者的用户名作为更正的步骤....但是至于理解错误我可以使用帮助计算下一步将调试这个...代码可以在这里下载http://aima.cs.berkeley.edu/lisp/code.tar.gz,它可以轻松安装给资深的emacs / lisp用户....任何帮助都表示赞赏。

1 个答案:

答案 0 :(得分:1)

使用SBCL:

我也尝试加载AIMA代码,在SBCL中遇到同样的问题。只需注明./logic/algorithms/tell-ask.lisp中的行:

(declare (special +no-bindings+))

喜欢这样

;;(declare (special +no-bindings+))

,或者完全删除整行。然而,这就是我所做的:

(defmethod ask-each ((kb literal-kb) query fn)
  "For each proof of query, call fn on the substitution that 
  the proof ends up with."
  ;;(declare (special +no-bindings+))
  (for each s in (literal-kb-sentences kb) do
       (when (equal s query) (funcall fn +no-bindings+))))

使用SBCL运行(aims-compile)时仍会遇到问题。它会抱怨一些常量被重新定义。只需查看可能的重启并每次都选择:

0: [CONTINUE] GO ahead and change the value.

这样做多次(大约是它的6倍),最终会加载。这很可能是因为AIMA的代码非标准构建/编译系统。这可能很烦人,但另一种方法是跟踪代码并查看重新加载某些文件的原因/位置。

使用Clozure(CCL):

CCL与./utilities/utilities.lisp有不同的问题。 CCL预定义了truefalse个函数,因此您必须确保这两行:

#-(or MCL Lispworks)
直接位于(defun true ...)(defun false ...)之前的

更改为:

#-(or MCL Lispworks CCL)

同样,在相同的来源中,修改error宏内的for-each,如下所示:

(error "~a is an illegal variable in (for each ~a in ~a ...)"
   var var list)

通过这些修改,CCL似乎可以很好地加载AIMA代码。

一般来说:

重新定义常量或以某种方式绕过调试器重启是一个坏主意。最佳解决方案是仅对(defconstant ...)进行一次评估,可能将它们放在一个单独的源文件中,并确保构建系统只选择一次。

找到另一个解决方案here,它需要在宏中包含包装defconstant的调用(借用here):

(defmacro define-constant (name value &optional doc)
  (if (boundp name)
      (format t
              "~&already defined ~A~%old value ~s~%attempted value ~s~%"
              name (symbol-value name) value))
  `(defconstant ,name (if (boundp ',name) (symbol-value ',name) ,value)
     ,@(when doc (list doc))))

然后替换所有出现的defconstant,如下所示:

(defconstant +no-bindings+ '((nil))
             "Indicates unification success, with no variables.")

使用:

(define-constant +no-bindings+ '((nil))
                 "Indicates unification success, with no variables.")

如果您选择define-constant“解决方案”,请确保首先评估define-constant