#lang racket

(define (modify-if trans code)
  ; locates every occurrence of an if expression in code and 
  ; applies the transform function to it.

  ; remember the trans function
  (define (mf c) (modify-if trans c))
  
  (if (and (list? code) (not (null? code)) (eq? 'if (first code)))

      ; recursivley transform the parts of the if before transforming the if
      (apply trans (map mf (rest code)))
      ; Note above is better than
      ; (trans (mf (second code)) (mf (third code)) (mf (fourth code)))

      (if (list? code) 
            ; recursively transform expressions
            (map mf code) 
            ; leaf expression, leave alone
            code)
      ))


(define c1 
  '(if true
      "c1-true"
      "c1-false"
      ))

(define c2
  '(if false
       (if (and true (if false true false))
           "c11"
           "c12"
           )
       "c21"
       ))

(define (wrap-not x)
  (list 'not x) )

; transform (if c p q) into (if (not c) q p)
(define (trans-1 c p q)
  (list 'if (wrap-not c) q p)
  )

(define (test1)
  (displayln c1)
  ;(displayln (eval c1))
  (displayln (modify-if trans-1 c1))
  (displayln (eval (modify-if trans-1 c1)))
  (newline)
  (displayln c2)
  (displayln (modify-if trans-1 c2))
  )

; (test1)