# yield jumps out of the 'receiver' function and never returns
print("This never prints")
x = callcc(receiver)
# f returns 2+1
# backtracks stores (continuation,[values]) pairs. Whenever a computation fails, we pull out another
# value from the list and feed it to the continuation. The idea is to perform a depth-first search.
backtracks = 
"""Aborts the current continuation and backtracks to another alternative stored in backtracks."""
if not backtracks: raise Exception('amb ran out of alternatives')
yield, alternatives = backtracks.pop()
alt = alternatives.pop()
if alternatives: # this continuation still has alternatives, so put them back on the list in case of a future 'fail'
"""The "ambivalent operator." The arguments to amb are alternatives, and the return value of amb
is an alternative which makes the future computation not fail."""
if not alternatives: fail()
if not b: fail()
"""Let's find a Pythagorean triple."""
x = amb(*range(1,100))
y = amb(*range(1,100))
z = amb(*range(1,100))
expect(x**2 + y**2 == z**2)
# We can print out all the Pythagorean triples.
trip = test_amb()
print("(x,y,z)=(%s,%s,%s)" % trip)
fail() # fail every time so it keeps backtracking, but the side effect of printing out remains