sicp-ex-4.60



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


woofy

A version that actually works with the book's evaluator implementation:

  
  
  
 (assert! (rule (before ?x ?y) 
             (lisp-value 
                 (lambda (s1 s2) 
                     (define (list->string s) 
                         (fold-right 
                             string-append 
                             "" 
                             (map symbol->string s))) 
                     (string<? (list->string s1) (list->string s2))) 
                 ?x 
                 ?y))) 
  
 (assert! (rule (lives-near ?person-1 ?person-2) 
             (and (address ?person-1 (?town . ?rest-1)) 
                  (address ?person-2 (?town . ?rest-2)) 
                  (before ?person-1 ?person-2)))) 
  
 ; Tests: 
  
 ;;; Query input: 
 (lives-near ?x ?y) 
  
 ;;; Query results: 
 (lives-near (aull dewitt) (reasoner louis)) 
 (lives-near (aull dewitt) (bitdiddle ben)) 
 (lives-near (fect cy d) (hacker alyssa p)) 
 (lives-near (bitdiddle ben) (reasoner louis)) 

meteorgan

  
  
 because all the answers satisfy the rule. 
 we can sort the person in alphabetic order, then get only one pair. 
 (define (person->string person) 
   (if (null? person) 
       "" 
       (string-append (symbol->string (car person)) (person->string (cdr person))))) 
 (define (person>? p1 p2) 
   (string>? (person->sring p1) (person->string p2))) 
  
 (assert! (rule (asy-lives-near ?person1 ?person2) 
                (and (address ?person1 (?town . ?rest-1)) 
                        (address ?person2 (?town . ?rest-2)) 
                        (lisp-value person>? ?person1 ?person2))))