<< Previous exercise (4.42) | Index | Next exercise (4.44) >>


Here's a solution that doesn't explicitly leave out solutions, instead having amb and require eliminate them naturally.

 (define (yacht) 
   (define gab 'gabrielle) 
   (define lor 'lorna) 
   (define ros 'rosalind) 
   (define mel 'melissa) 
   (define mar 'mary-ann) 
   (let ((barnacle (amb gab lor ros mel mar))) 
     (require (eq? barnacle mel)) 
     (let ((moore (amb gab lor ros mel mar))) 
       (require (eq? moore mar))     
       (let ((hall (amb gab lor ros mel mar))) 
         (require (not (memq hall (list barnacle moore ros))))  
         (let ((downing (amb gab lor ros mel mar))) 
           (require (not (memq downing (list barnacle moore hall mel)))) 
           (let ((parker (amb gab lor ros mel mar))) 
             (require (not (memq parker 
                                 (list barnacle moore hall downing mar)))) 
             (let ((yacht-names 
                    (list (list barnacle gab) 
                          (list moore lor) 
                          (list hall ros) 
                          (list downing mel) 
                          (list parker mar)))) 
               (require (eq? parker (cadr (assq gab yacht-names)))) 
               (list (list 'barnacle barnacle) 
                     (list 'moore moore) 
                     (list 'hall hall) 
                     (list 'downing downing) 
                     (list 'parker parker))))))))) 


 (define (father-daughter) 
   (let ((Moore 'Mary) 
         (Barnacle 'Melissa) 
         (Hall (amb 'Gabrielle 'Lorna)) 
         (Downing (amb 'Gabrielle 'Lorna 'Rosalind)) 
         (Parker (amb 'Lorna 'Rosalind))) 
     (require (cond ((eq? Hall 'Gabrielle) (eq? 'Rosalind Parker)) 
                    ((eq? Downing 'Gabrielle) (eq? 'Melissa Parker)) 
                    (else false))) 
     (require (distinct? (list Hall Downing Parker))) 
     (list (list 'Barnacle Barnacle) 
           (list 'Moore Moore) 
           (list 'Hall Hall) 
           (list 'Downing Downing) 
           (list 'Parker Parker)))) 
 run (father-daughter), get ((Barnacle Melissa) (Moore Mary) (Hall Gabrielle) (Downing Lorna) (Parker Rosalind)), so Lorna's father is Colonel Downing. 
 If we don't know Mary Ann's family name is Moore, we get: 
 ;;; Starting a new problem 
 ;;; Amb-Eval output: 
 ((Barnacle Melissa) (Moore Gabrielle) (Hall Mary) (Downing Rosalind) (Parker Lorna)) 
 ;;; Amb-Eval input: 
 ;;; Amb-Eval output: 
 ((Barnacle Melissa) (Moore Mary) (Hall Gabrielle) (Downing Lorna) (Parker Rosalind))