2014-09-22 142 views
0

为什么当它明显加入到lst时总会返回nil ???LISP,cond每次都返回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 
+2

您正在调试器中工作。 'cl-user 3:1>'表示您处于调试级别1. – 2014-09-22 08:33:29

回答

8

你在这么多方面做错了。

1. - 为什么在只使用可选参数时创建-aux函数?

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

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

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

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

我不是很舒服,但它看起来像使用打印进行调试,只需使用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.这将是真正easyer回答,如果你解释你从这个代码期待什么转型。

好运。

+0

谢谢,改变了一些东西并使用append代替,就像魅力一样。 – Ignacious 2014-09-22 05:55:54

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

然后你就可以工作的逻辑一点,确保结果不被忽略,确保毗事情是正确的,等等...