LISP,cond每次都返回nil

Ign*_*ous 0 lisp recursion function common-lisp helper

为什么当它显然将它添加到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
Run Code Online (Sandbox Code Playgroud)

cor*_*ump 8

你在很多方面做错了.

1. - 当你可以使用可选参数时,为什么要创建-aux函数?

(defun constants (form &optional lst)
  (cond
    ((null form) lst) ...
Run Code Online (Sandbox Code Playgroud)

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

((find (car form) '(implies not and or))
 (constants (cdr form) lst))
Run Code Online (Sandbox Code Playgroud)

3. - 删除重复可以修改你的列表,但不要认为它必须,即使它会修改它不是你想要的.你应该使用它的结果.我认为你甚至有一个STYLE-WARNING,在SBCL中你的代码看起来像这样:

; caught STYLE-WARNING:
;   The return value of DELETE-DUPLICATES should not be discarded.
Run Code Online (Sandbox Code Playgroud)

阅读警告,它有所帮助.

我不明白你期望什么结果,所以我不能修改你的功能才能正常工作,但我会试着告诉你问题在哪里.你的最后两个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))
Run Code Online (Sandbox Code Playgroud)

你应该写:

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

        (T
           (constants-aux (car form) lst) ;; Result is ignored
           (constants-aux (cdr form) lst))))
Run Code Online (Sandbox Code Playgroud)

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

(cons
   (constants-aux (car form) lst)
   (constants-aux (cdr form) lst))
Run Code Online (Sandbox Code Playgroud)

4我不是害羞,但看起来你使用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
Run Code Online (Sandbox Code Playgroud)

5.如果你解释你从这个代码期待什么转型这将是真正easyer回答.

祝好运.