;; <regent> := (general aide)
;;    where general is a knight, and aide is a serf.
;; 
;; <knight> := (private salary)
;;             | (officer fellow squire servant salary)
;;    where fellow is a knight, and squire and servant are serfs.
;;    salary is a number of potatoes.
;; 
;; <serf> := (simpleton potatoes)
;;           | (idiot)
;;           | (spy rebel)
;;    where potatoes is a number, and rebel is a regent.



;; --- internalizing the data def'n ----
;;    (you should have already done this)
;;
(define-structure (regent general aide))
(define-structure (knight-private salary))
(define-structure (knight-officer fellow squire servant salary))
(define-structure (serf-simpleton potatoes))
(define-structure (serf-idiot))
(define-structure (serf-spy potatoes rebel))



;; ---- Some more inhabitants ----
;;
(define peon1 (make-serf-simpleton 22))
(define peon2 (make-serf-simpleton 11))
(define peon3 (make-serf-simpleton 99))
(define peon4 (make-serf-simpleton  0))
(define peon5 (make-serf-simpleton 44))
(define peon6 (make-serf-simpleton 9999))   ;; currently unused

(define gomer-pyle    (make-knight-private  5))
(define beetle-bailey (make-knight-private 23))

(define sarge (make-knight-officer beetle-bailey peon1 peon2 50))
(define major-major (make-knight-officer sarge peon3 peon4 40))
  
(define olafIV (make-regent major-major peon5))




;; ---- solution ----

;; (pot-regent r)
;; r is a regent; return how many potatoes the regent rules.
;;
(define pot-regent
  (lambda (r)
    (+ (pot-knight (regent-general r))
       (pot-serf   (regent-aide    r)))))

;; (pot-knight k)
;; k is a knight; return how many potatoes the knight rules.
;;
(define pot-knight
  (lambda (k)
    (if (knight-private? k)
	0
	(+ (pot-knight (knight-officer-fellow k))
	   (pot-serf   (knight-officer-squire k))
	   (pot-serf   (knight-officer-servant k))))))

;; (pot-serf s)
;; s is a serf; return how many potatoes the serf rules.
;;
(define pot-serf
  (lambda (s)
    (cond [(serf-simpleton? s)
	   (serf-simpleton-potatoes s)]
          [(serf-idiot? s)
	   0]
	  [(serf-spy? s)
	   (+ (pot-regent (serf-spy-rebel s))
	      (serf-spy-potatoes s))]
	  [else
	    (error 'pot-serf "Bad serf: ~s" s)])))


; Test: olafIV should have 176 potatoes, and 10 people.
(pot-regent olafIV)

; Make a serf-spy who has olafIV as a rebel liege,
; and test your functions on the regent of that serf-spy.