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]