Dana Vrajitoru
C311 Programming Languages

General Transformation of Recursive Functions

General Transformation

Transformation

One Recursive Call

(defun factorial1 (n)
  (let ((st ()) (r 1) (ln n))
    (push ln st)
    (while st
      (cond
       ((>= ln 2)
        (setq ln (- ln 1))
        (push ln st))
       (t (setq r (* r (pop st))))))
    r))

Second Example

f(n) = 2 n2 + 3 f(n-1), 	f(1) = 2

(defun f (n)
  (if (= n 1) 2
    (+ (* 2 n n)
       (* 3 (f (- n 1))))))

Iterative Version

(defun f (n)
  (let ((st ()) (r 2) (ln 0))
    (push n st)
    (while st
      (cond
       ((> n 1)
        (setq n (- n 1))
        (push n st))
       (t (setq ln (pop st))
          (setq r (+ (* 2 ln ln)
                     (* 3 r))))))
    r))

Tree

Tree Structure

(defun root (T) "The root of the tree."
  (if T (car T)))
(defun left-subtree (T) 
  "The left subtree, also a list."
  (if (and T (cdr T))
    (car (cdr T)))) ; (cadr T)
(defun right-subtree (T) 
  "The right subtree, also a list."
  (if (> (length T) 2)
    (car (cdr (cdr T))))) ; (caddr T)

Print in Pre-Order

(defun print-preorder (T)
  "Prints the tree in preorder. Root - L - R"
  (if T
      (progn
        (mapc 'princ (list (root T) " "))
        (print-preorder (left-subtree T))
        (print-preorder (right-subtree T)))))
(setq S '(23 (51 (18) (33 (5))) (7 () (10))))
(print-preorder S)
23 51 18 33 5 7 10 nil

States

Iteration

(defun print-preor (T)
  "Prints the list in preorder without recursion."
  (let ((stackT nil) (frame nil) 
        (state nil))
    (push (cons T 'root) stackT)
    (while stackT
      (setq frame (pop stackT))
      (setq T (car frame) state (cdr frame))
      (if T
          (cond ((eq state 'root)
                 (my-print (root T) " ")
                 (push (cons T 'left) stackT))
                ((eq state 'left)
                 (push (cons T 'right) stackT)
                 (push (cons (left-subtree T) 
                             'root) stackT))
                ((eq state 'right)
                 (push (cons (right-subtree T) 
                             'root) stackT)))))))

Optimization

(defun print-preord (T)
  "An optimization of the function above."
  (let ((stackT ()))
    (while T
      (my-print (root T) " ")
      (push T stackT)
      (setq T (left-subtree T)))
    (while stackT
      (setq T (pop stackT))
      (setq T (right-subtree T))
      (while T
        (my-print (root T) " ")
        (push T stackT)
        (setq T (left-subtree T))))))