1

自从我使用 LISP 以来已经有一段时间了。我现在正在使用它来制作一个属性列表来表示语义网络。不过,我似乎无法弄清楚这个基本问题,它目前阻碍了所有进展。

我们期望的输入类型如下:

     (FACT (IS-A SEAT1 SEAT))
     (FACT (IS-A L1 LEG))
     (FACT (IS-A L2 LEG))
     (FACT (IS-A L3 LEG))

仅以第一个为例。首先,我对如何在另一个这样的函数中调用一个函数有点困惑。我最初的想法是创建一个名为 fact 的函数并使用 cond 语句来查看它是使用“is-a”还是“connected”(另一种可能性),但在“is-a”或“连接”,我不确定我会如何处理。

为了至少看看我是否理解了基本概念,我决定直接跳到“is-a”部分。这基本上应该是创建对象。

    (defun is-a (name type)
        (setf (get type 'name) name)
    )

理想情况下这会起作用,但为了实际调用该函数,您需要将引号运算符放在参数前面,因为它们不是变量。所以调用看起来像:

    (is-a 'seat1 'seat)

如果没有这些引号,CLISP 会抱怨该变量没有价值。那么,如果没有引号,我将如何制作可以在输入中完全读取的内容?

4

2 回答 2

1

您的财产清单不应该被评估。它们是用来read处理和处理的。然后,您的处理函数可以挑选出像factis-a和这样的符号,connected并适当地处理它们。

但是,由于您没有评估它们,因此您不应该为factis-a或定义过程(或宏!) connected

于 2015-03-23T01:19:46.493 回答
0

这里有几种可能性。如果您尝试直接评估这些行并且您想(FACT (IS-A SEAT1 SEAT))定义一个名为seat1type的变量seat,您可以这样做:

(defvar input '(FACT (IS-A SEAT1 SEAT)))

(defmacro fact (&body expr)
  `(progn . ,expr))

(defmacro is-a (name type)
  `(defparameter ,name (make-instance ',type)))

(defclass seat () ())

(eval input)

或者,您可以seat1通过如下定义使成为哈希表中的键is-a

(defvar *objects* (make-hash-table))

(defmacro is-a (name type)
  `(setf (gethash ',name *objects*) (make-instance ',type)))

(defclass seat () ())

(eval input)

destructuring-bind

(defvar input '(FACT (IS-A SEAT1 SEAT)))

(destructuring-bind (type (operator operand-1 operand-2)) input
  (format t "It is a ~a that ~a ~a ~a~%" type operand-1 operator operand-2))

输出:

It is a FACT that SEAT1 IS-A SEAT

LOOP 宏也可以解构:

(loop for (type (operator operand-1 operand-2)) in list-of-inputs
   do
     (format t "It is a ~a that ~a ~a ~a~%" type operand-1 operator operand-2))
于 2015-03-26T11:31:45.733 回答