I don't think your code is correct. First of all, it's not correctly indented, which makes it difficult to read. The correct indentation should be:
(defun find-all (a list)
(if (consp list)
(if (consp (car list))
(find-all a (car list))
(if (eq a (car list)) ; if properly intended here
(cons (car(cdr list)) (find-all a(cdr list)))
(find-all a(cdr list)))))))))
Even after that I have trouble following your logic. For example, when something is a cons, then you should process both the car
and the cdr
, but you don't. I didn't go through the the debugging process, but you should.
Instead, I'd like to show you an alternative. I would suggest splitting the problem in 2 parts:
flattening the list
Since we start with a nested list but end up with a flat list, it's easier to flatten the list first. Here is a classical flatten function:
(defun flatten (sxp)
(labels
((sub (sxp res)
(cond
((null sxp) res)
((consp sxp) (sub (car sxp) (sub (cdr sxp) res)))
(t (cons sxp res)))))
(sub sxp nil)))
processing the flat list
Now, with a flat list, the rest becomes obvious, using the member
function (and calling my function find-from
to distinguish it from yours at the REPL):
(defun find-from (a lst)
(labels
((sub (lst)
(when lst
(let ((rst (cdr (member a lst))))
(when rst
(cons (car rst) (sub rst)))))))
(sub (flatten lst))))
testing
? (find-from 'a '((b a) ((c a b))))
(C B)
? (find-from 'a '(b (a a) c))
(A C)
? (find-from 'a '(b d c e))
NIL
? (find-from 'a '(b a c a e))
(C E)