1-1. 素朴な方針
未知のリストsが空だったらnilを返す
car部がアトムだったら、a と一致するかどうか判断し、真だったらtを返し、偽だったら
残りのcdr部を調べる
car部がアトムでなかったら、すなわちリストだったら、それをcar部とcdr部に分けて
さらに深く調べる。
このような方針でプログラムを作ると次のように考えがまとまっていく。
なお、(consp s) は (and (listp s) (not (atom s))) と同じである。
(defun isin (a s)
(cond ((null s) nil)
((atom (car s)) (if (equal a (car s))
t
(isin a (cdr s))))
((consp (car s)) (or (isin a (car s))
(isin a (cdr s))))))
(defun isin (a s)
(cond ((null s) nil)
((atom (car s)) (if (equal a (car s))
t
(isin a (cdr s))))
(t (or (isin a (car s)) (isin a (cdr s))))))
(defun isin (a s)
(cond ((null s) nil)
((atom (car s)) (or (equal a (car s))
(isin a (cdr s))))
(t (or (isin a (car s)) (isin a (cdr s))))))
(defun isin (a s)
(cond ((null s) nil)
((and (atom (car s)) (equal a (car s))) t)
((atom (car s)) (isin a (cdr s)))
(t (or (isin a (car s)) (isin a (cdr s))))))
ここで、(setq x '(a b (1 c 2 (d e)) (f (3 (g 4) 5) h) 6)) として
(isin 'a x)を評価すればtが返り、(isin 'k x)を評価すればnilが返ってく
るわけである。
この方針でのisin関数は、最終的に次のように整理できます。
(defun isin (a s)
(cond ((null s) nil) ;空リストである
((equal a (car s)) t) ;アトムだとしたら一致しているか
((atom (car s)) (isin a (cdr s))) ;アトムだったが一致しなかった
(t (or (isin a (car s)) (isin a (cdr s)))))) ;アトムでなかった
|