Advertisement
timothy235

sicp-4-3-3-implementing-the-amb-evaluator

Mar 24th, 2017
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 8.92 KB | None | 0 0
  1. #lang racket
  2.  
  3. ;;;;;;;;;;
  4. ;; 4.50 ;;
  5. ;;;;;;;;;;
  6.  
  7. (require racket/random) ; for random-ref
  8.  
  9. ;; You also need to change amb to ramb in the installed helper procedures.
  10.  
  11. (define (ramb? expr) (tagged-list? expr 'ramb))
  12. (define (ramb-choices expr) (rest expr))
  13.  
  14. (define (analyze-ramb expr)
  15.   (define cprocs (map analyze (ramb-choices expr)))
  16.   (lambda (env succeed fail)
  17.     (define (try-next choices)
  18.       (cond [(empty? choices) (fail)]
  19.             [else
  20.               (define choice (random-ref choices))
  21.               (define other-choices (remove choice choices))
  22.               (choice env
  23.                       succeed
  24.                       (lambda ()
  25.                         (try-next other-choices)))]))
  26.     (try-next cprocs)))
  27.  
  28. ;; test
  29.  
  30. ;; (driver-loop)
  31. ;; ;;; Ramb-Eval input:
  32. ;; (let ([x (an-element-of (list 1 2 3))]) x)
  33. ;; ;;; Starting a new problem
  34. ;; ;;; Ramb-Eval value:
  35. ;; 2
  36. ;; ;;; Ramb-Eval input:
  37. ;; try-again
  38. ;; ;;; Ramb-Eval value:
  39. ;; 3
  40. ;; ;;; Ramb-Eval input:
  41. ;; try-again
  42. ;; ;;; Ramb-Eval value:
  43. ;; 1
  44. ;; ;;; Ramb-Eval input:
  45. ;; try-again
  46. ;; ;;; There are no more values of
  47. ;; (let ((x (an-element-of (list 1 2 3)))) x)
  48.  
  49. ;;;;;;;;;;
  50. ;; 4.51 ;;
  51. ;;;;;;;;;;
  52.  
  53. ;; Permanent assignments have the form:  (permanent-set! <var> <value>)
  54. (define (permanent-assignment? expr)
  55.   (tagged-list? expr 'permanent-set!))
  56. (define (permanent-assignment-variable expr) (second expr))
  57. (define (permanent-assignment-value expr) (third expr))
  58.  
  59. ; do not restore old value if branch later fails
  60. (define (analyze-permanent-assignment expr)
  61.   (define var (permanent-assignment-variable expr))
  62.   (define vproc (analyze (permanent-assignment-value expr)))
  63.   (lambda (env succeed fail)
  64.     (vproc env
  65.            (lambda (val fail2)
  66.              (set-variable-value! var val env)
  67.              (succeed 'ok
  68.                       (lambda ()
  69.                         (fail2))))
  70.            fail)))
  71.  
  72. ;; USING PERMANENT-SET!
  73.  
  74. ;; Notice how count skips 1, 5, and 9, when x = y.
  75.  
  76. ;; (driver-loop)
  77. ;; ;;; Amb-Eval input:
  78. ;; (define count 0)
  79. ;; ;;; Starting a new problem
  80. ;; ;;; Amb-Eval value:
  81. ;; ok
  82. ;; ;;; Amb-Eval input:
  83. ;; (let ([x (an-element-of '(a b c))]
  84.       ;; [y (an-element-of '(a b c))])
  85.   ;; (permanent-set! count (+ count 1))
  86.   ;; (my-require (not (eq? x y)))
  87.   ;; (list x y count))
  88. ;; ;;; Starting a new problem
  89. ;; ;;; Amb-Eval value:
  90. ;; (a b 2)
  91. ;; ;;; Amb-Eval input:
  92. ;; try-again
  93. ;; ;;; Amb-Eval value:
  94. ;; (a c 3)
  95. ;; ;;; Amb-Eval input:
  96. ;; try-again
  97. ;; ;;; Amb-Eval value:
  98. ;; (b a 4)
  99. ;; ;;; Amb-Eval input:
  100. ;; try-again
  101. ;; ;;; Amb-Eval value:
  102. ;; (b c 6)
  103. ;; ;;; Amb-Eval input:
  104. ;; try-again
  105. ;; ;;; Amb-Eval value:
  106. ;; (c a 7)
  107. ;; ;;; Amb-Eval input:
  108. ;; try-again
  109. ;; ;;; Amb-Eval value:
  110. ;; (c b 8)
  111. ;; ;;; Amb-Eval input:
  112. ;; try-again
  113. ;; ;;; There are no more values of
  114. ;; (let ((x (an-element-of '(a b c)))
  115.       ;; (y (an-element-of '(a b c))))
  116.   ;; (permanent-set! count (+ count 1))
  117.   ;; (my-require (not (eq? x y)))
  118.   ;; (list x y count))
  119.  
  120. ;; USING SET!
  121.  
  122. ;; Using set!, count never increments.
  123.  
  124. #|
  125. (driver-loop)
  126. ;;; Amb-Eval input:
  127. (define count 0)
  128. ;;; Starting a new problem
  129. ;;; Amb-Eval value:
  130. ok
  131. ;;; Amb-Eval input:
  132. (let ([x (an-element-of '(a b c))]
  133.       [y (an-element-of '(a b c))])
  134.   (set! count (+ count 1))
  135.   (my-require (not (eq? x y)))
  136.   (list x y count))
  137.  
  138. ;;; Starting a new problem
  139. ;;; Amb-Eval value:
  140. (a b 1)
  141. ;;; Amb-Eval input:
  142. try-again
  143. ;;; Amb-Eval value:
  144. (a c 1)
  145. ;;; Amb-Eval input:
  146. try-again
  147. ;;; Amb-Eval value:
  148. (b a 1)
  149. ;;; Amb-Eval input:
  150. try-again
  151. ;;; Amb-Eval value:
  152. (b c 1)
  153. ;;; Amb-Eval input:
  154. try-again
  155. ;;; Amb-Eval value:
  156. (c a 1)
  157. ;;; Amb-Eval input:
  158. try-again
  159. ;;; Amb-Eval value:
  160. (c b 1)
  161. ;;; Amb-Eval input:
  162. try-again
  163. ;;; There are no more values of
  164. (let ((x (an-element-of '(a b c)))
  165.       (y (an-element-of '(a b c))))
  166.   (set! count (+ count 1))
  167.   (my-require (not (eq? x y)))
  168.   (list x y count))
  169. |#
  170.  
  171. ;;;;;;;;;;
  172. ;; 4.52 ;;
  173. ;;;;;;;;;;
  174.  
  175. ;; if-fail expressions have the form:  (if-fail <success-clause> <failure-clause>)
  176. (define (if-fail? expr) (tagged-list? expr 'if-fail))
  177. (define (if-fail-success-clause expr) (second expr))
  178. (define (if-fail-failure-clause expr) (third expr))
  179.  
  180. (define (analyze-if-fail expr)
  181.   (define sproc (analyze (if-fail-success-clause expr)))
  182.   (define fproc (analyze (if-fail-failure-clause expr)))
  183.   (lambda (env succeed fail)
  184.     (sproc env
  185.            ; what you do when amb returns a value val
  186.            (lambda (val fail2)
  187.              (succeed val fail2))
  188.            ; what you do when amb fails to return a value
  189.            (lambda () (fproc env succeed fail)))))
  190.  
  191. ;; Be sure to add even? to primitive procedures.
  192.  
  193. ;; test
  194.  
  195. ;; (driver-loop)
  196. ;; ;;; Amb-Eval input:
  197. ;; (if-fail (let ([x (an-element-of '(1 3 5))])
  198.            ;; (my-require (even? x))
  199.            ;; x)
  200.          ;; 'all-odd)
  201. ;; ;;; Starting a new problem
  202. ;; ;;; Amb-Eval value:
  203. ;; all-odd
  204. ;; ;;; Amb-Eval input:
  205. ;; (if-fail (let ([x (an-element-of '(1 3 5 8))])
  206.            ;; (my-require (even? x))
  207.            ;; x)
  208.          ;; 'all-odd)
  209. ;; ;;; Starting a new problem
  210. ;; ;;; Amb-Eval value:
  211. ;; 8
  212. ;; ;;; Amb-Eval input:
  213. ;; (if-fail (let ([x (an-element-of '(1 3))])
  214.            ;; (my-require (odd? x))
  215.            ;; x)
  216.          ;; 'all-even)
  217. ;; ;;; Starting a new problem
  218. ;; ;;; Amb-Eval value:
  219. ;; 1
  220. ;; ;;; Amb-Eval input:
  221. ;; try-again
  222. ;; ;;; Amb-Eval value:
  223. ;; 3
  224. ;; ;;; Amb-Eval input:
  225. ;; try-again
  226. ;; ;;; Amb-Eval value:
  227. ;; all-even
  228.  
  229. ;;;;;;;;;;
  230. ;; 4.53 ;;
  231. ;;;;;;;;;;
  232.  
  233. ;; Be sure to add prime? from math/number-theory to primitive procedures.
  234.  
  235. (define (prime-sum-pair list1 list2)
  236.   (let ([a (an-element-of list1)]
  237.         [b (an-element-of list2)])
  238.     (my-require (prime? (+ a b)))
  239.     (list a b)))
  240.  
  241. (let ([pairs empty])
  242.   (if-fail (let ([p (prime-sum-pair '(1 3 5 8) '(20 35 110))])
  243.              (permanent-set! pairs (cons p pairs))
  244.              (amb))
  245.            pairs))
  246.  
  247. ;; test
  248.  
  249. ;; (driver-loop)
  250. ;; ;;; Amb-Eval input:
  251. ;; (define (prime-sum-pair list1 list2)
  252.   ;; (let ([a (an-element-of list1)]
  253.         ;; [b (an-element-of list2)])
  254.     ;; (my-require (prime? (+ a b)))
  255.     ;; (list a b)))
  256. ;; ;;; Starting a new problem
  257. ;; ;;; Amb-Eval value:
  258. ;; ok
  259. ;; ;;; Amb-Eval input:
  260. ;; (let ([pairs '()])
  261.   ;; (if-fail (let ([p (prime-sum-pair '(1 3 5 8) '(20 35 110))])
  262.              ;; (permanent-set! pairs (cons p pairs))
  263.              ;; (amb))
  264.            ;; pairs))
  265. ;; ;;; Starting a new problem
  266. ;; ;;; Amb-Eval value:
  267. ;; ((8 35) (3 110) (3 20))
  268. ;; ;;; Amb-Eval input:
  269. ;; try-again
  270. ;; ;;; There are no more values of
  271. ;; (let ((pairs empty))
  272.   ;; (if-fail (let ((p (prime-sum-pair '(1 3 5 8) '(20 35 110))))
  273.              ;; (permanent-set! pairs (cons p pairs))
  274.              ;; (amb)) pairs))
  275.  
  276. ;;;;;;;;;;
  277. ;; 4.54 ;;
  278. ;;;;;;;;;;
  279.  
  280. (define (my-require? expr) (tagged-list? expr 'my-require))
  281. (define (my-require-predicate expr) (second expr))
  282.  
  283. (define (analyze-my-require expr)
  284.   (define pproc (analyze (my-require-predicate expr)))
  285.   (lambda (env succeed fail)
  286.     (pproc env
  287.            (lambda (pred-value fail2)
  288.              (if (not pred-value)
  289.                ; fail if predicate false
  290.                (fail)
  291.                ; continue if predicate true
  292.                (succeed 'ok fail2)))
  293.            ; fail if search fails
  294.            fail)))
  295.  
  296. ;; test
  297.  
  298. #|
  299. (driver-loop)
  300. ;;; Amb-Eval input:
  301. (define (multiple-dwelling)
  302.    (let ([baker (an-element-of (list 1 2 3 4 5))])
  303.      (my-require (not (= baker 5)))
  304.      (let ([cooper (amb 1 2 3 4 5)])
  305.        (my-require (not (= cooper 1)))
  306.        (let ([fletcher (amb 1 2 3 4 5)])
  307.          (my-require (not (= fletcher 5)))
  308.          (my-require (not (= fletcher 1)))
  309.          (my-require (not (= (abs (- fletcher cooper)) 1)))
  310.          (let ([miller (amb 1 2 3 4 5)])
  311.            (my-require (> miller cooper))
  312.            (let ([smith (amb 1 2 3 4 5)])
  313.              (my-require (distinct? (list baker cooper fletcher miller smith)))
  314.              ;; (my-require (not (= (abs (- smith fletcher)) 1)))
  315.              (list (list 'baker baker)
  316.                    (list 'cooper cooper)
  317.                    (list 'fletcher fletcher)
  318.                    (list 'miller miller)
  319.                    (list 'smith smith))))))))
  320. ;;; Starting a new problem
  321. ;;; Amb-Eval value:
  322. ok
  323. ;;; Amb-Eval input:
  324. (multiple-dwelling)
  325. ;;; Starting a new problem
  326. ;;; Amb-Eval value:
  327. ((baker 1) (cooper 2) (fletcher 4) (miller 3) (smith 5))
  328. ;;; Amb-Eval input:
  329. try-again
  330. ;;; Amb-Eval value:
  331. ((baker 1) (cooper 2) (fletcher 4) (miller 5) (smith 3))
  332. ;;; Amb-Eval input:
  333. try-again
  334. ;;; Amb-Eval value:
  335. ((baker 1) (cooper 4) (fletcher 2) (miller 5) (smith 3))
  336. ;;; Amb-Eval input:
  337. try-again
  338. ;;; Amb-Eval value:
  339. ((baker 3) (cooper 2) (fletcher 4) (miller 5) (smith 1))
  340. ;;; Amb-Eval input:
  341. try-again
  342. ;;; Amb-Eval value:
  343. ((baker 3) (cooper 4) (fletcher 2) (miller 5) (smith 1))
  344. ;;; Amb-Eval input:
  345. try-again
  346. ;;; There are no more values of
  347. (multiple-dwelling)
  348. |#
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement