curry.backends.py.eval.rts_control module
Implements RuntimeState methods that manipulate the work queue. This module is not intended to be imported except by rts.py.
- curry.backends.py.eval.rts_control.append(rts, config)[source]
Append a configuration to the queue.
- curry.backends.py.eval.rts_control.catch_control(rts, ground=True, nondet=False, residual=False, restart=False, steplimit=False, unwind=False)[source]
Catch and handle flow-control exceptions.
- Parameters:
ground – Require ground terms. Propagate E_RESIDUAL only if this is true.
nondet – Catch non-determinism and raise NondetMonadError if it occurs. This takes priority over all other options.
residual – Handle residuals by updating the current configuration and rotating the queue.
restart – Catch and ignore E_RESTART.
steplimit – Handle a spent step budget by rotating the queue. The exception names the queue to rotate (see count_step). When that is an enclosing queue, the exception propagates to the handler of that queue. The set-function evaluations in between are suspended. They resume when their configuration runs again. A RecursionError raised by deep evaluation goes to
overflow: the configuration runs again after the others when it made progress, and an alternative that is stuck at the same depth is dropped. So the other alternatives still produce their values.unwind – Catch and ignore E_UNWIND.
- Returns:
A context manager.
- curry.backends.py.eval.rts_control.count_step(rts)[source]
Account for one rewrite step of the current configuration.
Called from S after each completed step. The step belongs to the current configuration and to the configuration at the head of each enclosing queue, because a set-function evaluation runs inside a step of the enclosing configuration. Each of them counts the step and spends one unit of its budget.
When a configuration has spent its budget, the queue that holds it rotates so that the other configurations get a turn. A queue with one configuration cannot rotate. The outermost queue that can rotate is the target. D rotates it when it handles E_STEPLIMIT, which carries the ID of the queue (see catch_control). The exception suspends the nested evaluations. They resume when their configuration runs again. A nested queue that can rotate is rotated here, in place, before the exception is raised. Otherwise a nested queue whose budget expires together with the budget of an enclosing queue would never rotate. With no step budget, only the counts are kept.
- curry.backends.py.eval.rts_control.overflow(rts, error)[source]
Handle a RecursionError raised by the evaluation of the current configuration. Returns True when D continues with the current queue, and False when the error goes to the enclosing queue. This mirrors
RuntimeState::unwindof the C++ backend.A configuration that took no step since it last overflowed is stuck: it repeats the same descent and overflows at the same point. The steps of a nested set-function evaluation count for the enclosing configuration. Re-scanning a configuration from its root repeats the descent but loses no work, because the graph holds every result.
In the outermost queue, a configuration that made progress runs again after the others. A stuck one is dropped. Its error waits in
rts.deferred_erroruntil the queue is empty (see D and ready), so the other alternatives still produce their values. In a nested queue, a configuration cannot be dropped without losing a value of the set function. It runs again after the others when any step was taken since it last overflowed. When no step was taken, the enclosing queue decides.
- curry.backends.py.eval.rts_control.raise_deferred_error(rts)[source]
Raise the error of an alternative dropped at the stack limit, if there is one. Only the outermost queue reports it, after the other alternatives have run. See overflow.
- curry.backends.py.eval.rts_control.ready(rts)[source]
Checks whether the runtime is ready to continue evaluation. Skips over blocked configurations and raises EvaluationSuspended if the queue contains only blocked configurations. Returns True when the queue is not empty and the configuration at the head is ready to be further evaluated.
- curry.backends.py.eval.rts_control.release_value(rts)[source]
Makes a value from the first configuration, detaches that configuration from the computation state, and then returns the value.
- curry.backends.py.eval.rts_control.rotate(rts, n=1)[source]
Rotate the queue by
npositions. By default, the current configuration is moved to the end.