Add exercise 4.53

This commit is contained in:
Oliver Payne 2024-01-30 22:48:03 +00:00
parent c07eef9e9e
commit 7a16a3efd8
1 changed files with 49 additions and 0 deletions

View File

@ -139,3 +139,52 @@ try-again
7
(if-fail (let ((x (an-element-of (quote (1 3 5 8))))) (require (even? x)) x) (quote all-odd))
;; Exercise 4.53
(define (square x) (* x x))
(define (smallest-divisor n)
(find-divisor n 2))
(define (find-divisor n test-divisor)
(cond ((> (square test-divisor) n) n)
((divides? test-divisor n) test-divisor)
(else (find-divisor n (+ test-divisor 1)))))
(define (divides? a b)
(= (remainder b a) 0))
(define (prime? n)
(= n (smallest-divisor n)))
(define (prime-sum-pair list1 list2)
(let ((a (an-element-of list1))
(b (an-element-of list2)))
(require (prime? (+ a b)))
(list a b)))
;;; Amb-Eval input:
(let ((pairs '()))
(if-fail (let ((p (prime-sum-pair '(1 3 5 8) '(20 35 110))))
(permanent-set! pairs (cons p pairs))
(amb))
pairs))
;;; Starting a new problem
;;; Amb-Eval value:
0
((8 35) (3 110) (3 20))
;; The call to prime-sum-pair succeeds for each of the pairs that
;; satisfy the condition. On success, the let body is entered, which
;; conses the current result onto pairs. Then the (amb) call forces
;; back tracking to the next solution. For each of these, pairs is
;; augmented with the candidate solution, until there are no more
;; solutions. At this point, the let expression fails, and if-fail
;; causes pairs to be evaluated.