在LISP中输入参数而不使用quote运算符(属性列表/语义网络/基本函数)

在LISP中输入参数而不使用quote运算符(属性列表/语义网络/基本函数),lisp,common-lisp,property-list,Lisp,Common Lisp,Property List,我已经有一段时间没用LISP了。我现在用它来制作一个属性列表来表示一个语义网络。但我似乎无法解决这个基本问题,目前它阻碍了所有进展 我们期望的输入类型如下: (FACT (IS-A SEAT1 SEAT)) (FACT (IS-A L1 LEG)) (FACT (IS-A L2 LEG)) (FACT (IS-A L3 LEG)) 以第一个为例。首先,我有点困惑于如何在另一个函数中调用这样的函数。我最初的想法是创建一个名为fact的函数,并使用cond语

我已经有一段时间没用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”或“connected”之前有一个额外的括号,我不确定该如何处理

为了至少看看我是否把基本想法记下来,我决定直接跳到“is-a”部分。这基本上应该是创建对象

    (defun is-a (name type)
        (setf (get type 'name) name)
    )
理想情况下,这会起作用,但为了实际调用函数,需要将quote运算符放在参数前面,因为它们不是变量。所以这个电话看起来像:

    (is-a 'seat1 'seat)

如果没有这些引号,CLISP会抱怨变量没有值。那么,我该如何制作一些可以完全按照上面所示在输入中读取的东西,而不使用引号呢?

您的属性列表不需要进行评估。它们应该被
读取和处理。然后,您的处理功能可以选择符号,如
fact
is-a
connected
,并对其进行适当处理


但是,由于您没有对它们进行评估,因此不应该为
事实
is-a
、或
连接的
定义过程(或宏!),这里有一些可能性。如果您试图直接计算这些行,并且希望
(事实(IS-A SEAT1 SEAT))
定义一个名为
SEAT1
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)
(defvar *objects* (make-hash-table))

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

(defclass seat () ())

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

(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)
(defvar *objects* (make-hash-table))

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

(defclass seat () ())

(eval input)
解构绑定

(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 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))

那么,您是否建议在每一行中进行更多的阅读,然后进行分析,以了解需要对其进行哪些操作?让我感到困惑的是如何处理这些查询。我的第一个倾向是简单地在查询中使用给定的值来查看它是否存在
code
(查询值(is-a-value-seat))
code
应该返回:seat1您应该一次阅读一个表单(而不是一行),但粗略的想法是正确的。我不记得在我之前的课程中看到过任何关于表单的内容。我现在得去调查一下。谢谢你的帮助。“你的属性列表不是用来评估的。它们是用来读取和处理的。”我同意,只是这些属性列表看起来不像是逻辑公式。在这种情况下,定义一个事实宏来断言其中的公式(或使其以其他方式被解释为适当的)可能实际上是合适的。首先让算法部分工作。