PLOGHELP ON_INTERRUPT Simon Nichols, June 1991 ?- library(on_interrupt). ?- on_interrupt(OldAction, NewAction). The predicate on_interrupt/1, defined in LIBRARY ON_INTERRUPT, provides a means for Prolog programs to trap interrupts (such as occur when you type the terminal interrupt character, usually CTRL-C). The arguments to on_interrupt/2 are both terms which represent either goals or the special action 'abort'. Each goal specifies an action to be performed when an interrupt occurs: this is called the "interrupt action". When on_interrupt/2 is called, OldAction is unified with the existing interrupt action. If NewAction is instantiated, it becomes the new interrupt action; if it is an uninstantiated variable, it is also unified with the existing interrupt action. To find out the current interrupt action, do ?- on_interrupt(OldAction, _). OldAction = abort ? yes The default action is 'abort', which aborts all current executions and returns control to the Prolog top level. The current input and output files are switched back to be the user's terminal. This is similar to the default behaviour which results from calling the predicate abort/0 (see PLOGHELP * ABORT). However, abort/0 actually invokes the current interrupt action. To change the current interrupt action, do ?- on_interrupt(OldAction, interrupt_handler). OldAction = abort ? yes Given a definition of interrupt_handler/0 , such as the (rather pointless) interrupt_handler :- nl, write('Interrupt handler here ...'), abort. then the effect of an interrupt (or a call of abort/0) will be ?- ^C Interrupt handler here ... Setprolog ?- Note that a call to abort/0 inside an interrupt action always invokes the default definition of abort/0. Here is a more substantial example, illustrating the use of on_interrupt/2 in conjunction with the predicates catch/3 and throw/2, defined in LIBRARY CATCH (see PLOGHELP * CATCH). start :- on_interrupt(OldAction, throw(loop)), ( loop(1) ; on_interrupt(_, OldAction) ). loop(N) :- catch(step(N, N1), loop, N1=N), loop(N1). step(N, N1) :- write('Step'), tab, write(N), nl, read(T), T \= end_of_file, N1 is N + 1. This program does nothing more than read terms until end of file is reached, signalled on UNIX usually by CTRL-D, on VMS by CTRL-Z and in VED immediate mode (see HELP * IM) by the command end_im. The prompt is StepN, where N is an integer representing the current step number. Interrupting the program causes the same step to be restarted, as shown by the same step number. The entry point to the program, the predicate start/0, establishes as an interrupt action the goal throw(loop) where 'loop' is the tag. The predicate loop/1 calls step inside a call of catch/3. This call of catch/3 specifies 'loop' as the tag and as the recovery action the goal N1=N which keeps the step number unchanged. If the call to step/2 succeeds without interruption, N1 will be instantiated to N + 1, and so we proceed to the next step. If an interrupt occurs during the evaluation of step/2, the goal throw(loop) is called which will terminate the current flow of control, returning immediately to the invocation of catch/3 within loop/1. This will then invoke the goal N1=N causing the current step to be resumed. In general, a program which wants to guard against interrupts will have the form: start :- on_interrupt(OldAction, throw(tag)), ( loop ; on_interrupt(_, OldAction) ). loop :- catch(main_processing, tag, handler), loop. --- C.all/plog/help/on_interrupt --- Copyright University of Sussex 1991. All rights reserved. ----------