Quintus Prolog Manual
At any time, Prolog's execution can be interrupted by typing ^c. The following prompt is then displayed:
Prolog interruption (h for help)?
If you then type 'h', followed by <Return>, you will get a list of the possible responses to this prompt:
Prolog interrupt options:
h help - this list
c continue - do nothing
d debug - debugger will start leaping
t trace - debugger will start creeping
a abort - abort to the current break level
q really abort - abort to the top level
e exit - exit from Prolog
The 'd' option will cause you to enter the debugger the next time control passes to a spypoint. You can then use the 'g' (ancestors) option of the debugger to find out at what level of execution you interrupted the program.
The 't' option will also cause you to enter the debugger at the next call.
The 'a' option causes an abort to the current break level. In previous releases of Quintus Prolog, the 'a' option ignored break levels, always aborting to the top level (break level 0).
The 'q' option causes an abort to the top level (break level 0). This behavior is identical to the 'a' option in previous Quintus Prolog systems.
In runtime systems, the default behavior on a ^c interrupt is to abort immediately, rather than display the above menu.
For more information on ^c interrupts and signal handlers, see section G-11-2.
The predicates which control this are:
G-11-2-1: Changing Prolog's Control Flow from C
If the application has a toplevel, the function QP_action() can be called from C to alter Prolog's flow of control. This function allows the user to make Prolog abort, exit, suspend execution, turn on debugging, or prompt for the desired action. To use it, include the file quintus.h in your C source code, using #include. This file should be installed in /usr/include/quintus; if not, there should be a copy of it in the "embed" directory (refer to Chapter A-3 for location). quintus.h defines the following constants:
QP_ABORT *Abort to the current break level QP_REALLY_ABORT *Abort to top level QP_STOP Stop (suspend) process"} QP_IGNORE Do nothing QP_EXIT *Exit Prolog immediately QP_MENU Present action menu QP_ARITH *Indicate an arithmetic error and abort (obsolete) QP_TRACE Turn on trace mode QP_DEBUG Turn on debugging
To change Prolog's control flow in a given instance, call QP_action() with one of these constants; for example,
#include <quintus/quintus.h>
void abort_execution(){
QP_action(QP_ABORT);
}
Some calls to QP_action() do not normally return, for example when the QP_ABORT constant is specified. However, calls to QP_action() from an interrupt handler must be viewed as requests. They are requests that will definitely be honored, but not always at the time of the call to QP_action(). Therefore calls to QP_action() should be prepared for the function to return.
It is currently not possible to call Prolog from an interrupt handler.
For systems that do not have a toplevel, the actions marked with an asterisk will have no effect other than to make QP_action() return QP_ERROR.
What does it mean to have a toplevel? If the application is calling the function QP_toplevel(), then the application has a toplevel. The development system and runtime systems both call QP_toplevel(). An exit from either of these environments is effectively a return from QP_toplevel(). An embedded application may or may not call QP_toplevel(). One of the things QP_toplevel() does is establish signal handlers. Another thing it does is establish a place for QP_action() to jump to, the actions marked with an asterik are essentially a jump to the toplevel, and will not work in systems without a toplevel. For more about QP_toplevel(), see section M-3-66.
G-11-2-2: User-specified signal handlers
Prolog sets up signal handlers when either QP_initialize() or QP_toplevel() is called. These handlers provide the default interrupt handling for Control-c described in the previous sections. QP_initialize() and QP_toplevel() sets handlers for all signals which have the default handler and the default behavior is not what Prolog wants. If users have set their own signal handlers (which are different from the default signal handlers) then Prolog will not change these handlers. Once Prolog has started up and is running the toplevel read-prove loop, Prolog will not change any signal handlers unless the user calls QP_toplevel().
Users can set and remove signal handlers using the system function 'signal()'.
To set up a signal handler, call the routine
signal(signal_name, function_name)
from within a C foreign function, where signal_name is a constant identifying the signal being trapped and function_name is the name of the function to be called in the event of the signal. The constants identifying the various signals are defined in the file /usr/include/signal.h.
The example below shows how one would define an interrupt handler using 'signal' and QP_action(). For most users ^C is the interrupt character. The files interrupt.c and interrupt.pl make up this example; the interrupt handler is set up by calling establish_handler/0 after compiling interrupt.pl.
interrupt.pl
/*
This is the foreign interface file for a sample interrupt handler.
*/
foreign_file('interrupt.o',[establish_handler]).
foreign(establish_handler, establish_handler).
:- load_foreign_files(['interrupt.o'], []).
interrupt.c
/*
The function my_handler is called when the user types the interrupt
character (normally ^c). This function prompts for a response
and executes the user's choice.
*/
#include <signal.h>
#include <quintus/quintus.h>
int my_handler()
{
char c;
for(;;) {
printf("\nWell? ");
c = getchar();
if (c != '\n')
while (getchar() != '\n') {};
switch(c) {
case 'a': QP_action(QP_ABORT);
case 'e': QP_action(QP_EXIT);
case 'c': return;
default: printf("a, c or e, please");
}
}
}
void establish_handler()
{
signal(SIGINT, my_handler);
}
The following trace illustrates the use of these files:
<prompt> cc -c interrupt.c
<prompt> prolog
Quintus Prolog Release 3.4 (Sun 4, SunOS 5.5)
Originally developed by Quintus Corporation, USA.
Copyright (C) 1998, Swedish Institute of Computer Science. All rights reserved.
PO Box 1263, SE-164 29 Kista, Sweden. +46 8 633 1500
Email: qpsupport@sics.se WWW: http://www.sics.se/
| ?- compile(interrupt).
% compiling file /goedel/tim/interrupt.pl
% foreign file /goedel/tim/interrupt.o loaded
% interrupt.pl compiled in module user, 0.150 sec 1,508 bytes
yes
| ?- establish_handler.
yes
| ?- write(hi).
hi
yes
| ?- ^C
Well? g
a, c or e, please
Well? a
! Execution aborted
| ?- ^C
Well? e
<prompt>
A critical region is a section of code during whose execution interrupts are to be ignored. To create a critical region, one must block signals for the duration of the critical region and unblock the signals when leaving the critical region. Examples of how to do this in both Prolog and C are in the library files critical.pl and critical.c, which is discussed further in the the chapter on exceptions (section G-19-6).
G-11-3: Predicate/Function Summary
abort/0 QP_action() break/0 halt/0
library(critical)
contact:
product support
sales information