Next: , Up: amb examples   [Index]


1.4.2.1 Introductory examples

In all the examples of this section we will assume that the following prelude opens the program:

#!r6rs
(import (vicare)
  (vicare language-extensions amb))

The amb operator requires appropriate initialisation of the dynamic environment, so if we just evaluate the following form we will get an error:

(amb)
error→ &amb-not-initialised

If we initialise the environment and then just call amb, we get an “exhausted search tree” error:

(with-ambiguous-choices
 (amb))
error→ &amb-exhaustion

because there are no choices, so the search terminates immediately.

If we apply amb to some choices, it will return the first one:

(with-ambiguous-choices
 (amb 1 2 3))
⇒ 1

If we want to see an actual use of amb, we have to reject some choices. Let’s look at this program:

(with-ambiguous-choices
 (let ((X (amb 1 2 3)))
   (amb-assert (even? X))
   X))
⇒ 2

this is what happens:

  1. amb returns the result of the first expression: 1.
  2. amb-assert rejects 1 because it is odd; the execution flow jumps back to the form (amb 1 2 3).
  3. amb returns the result of the next expression: 2.
  4. amb-assert accepts 2 because it is even.
  5. The result is 2.

The custom failure handler

The syntax with-amb-exhaustion-handler allows us to install a custom handler for the event “exhausted search tree”; the installed handler is called by amb whenever no more choices are available. As example, if we want a non–local exit at the end of a failed search, we can do:

(call/cc
    (lambda (escape)
      (with-ambiguous-choices
       (with-amb-exhaustion-handler
           (lambda ()
             (escape #t))
         (lambda ()
           (amb)
           #f)))))
⇒ #t

Next: , Up: amb examples   [Index]