sicp-ex-4.4



<< Previous exercise (4.3) | Index | Next exercise (4.5) >>


woofy

  
  
  
 ; special forms 
 (define (and? exp) (tagged-list? exp 'and)) 
 (define (and-predicates exp) (cdr exp)) 
 (define (first-predicate seq) (car seq)) 
 (define (rest-predicates seq) (cdr seq)) 
 (define (no-predicate? seq) (null? seq)) 
 (define (eval-and-predicates exps env) 
     (cond ((no-predicates? exps) true) 
           ((not (true? (eval (first-predicate exps)))) false) 
           (else (eval-and-predicate (rest-predicates exps) env)))) 
  
 (define (or? exp) (tagged-list? exp 'or)) 
 (define (or-predicates exp) (cdr exp)) 
 (define (eval-or-predicates exps env) 
     (cond ((no-predicates? exps) false) 
           ((true? (eval (first-predicate exps))) true) 
           (else (eval-or-predicate (rest-predicates exps) env)))) 
  
 ; derived expressions 
 (define (and->if exp) 
     (expand-and-predicates (and-predicates exp))) 
 (define (expand-and-predicates predicates) 
     (if (no-predicates? predicates) 
         'true 
         (make-if (first-predicate predicates) 
                  (expand-predicates (rest-predicates predicates)) 
                  'false))) 
  
 (define (or->if exp) 
     (expand-or-predicates (or-predicates exp))) 
 (define (expand-or-predicates predicates) 
     (if (no-predicate? predicates) 
         'false 
         (make-if (first-predicate predicates) 
                 'true 
                 (expand-predicates (rest-predicates predicates))))) 

dummy

a.

 ;; procedures to extract the parts of the expressions 
 (define (and-clauses exp) (cdr exp)) 
 (define (or-clauses exp) (cdr exp)) 
 (define (first-exp seq) (car seq)) 
 (define (rest-exp seq) (cdr seq)) 
 (define (empty-exp? seq) (null? seq)) 
 (define (last-exp? seq) (null? (cdr seq))) 
  
 ;; (and (list? '()) (number? 2) 3) => 3 
 (define (eval-and exps env) 
   (cond ((empty-exp? exps) #t) 
         (else 
          (let ((first (eval (first-expt exps) env))) 
            (cond ((last-exp? exps) first) 
                  (first (eval-and (rest-exp exps) env)) 
                  (else #f)))))) 
                        
 (define (eval-or exps env) 
   (cond ((empty-exp? exps) #f) 
         (else 
          (let ((first (eval (first-exp exps) env))) 
            (cond ((last-exp? exps) first) 
                  (first #t) 
                  (else 
                   (eval-or (rest-exp exps) env))))))) 
  

b.

 ;; (and (list? '()) (number? 2) 3)  
 ;; derived into "if" 
 ;; (if (list? '()) 
 ;;     (if (number? 2) 
 ;;      3 
 ;;      #f) 
 ;;     #f) 
  
 (define (and->if exp) 
   (expand-and-clauses (and-clauses exp))) 
  
 (define (expand-and-clauses clauses) 
   (cond ((empty-exp? clauses) 'false) 
         ((last-exp? clauses) (first-exp clauses)) 
         (else (make-if (first-exp clauses) 
                        (expand-and-clauses (rest-exp clauses)) 
                        #f)))) 
  
 (define (or->if exp) 
   (expand-or-clauses (or-clauses exp))) 
  
 (define (expand-or-clauses clauses) 
   (cond ((empty-exp? clauses) 'false) 
         ((last-exp? clauses) (first-exp clauses)) 
         (else (make-if (first-exp clauses) 
                        #t 
                        (expand-or-clauses (rest-exp clauses)))))) 

aos

 (define (and? exp) 
   (tagged-list? exp 'and)) 
 (define (and-expressions exp) (cadr exp)) 
 (define (first-expression exps) (car exps)) 
 (define (rest-expressions exps) (cdr exps)) 
 (define (and-eval-exps exps env) 
   (cond ((null? exps) 'true) 
         ((null? (rest-expressions exps)) 
          (eval (first-expression exps) env)) 
         ((true? (eval (first-expression exps) env)) 
          (and-eval-exps (rest-expressions exps) env)) 
         (else 'false))) 
  
 (and-eval-exps (and-expressions exp) env) 
  
 (define (or? exp) 
   (tagged-list? exp 'or)) 
 (define (or-expressions exp) (cadr exp)) 
 (define (or-eval-exps exps env) 
   (cond ((null? exps) 'false) 
         ((true? (eval (first-expression exps) env)) 'true) 
         (else 
           (or-eval-exps (rest-expressions exps) env)))) 
  
 (or-eval-exps (or-expressions exp) env) 

Sticking to the book's use of 'false and 'true rather than explicitly assigning it as a boolean.


o3o3o

  
 (define (and? exp) 
   (tagged-list? exp 'and)) 
  
 (define (or? exp) 
   (tagged-list? exp 'or)) 
  
 (define (eval-and exp env) 
   (cond ((no-operands?  exp) true) 
         ((eq? false (eval (first-operand exp) env)) false) 
         (else 
           (eval-and (rest-operands exp) env)))) 
  
 (define (eval-or exp env) 
   (cond ((no-operands?  exp) false) 
         ((eq? (eval (first-operand exp) env) true) true) 
         (else 
           (eval-or (rest-operands exp) env))))