Next: amb examples ssc, Up: amb examples [Index]
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:
amb
returns the result of the first expression: 1
.
amb-assert
rejects 1
because it is odd; the execution flow
jumps back to the form (amb 1 2 3)
.
amb
returns the result of the next expression: 2
.
amb-assert
accepts 2
because it is even.
2
.
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: amb examples ssc, Up: amb examples [Index]