

(define pair2list
  (lambda (p)
    (if
      (null? (car p))
      '()
      (cons
        (cons (caar p) (cadr p))
        (pair2list (cons (cdar p) (cddr p)))
      )
    )
  )
)

(define list2pair
  (lambda (l)
    (if
      (null? l)
      (cons '() '())
      (let
        ((x (list2pair (cdr l))))
        (cons
          (cons (caar l) (car x))
          (cons (cdar l) (cdr x))
        )
      )
    )
  )
)

(define pos-in-list
  (lambda (pred lst)
    (pos-in-list-helper pred lst 0)
  )
)

(define pos-in-list-helper
  (lambda (pred lst n)
    (if (null? lst) '()
      (if (pred (car lst))
        (cons n (pos-in-list-helper pred (cdr lst) (+ n 1)))
        (pos-in-list-helper pred (cdr lst) (+ n 1))
      )
    )
  )
)

;
; <n-list> ::= ({<n-list-exp>}*)
; <n-list-exp> ::= <n-list> | <number>
;

(define map-n-list
  (lambda (pred nlst)
    (map (lambda (x) (map-n-list-exp pred x)) nlst)
  )
)

(define map-n-list-exp
  (lambda (pred nlstexp)
    (if (number? nlstexp)
      (pred nlstexp)
      (map-n-list pred nlstexp)
    )
  )
)

(define not-in-env
  (lambda (sym)
     (eopl:error 'apply-env "No binding for ~s" sym)))

(define empty-env '())

(define apply-env
  (lambda (env x)
    (if (null? env) not-in-env
      (if (eq? (caar env) x) (cdar env)
        (apply-env (cdr env) x)
      )
    )
  )
)

(define extend-env
  (lambda (x val env)
    (append (pair2list (cons x val)) env)
  )
)

; Probelm 5 solution: coming soon ...

