🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.prolog
Article #1310

Re: Standards question: behavior of arg/3

#1310
From: Richard A. O'Keefe
Date: Tue, 23 Oct 1990 08:20
215 lines
10164 bytes
In article <1753@ecrc.de>, micha@ecrc.de (Micha Meier) writes:
> I completely agree with Richard O'Keefe that there should be just a few
> design principles and everything else should depend on them.
> The problem is, however, how to select these principles to obtain a sensible
> system.

I didn't find it all that hard.  What did I overlook?

> When we introduce built-in predicates to the language, the situation
> changes, because not all of them can be defined as a set of axioms
> of the language. (Let us leave out non-logical predicates, where
> the situation is much clearer.)

Eh?  EPs fall into four categories:
    -- commands (change the state of the world)
    -- state functions (don't change anything themselves but
	are affected by commands)
    -- pseudo-predicates (don't depend on the state of the
	world, do depend on the instantiation state of their
	arguments, hence on evaluation order)
    -- pure predicates (don't depend on the state of the world)
Pseudo-predicates can't be defined by (possibly infinite) sets
of facts, but state functions and pure predicates can.  The
pseudo-predicates can, to the best of my knowledge, be defined
in terms of var/1, nonvar/1, and possibly infinite sets of facts.

> Those predicates, which can be defined
> in Prolog, have then also a clear meaning and there seems no necessity
> to introduce error messages.

Let's keep things clear.  Let's _not_ talk about error MESSAGES.
Those are reports intended for human consumption.  Let's talk about
error detection and signalling.

The design I did for Quintus last year split errors into four
main groups:
	disasters		Things went so badly wrong that
				the error handling system can't
				be entered.
	faults			A query appears to make sense, but
				the Prolog system is unable to
				process it (not enough memory,
				numeric over/underflow, unsupported
				data type, file server dropped dead,
				and so on)
	errors			a command could not be obeyed because
				an object identifier is malformed or
				fails to identify an object or the
				operation is not permitted, &c
				or a state function asking about some
				object couldn't be evaluated for a
				similar reason
	failures		a query makes sense, and logically has
				the answer 'no', but it's most likely
				and error.

(That's why I keep saying "instantiation FAULT"; what one Prolog will
signal as an exception another may be able to handle by suspending.)
Disasters and faults can happen at any time.  Errors can only happen
when it would be INCORRECT to fail.  (For example, if I ask
	clause(true, Head, Body)
either I should get a clause back, or I should get an error signalled
because I have no permission to look at the clauses of true/0.  It
would be WRONG to fail here.)  "failure" signals could well be optional;
they are in effect run-type type checks.

Disasters, faults, and errors have a very simple criterion:  if the
Prolog system can determine the correct answer (including failure as
a correct answer) it should do so, and when and only when it is not
able to determine the correct answer, that is either a disaster, a
fault, or an error, depending on the reason why the correct answer
can't be obtained.

> However, when these logical principles are fully applied,
> debugging programs becomes difficult.

Oh?  How?  Exception detection and signalling is NOT repeat *NOT*
a debugging feature.  Exception handling is all about not producing
incorrect answers.  Debugging goes further.  You might well call
'failure' messages, e.g.
 
	! Type failure in argument 1 of arg/3
	! integer expected, but f(a,b,c) found
	! Goal: arg(f(a,b,c), 1, _235)

a debugging tool.  I wouldn't quarrel with that.  But it's not the
only debugging tool.  A programmer should be able to attach a
"critic" to any predicate that will check lots of things which
aren't technically errors.

> Richard O'Keefe suggest that we apply the table method extensively,
> but, exactly in case of arg/3, this would mean a different
> semantics than in the vast majority of existing Prolog systems.

Strictly speaking, it _would_ be different DEC-10 Prolog (but not
from MU Prolog or IBM Prolog).  But then so is producing error
reports different!  There is no real likelihood of the ISO version
of arg/3 being eactly like DEC-10 Prolog's arg/3.  A change which
provides more CORRECT answers surely is no bad thing?  We're not
talking about taking _working_ programs and breaking them, we're
talking about programs which didn't work properly and either
reporting this fact or making them work properly.

> in fact more like defining a new language, than to standardise
> the old one.

Not at all.  There is prior art.  We _can't_ be compatible with
_every_ previous Prolog.  There _are_ rough spots that have to
be spelled out, and precisely because these were grey areas in
the past we're going to differ from previous systems.  It's important
to minimise the differences.  Extremely important.  But extending the
_specification_ of an EP to say that it works in cases which previously
were not well defined, that's not much like defining a new language.

> Another example may be is/2:
> 	5 is 3 + X
> is completely logical and makes sense, however we cannot expect Prolog
> to succeed here, even if the number of solutions is finite.

No, the number of solutions here is not finite.  Plug into X any ground
arithmetic formula which evaluates to 2 and you have a solution:
	X = 2; X = 1+1; X = 0+2; X = -1+3; X = -2+4; ...
The EP plus/3, however, *should* be solved in such a case:
	plus(3, X, 5)
does have a unique solution for X, namely X = 5.  (plus/3 only makes sense
for rational numbers, not approximate numbers such as floats.)

> The same concerns the query
> 	X is fred	(from O'Keefe's Standard paper)
> which would fail if is/2 were defined with a table, but this
> failure would not mean anything reasonable to the programmer.

It's what I called a "type failure".  It does mean something sensible:
"'fred' is not an arithmetic expression."  In QP you would get a
message something like
	! Type failure in argument 2 of is/2
	! Arithmetic expression expected but fred found
	! Goal:  _234 is fred
If you want to switch this off, fine.  There are precisely three reasons
why a call
	Lhs is Rhs
may fail:
	- Rhs is not a well-formed arithmetic expression
	- Rhs asks for a value which definitely does not exist
	  (such as 1 // 0 or sqrt(-1.0))
	- Lhs is already instantiated to something which doesn't
	  unify with the value of Rhs
If Lhs is a new variable, then only the other possibilities exist.

> O'Keefe further says
> <I have frequently used
> <                arg(N, T, A),
> <                !,              % now we know that N >= 1
> 
> These are really bad arguments about the semantics of arg/3. If p/3
> is called with an integer which is possibly zero, there is no
> need to push the work to arg/3:

Hello Mr Thought Policeman!  Yes, I *can* rewrite my code.  Why
*should* I?  Why "push the work to" _me_?  Why is it ok to break
code that relied on a defined property of arg/3?  Especially when
you consider that I wrote PS/6 and sent it to the net back in 1984
precisely to make clear what it was that I _wanted_ to be able to
rely on?  The kind of argument here will apply to every kind of
type and range checking.  For example, concerning division by 0,
"there is no need to push the work to _//_", we could allow 
	X is Y//Z
to return any random junk you like when Z = 0, the programmer *could*
have written the code as
	(   Z =:= 0 -> signal_error(/* an appropriate error term */)
	;/* Z =\= 0 */ X is Y//Z
	).

> <If arg/3 is implemented sensibly, you have only to ask
> <        arg(3, Term, _) % if this succeeds, arity{Term} >= 3

> Why is it necessary to use arg/3 to test the arity of a functor
> when we have functor/3?? The minimality principle has to be applied.

Who said it was *necessary*?  All I said was that it was *possible*;
if I want to know whether there is a 3rd argument I can ask it directly
without asking what the arity actually is.  (As it happens I don't do
that myself.)

WHAT minimality principle?  The BSI and ISO mobs have made much
mention of a minimality principle, but they have never said what it
IS.  Let's see:  if there is one way of doing something, there shouldn't
be another?  Right:  then let us have (<)/2 alone, and not have
(>=)/2, (>)/2, or (=<)/2; let us leave out (=)/2 because the user can
define it, let us leave out (=..)/2 because the user can define it,
let us leave out read/1 because the user can define it, let's leave
out binary _-_, because we can always do -Y+X instead of X-Y, ...
This is ridiculous.

Let me be completely frank here:  not only have I been unable to discover
what the ISO mob mean by "minimality", the vague ideas I have about what
it might mean seem for the most part to be very bad ideas.

> We have some compatibility packages for other Prolog dialects,
> and it is interesting to note that for C-Prolog, the only
> events to redefine to make all our C-Prolog programs work
> was the behavior of arg/3 and undefined predicates.

It depends on which version of C Prolog you had.  The 1.*.edai
versions were a wee bit more thorough about reporting errors.

> We do not insist that the standard does what we do,
> but it is a very interesting experience to work with such a system,

It sounds rather like QP.

[I hope someone on the ANSI or ISO committees is keeping a copy of
this stuff.]
-- 
Fear most of all to be in error.	-- Kierkegaard, quoting Socrates.
Technical Details
Message-ID: <4055@goanna.cs.rmit.oz.au>
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!munnari.oz.au!goanna!ok
References: <9888@bunny.GTE.COM> <3992@goanna.cs.rmit.oz.au> <1753@ecrc.de>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!uunet!munnari.oz.au!goanna!ok
From: ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe)
Newsgroups: comp.lang.prolog
Subject: Re: Standards question: behavior of arg/3
Keywords: ANSI, standard
Message-ID: <4055@goanna.cs.rmit.oz.au>
Date: 23 Oct 90 08:20:20 GMT
References: <9888@bunny.GTE.COM> <3992@goanna.cs.rmit.oz.au> <1753@ecrc.de>
Organization: Comp Sci, RMIT, Melbourne, Australia
Lines: 215