I am struggling with what is the precise semantics of throw/1 without a suitable catch/3 in ISO Prolog. I am reading the ISO Prolog specification, and it seems to me that th
(We are talking here about ISO/IEC 13211-1:1995)
The definition of the control construct throw/1
(7.8.10) states in two places, that in this situation there shall be a system error. First, as you have observed, there is 7.8.10.1 c:
c) It shall be a system error (7.12.2 j) if S is now
empty,
and then, there is the error clause:
7.8.10.3 Errors
a)
B
is a variable
—instantiation_error
.b)
B
does not unify with theC
argument of any call
of catch/3
—system_error
.
To see what a system error is, we need to look at subclause 7.12.2 j:
j) There may be a System Error at any stage of
execution. The conditions in which there shall be a
system error, and the action taken by a processor after
a system error are implementation dependent. It has the
formsystem_error
.
So, the action taken by a processor after a system error is implementation dependent. An infinite loop would be fine, too.
In a standard conforming program you cannot rely on any particular action in that situation.
Ad Note 1: A Note is not normative. See 1.1 Notes. It is essentially a summary.
Ad Note 2: This is to avoid any overspecification. Parts as these are kept as vague as possible in the standard because a system error might have corrupted a Prolog system. It is quite similar with resource errors. Ideally a system would catch them and continue execution, but many implementations have difficulties to guarantee this in the general case.
Ad Note 3: The formal semantics is quintessentially another implementation. And in some parts, an implementation has to make certain decisions, whereas a specification can leave open all possibilities. Apart from that, note that the formal semantics is not normative. It did help to debug the standard, though.
Edit: In the comments you say:
(1mo) So you are saying that this allows the processor to immediately do its implementation dependent action when a system error occurs - not only after it is uncaught? (2do) Thus relieving it from the necessity to apply the goal transformation in 7.12.1 ? (3tio) It would then also be OK if system errors are not catchable (by catch/3) at all?
The sentence in 7.12.2 j
... the action taken by a processor after a system error are implementation dependent.
effectively overrules 7.12.1. Similarly to 7.12.2 h which may occur "at any stage of execution", too.
Just to be sure that we are reading the codex correctly assume the opposite for a moment. Imagine that a system error occurs and 7.12.1 would now produce such an error that is not caught anywhere, then we again would have a system error etc. Thus: the sentence above would never apply. This alone suggests that we have read here something incorrectly.
On the other hand, imagine a situation where a system error occurs when the system is completely corrupted. How should now 7.12.1 be executed anyway? So the Prolog system would be unable to execute this loop. Does this mean that a Prolog processor can only be conforming if we can prove that there will never be a system error? This is practically impossible, in particular, because
7.12.2 Error classification
NOTES
...
4 A System Error may happen for example (a) in interactions
with the operating system (for example, a disc crash or interrupt),
...
So effectively this would mean that there cannot be any conforming Prolog processor.
7.12.1 describes a way how an error is handled within Prolog. That is, if you are able to handle the error within Prolog, then a Prolog system should use this method. However, there might be situations where it is very difficult or even impossible (see above case) to handle an error in Prolog at all. In such situations a system might bail out.
Short answer: Yes. It is a quite extreme, but valid, reading that system errors are not catchable and execution would be terminated then. But maybe, take first a step back to understand (a) what a technical standard is for and what not, (b) the scope of a standard.
Or, rather start with b: In 1 Scope, we have:
NOTE - This part of ISO/IEC 13211 does not specify:
...
f) the user environment (top level loop, debugger, library
system, editor, compiler etc.) of a Prolog processor.
(Strictly speaking this is only a note, but if you leaf through the standard, you will realize that these aspects are not specified.) I somewhat suspect that what you actually want is to understand what a toplevel loop shall do with an uncaught error. However, this question is out of scope of 13211-1. It probably makes a lot of sense to report such an error and continue execution.
The other point here is what a technical standard is actually for. Technical standards are frequently misunderstood to be a complete guarantee that a system will work "properly". However, if a system is conforming to a technical standard, this does not imply that it is fit for any purpose or use. To show you the very extreme, consider the shell command exit 1
which might be considered to be a processor conforming to 13211-1 (provided it comes accompanied with documentation that defines all implementation defined features). Why? Well, when the system starts up, it might realize that the minimal requirements (1 Scope, Note b) are not met and thus it produces a system error which is handled by producing error code 1.
What you actually want is rather a system that does conform and is fit for certain purposes (that are out of scope of 13211-1). So in addition of asking yourself whether or not a certain behavior is conforming or not, you will also look about how this system is fit for certain purposes.
A good example to this end are resource errors. Many Prolog systems are able to handle certain resource errors. Consider:
p(-X) :- p(X).
and the query catch(p(X),error(E,_),true).
A system has now several opportunities: loop infinitely (which requires a very, very smart GC), succeed with E = resource_error(Resource)
, succeed with E = system_error
, stop execution with some error code, eat up all resources.
While there is no statement that a system has to catch such an error, all the mechanism is provided in the standard to do so.
Similarly in the case of a system_error
: If it makes sense, it might be a good idea to report system errors properly within Prolog, however, if things go too far, bailing out safely is still not the worst that can happen. In fact, the worst (yet still conforming) way would be to continue execution "as if" everything is fine, when it is not.