(define (left-branch mobile) (car mobile)) (define (right-branch mobile) (cadr mobile)) (define (branch-length branch) (car branch)) (define (branch-structure branch) (cadr branch))
(define (leaf-weight? structure) (number? structure))この関数ならびに、上述の selector を用いて、total-weight は以下のように 再帰的に定義できる。
(define (weight-value weight-obj) weight-obj) (define (mobile-total-weight mobile) (+ (total-weight (branch-structure (left-branch mobile))) (total-weight (branch-structure (right-branch mobile))))) (define (total-weight structure) (if (leaf-weight? structure) (weight-value structure) (mobile-total-weight structure)))
(define (branch-moment branch) (* (total-weight (branch-structure branch)) (branch-length branch))) (define (mobile-balanced? structure) (if (leaf-weight? structure) #t (and (mobile-balanced? (branch-structure (left-branch structure))) (mobile-balanced? (branch-structure (right-branch structure))) (= (branch-moment (left-branch structure)) (branch-moment (right-branch structure))))))
;;; Structure := Mobile | Weight ;;; Mobile := ('Mobile left-structure right-structure) ;;; Weight := ('Weight weight-value) (define (make-mobile left right) (list 'Mobile left right)) (define (make-weight value) (list 'Weight value))
;;; mobile selector (define (left-branch mobile) (cadr mobile)) (define (right-branch mobile) (caddr mobile)) ;;; weight-obj selector (define (weight-value weight-obj) (cadr weight-obj)) ;;; mobile/weight type predicate (define (leaf-weight? structure) (eq? (car mobile) 'Weight))つまり、データ構造へのアクセス手段を別途記述しておくことで、 データ構造変更への対応が容易に行える。 これは、C プログラミングの時も同様であり、 しばしば、header file に各種 constructor/selector が マクロの形でまとめて定義されている。
99.10.6/ Tomio KAMADA: kamada@cs.kobe-u.ac.jp