Subject: Re: [SWIPL] sumlist to arithmetic function

From: Paul Singleton <[email-masked]>
Date: Fri, 24 Aug 2001 00:01:37 +0100

Hans-Ulrich Zimmermann <[email-masked]> writes:

> converting the old sumlist predicate to an arithmetic function
> will not work:

> :-arithmetic_function(sumlist/1).

> sumlist([],0).
> sumlist([Kopf|Rumpf], Summe) :- sumlist(Rumpf,Teilsumme), 
                                Summe is Kopf + Teilsumme.

> Is there any solution?

Empirically, SWI-Prolog accepts this directive:

  :- arithmetic_function(sumlist/1).

but if you call e.g. this goal

  ?- A is sumlist([1,2,3,4,5]).

it raises this error at runtime:

   '.'/2: Type error: `[]' expected, found `[2, 3, 4, 5]'

I don't see why it should be expecting an empty list but be
unprepared for a non-empty one?  Perhaps Jan will enlighten us.

Anyway, there's no good reason why is/2 has to be built-in,
since it can be implemented (without regard to efficiency) as
a library predicate, e.g.

  iz(Val, Expr) :-
      (   functor(Expr, Name, Arity),
          evaluable_functor(Name/Arity)
      ->  Expr =.. [Name|SubExprs],
          iz_1(Vals, SubExprs),         % evaluate its args
          append(Vals, [Val], Args),    % convert to a relation
          Goal =.. [Name|Args],         % (cont'd)
          call(Goal)
      ;   Val = Expr
      ).

  iz_1([], []).
  iz_1([V|Vs], [E|Es]) :-
      iz(V, E),
      iz_1(Vs, Es).

  evaluable_functor(sumlist/1).

  ?- iz( Q, sumlist([1,2,3,4,5])),
      write( 'Q'=Q), nl.
  Q=15

  Yes

i.e. it works for me (e.&o.e. :-)

Paul Singleton