在Common LISP

时间:2015-10-30 19:59:55

标签: common-lisp

对于我的项目,我特别需要一个具有(其中包括)2个插槽的结构:

  • 一个保存数据(当前状态,结构)
  • 一个人拥有一个功能(is-state-a-solution)

该功能槽必须评估当前状态并根据它返回结果。但是,我无法找到如何正确地做到这一点。这是我的代码的一部分。

(defstruct state moves-left)

(defstruct problem
    (current-state)
    (solution (function (lambda () (null (state-moves-left :current-state)))))
)

编译时没有错误,但是当我解释它时会发生错误:

> (setq p0 (make-problem :current-state (make-state)))
> (funcall (problem-solution p0))

SYSTEM::%STRUCTURE-REF: :CURRENT-STATE is not a structure of type STATE

任何人都知道如何解决这个问题?我通常只使用常用功能,但这些结构和插槽都是硬性要求。

编辑:谢谢你的回答。在得知这是不可能的之后,我更彻底地重新阅读了这些要求,并发现这个函数实际上会得到一个参数(一个状态)。所以,代码现在有效:

(defstruct problem
    (current-state)
    (solution (function (lambda (state) (not (null (state-moves-left state))))))
)

3 个答案:

答案 0 :(得分:4)

您可以拥有单独的创建功能:

(defun create-problem (state)
  (let ((problem (make-problem :current-state state)))
    (setf (problem-solution problem)
          (lambda ()
            (null (state-moves-left (problem-current-state problem)))))
    problem))

但是:为什么不直接使用函数/方法?

(defmethod problem-solution ((p problem))
  (null (state-moves-left (problem-current-state p))))

答案 1 :(得分:2)

错误的原因是Common Lisp中的结构不能用作类:在插槽solution的函数默认值内部,无法引用结构本身的插槽(因为你是尝试使用(state-moves-left :current-state)

如果你坚持使用结构而不是类,一种可能性是用参数定义函数,并在调用函数时传递结构本身。类似的东西:

(defstruct problem
    (current-state)
    (solution (function (lambda (p) (null (state-moves-left p))))))

(let ((p0 (make-problem :current-state (make-state))))
  (funcall (problem-solution p0) p0))

答案 2 :(得分:0)

在了解到这是不可能的之后,我更彻底地重读了需求,发现这个函数实际上会接收一个参数(一个状态)。所以,代码现在可以工作了:

(解构问题 (当前状态) (解决方案(函数(lambda(状态)(不是(空(状态-移动-左状态)))))) )