【问题标题】:LISP, cond returning nil everytimeLISP, cond 每次都返回 nil
【发布时间】:2014-11-15 23:13:26
【问题描述】:

为什么它显然将它添加到 lst 时总是返回 nil ???

请帮忙!

谢谢!

CL-USER 1 : 1 > (defun constants-aux (form lst)
                  (cond ((null form) lst)
                        ((eq (car form) 'implies) (constants-aux (cdr form) lst))
                        ((eq (car form) 'not) (constants-aux (cdr form) lst))
                        ((eq (car form) 'and) (constants-aux (cdr form) lst))
                        ((eq (car form) 'or) (constants-aux (cdr form) lst))
                        ((atom (car form)) (print (car form)) (cons (car form) (list lst)) (delete-duplicates lst) (constants-aux (cdr form) lst))
                        (T (constants-aux (car form) lst) (constants-aux (cdr form) lst))))
CONSTANTS-AUX

CL-USER 2 : 1 > (defun constants (form)
                   (constants-aux form nil))
CONSTANTS

CL-USER 3 : 1 > constants '(IMPLIES (NOT Q) (IMPLIES Q P))

Q 
Q 
P 
NIL

【问题讨论】:

  • 您正在调试器中工作。 cl-user 3 : 1 > 表示您处于调试级别 1。

标签: function recursion lisp common-lisp helper


【解决方案1】:

你在很多方面都做错了。

1. - 为什么要创建 -aux 函数,而您只能使用可选参数?

(defun constants (form &optional lst)
  (cond
    ((null form) lst) ...

2. - 你不需要那么多类似的分支,你可以这样写:

((find (car form) '(implies not and or))
 (constants (cdr form) lst))

3. - delete-duplicates 可以修改你的列表,但不要认为它必须这样做,即使它会,它所做的修改也不是你想要的。你应该使用它的结果。我认为您甚至收到了样式警告,在 SBCL 中,您的代码看起来像这样:

; caught STYLE-WARNING:
;   The return value of DELETE-DUPLICATES should not be discarded.

阅读警告,它会有所帮助。

我不明白您期望什么结果,所以我无法修改您的函数以使其正常工作,但我会尝试向您展示问题所在。最后两个 cond 分支的代码:

((atom (car form))
         (print (car form))
         (cons (car form) (list lst)) ;; Result is ignored
         (delete-duplicates lst)      ;; Result is ignored
         (constants-aux (cdr form) lst))

你应该写:

(constant-aux (cdr form) (delete-duplicates lst))

        (T
           (constants-aux (car form) lst) ;; Result is ignored
           (constants-aux (cdr form) lst))))

可能(取决于你想得到什么)你应该写:

(cons
   (constants-aux (car form) lst)
   (constants-aux (cdr form) lst))

4 我不是 shure,但看起来您使用 print 进行调试,只需使用 trace 代替。对于您的代码,它将为您提供非常好的信息,您的列表在执行期间发生了什么:

  0: (CONSTANTS-AUX (IMPLIES (NOT Q) (IMPLIES Q P)) NIL)
    1: (CONSTANTS-AUX ((NOT Q) (IMPLIES Q P)) NIL)
      2: (CONSTANTS-AUX (NOT Q) NIL)
        3: (CONSTANTS-AUX (Q) NIL)

Q           4: (CONSTANTS-AUX NIL NIL)
          4: CONSTANTS-AUX returned NIL
        3: CONSTANTS-AUX returned NIL
      2: CONSTANTS-AUX returned NIL
      2: (CONSTANTS-AUX ((IMPLIES Q P)) NIL)
        3: (CONSTANTS-AUX (IMPLIES Q P) NIL)
          4: (CONSTANTS-AUX (Q P) NIL)

Q             5: (CONSTANTS-AUX (P) NIL)

P               6: (CONSTANTS-AUX NIL NIL)
              6: CONSTANTS-AUX returned NIL
            5: CONSTANTS-AUX returned NIL
          4: CONSTANTS-AUX returned NIL
        3: CONSTANTS-AUX returned NIL
        3: (CONSTANTS-AUX NIL NIL)
        3: CONSTANTS-AUX returned NIL
      2: CONSTANTS-AUX returned NIL
    1: CONSTANTS-AUX returned NIL
  0: CONSTANTS-AUX returned NIL

5.如果你解释一下你期望从这段代码中得到什么样的转换,那会很容易回答。

祝你好运。

【讨论】:

  • 谢谢,改了一些东西,改用 append,效果很好。
【解决方案2】:

首先要正确格式化您的代码。示例:

(defun constants-aux (form lst)
  (cond ((null form) lst)
        ((eq (car form) 'implies) (constants-aux (cdr form) lst))
        ((eq (car form) 'not)     (constants-aux (cdr form) lst))
        ((eq (car form) 'and)     (constants-aux (cdr form) lst))
        ((eq (car form) 'or)      (constants-aux (cdr form) lst))
        ((atom (car form))
         (print (car form))
         (cons (car form) (list lst))
         (delete-duplicates lst)
         (constants-aux (cdr form) lst))
        (T
         (constants-aux (car form) lst)
         (constants-aux (cdr form) lst))))

然后你可以简化你的代码:

(defun constants-aux (form list)
  (cond ((null form) list)
        ((member (car form) '(implies not and or))
         (constants-aux (cdr form) list))
        ((atom (car form))
         (constants-aux (cdr form)
                        (adjoin (car form) list)))
        (T
         (constants-aux (car form) list)
         (constants-aux (cdr form) list))))

那么我们可能会摆脱carcdr

(defun constants-aux (form list)
  (if (consp form)
      (destructuring-bind (head . tail)
          form
        (cond ((member head '(implies not and or))
               (constants-aux tail list))
              ((atom head)
               (constants-aux tail (adjoin head list)))
              (T
               (constants-aux head list)
               (constants-aux tail list))))
    list))

然后你可以在逻辑上做一些工作,确保结果不会被忽略,确保相邻的东西是正确的,等等......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-07
    • 2015-08-21
    • 2019-02-26
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多