20-CS-4003-001 Organization of Programming Languages Fall 2017
Call-with-current-continuation examples

Lambda calculus, Type theory, Formal semantics, Program analysis

    Prev     Next     All lectures        Code

Can nest the amb values

(define call/cc call-with-current-continuation)

(define amb-fail (lambda () (error 'no-solution)))

(define-syntax amb
  (syntax-rules ()
    ((amb x ...)
     (let ((prev-level amb-fail))
       (call/cc 
         (lambda (sk)
           (call/cc 
             (lambda (fk1)
               (set! amb-fail (lambda () (fk1 'fail)))
               (sk x)))
           ...
           (newline)  ;; Whoops - take this out
           (prev-level)))))))

(define assert (lambda (p) (if (not p) (amb))))

(define f
  (lambda () 
    (let ((a (amb 1 2 3 4 5 6 7))
	  (b (amb 11 12 13 14 15)))
      (display 'try:)(display a)
      (display "-")(display b)(display " ")
      (assert (and (eq? a 6) (eq? b 14)))
      (display "success: a=")(display a)
      (display " b=")(display b)(newline)
      (cons a b))))

(define g
  (lambda () 
    (let ((a (amb 1 2 3))
	  (b (amb 11 12 13)))
      (display 'try:)(display a)
      (display "-")(display b)(display " ")
      (assert (and (eq? a 6) (eq? b 14)))
      (display "success: a=")(display a)
      (display " b=")(display b)(newline)
      (cons a b))))
 -  To fix the problem of the previous slide interpret the variable amb-fail to hold the continuations that take the program through the current level of amb values. Therefore, upon entering the macro (the next amb level), save amb-fail as prev-level and invoke it at after the last inner call/cc to return to the previous level.

The assert procedure now makes more sense if it invokes (amb) instead of (amb-fail). Also, amb-fail should start out as a procedure to be consistent with what happens to it later (and prevent a problem when there are no solutions as in the case of invoking (g)).