Budeme musieť testovať, či ide o číslo, alebo o 3 prvkový zoznam, ktorého 2 prvok je operácia a 1. a 3. sú zase výrazy. To jasne vedie na rekurzívne riešenie. Je výhodné si vytvoriť funkcie, ktoré overia, či ide o zoznam a či je to 3 prvkový zoznam.
Aby sme overili či je argumentom funkcie trojprvkový zoznam použijeme
napr. funkciu pocet.
(defun pocet (zoz)
(cond ((null zoz) 0)
(T (+ 1 (pocet (rest zoz))))
)
)
; vráti T ak je sv operácia
(defun operacia (sv)
(OR (eq '+ sv) (eq '- sv) (eq '* sv) (eq 'div sv))
)
; Potrebujeme predikát, na zistenie či ide o zoznam. Klasický LISTP
; vracia T aj ak ide o bodka-dvojicu ktorá nie je zoznamom a to nám nevyhovuje.
(defun mylistp (zoz)
(cond ((null zoz) T)
((ATOM zoz) NIL)
(T (mylistp (rest zoz)))
)
)
Príklad použitia:
(mylistp '(1 . 2)) -> NIL
Klasický LISTP nám vráti hodnotu akú nechceme.
(LISTP '(1 . 2)) -> T
Princíp testu: ak sv je zoznam tak musí byť
3 prvkový a 2 prvok operácia a 1 a 3 prvok výrazy, inak musí byť číslo.
(defun vyraz (sv)
(cond ((NUMBERP sv) T)
((mylistp sv) (AND (= 3 (pocet sv)) (operacia (second sv)) (vyraz (first sv)) (vyraz (third sv))))
(T NIL)
)
)
Príklady použitia:
(vyraz '(1 2 3)) -> NIL
(vyraz '(1 + 3)) -> T
(vyraz '((1 + 3) . 7)) -> NIL
(vyraz 7) -> T
(vyraz '(1 + ((2 div 7) * 3))) -> T