Subject: Re: [SWIPL] sumlist to arithmetic function

From: "Richard A. O'Keefe" <[email-masked]>
Date: Wed, 22 Aug 2001 12:11:17 +1200 (NZST)

Hans-Ulrich Zimmermann <[email-masked]> asks
whether there is any way of making

	sumlist([],0).
	sumlist([Kopf|Rumpf], Summe) :- sumlist(Rumpf,Teilsumme), 
	                                Summe is Kopf + Teilsumme.
	
into something that SWI Prolog will recognise as an arithmetic function.

The first observation is that it is generally better to write
    list_sum(List, Sum) :-
        list_sum(List, 0, Sum).

    list_sum([], Sum, Sum).
    list_sum([X|Xs], Sum0, Sum) :-
	Sum1 is Sum0 + X,
	list_sum(Xs, Sum1, Sum).

The second point is that the SWI Prolog manual is rather confused here:
"Arithmetic functions are terms which are evaluated by the arithmetic
predicates described above."
No, arithmetic functions are FUNCTORS which may appear in terms that are
evaluated by the arithmetic predicates.

There is another mistake in 3.27 as well: "if a function returns a floating-
point value which is whole it is automatically transformed to an integer".
I think that's a very very bad idea, but the mistake is that the sentence
isn't true.  Some such results are _not_ converted to integers.

There is further confusion in 3.27.  Does "mod/2 is implemented *using*
the C % operator" mean that we should expect it to have the *semantics*
of the C % operator (in which case the table of examples is wholly
unjustified, the C % operator being notoriously underdefined) or is it
simply a comment about the implementation (in which case, why bother?).

Section 3.28 does not adequately explain the semantics of *calling* a
user-defined arithmetic function.
 - what is supposed to happen if such a function fails?
   [Other Prolog compilers are entitled to assume that arithmetic expression
    evaluation can only succeed determinately or err, it cannot fail.]

 - what is supposed to happen if such a function exits with a choice-point
   on the stack?

 - are the arguments to such a function evaluated or not?  If they are,
   what is supposed to happen if the arguments are not themselves legal
   arithmetic expressions?

This is the point.  When you use a user-defined arithmetic function in
SWI Prolog, the arguments passed to it *must* themselves be legal
arithmetic expressions.  They are evaluated before the call to the function
and the way they are evaluated is the same way that _all_ arithmetic
expressions are evaluated.

In short, there is NO way to turn sumlist/2 (or list_sum/2) into an
arithmetic function, because it *ISN'T* one.  An arithmetic function
is a relation solely between *numbers*, and the first argument of
sumlist/2 is not a number.

Bill Clocksin once told me that if he were designing Prolog from scratch
he'd leave out user-defined operators and arithmetic expressions.  For a
long time I have been convinced he was right.  These features seem to
tempt people to try to do things they would be better off not doing.