From paul.singleton@bcs.org.uk Fri Aug 24 01:00:40 2001
Received: from cmailg7.svr.pol.co.uk (cmailg7.svr.pol.co.uk [195.92.195.177])
	by swi.psy.uva.nl (8.11.2/8.11.2) with ESMTP id f7NN0eb23857
	for <prolog@swi.psy.uva.nl>; Fri, 24 Aug 2001 01:00:40 +0200 (MET DST)
Received: from modem-159.vanadium.dialup.pol.co.uk ([62.136.22.159] helo=bcs.org.uk)
	by cmailg7.svr.pol.co.uk with esmtp (Exim 3.13 #0)
	id 15a3Sp-0008E7-00
	for prolog@swi.psy.uva.nl; Fri, 24 Aug 2001 00:00:39 +0100
Message-ID: <3B858B51.B759B41@bcs.org.uk>
Date: Fri, 24 Aug 2001 00:01:37 +0100
From: Paul Singleton <paul.singleton@bcs.org.uk>
Organization: SmartArts Computing Consultancy
X-Mailer: Mozilla 4.74 [en] (WinNT; U)
X-Accept-Language: en
MIME-Version: 1.0
To: SWI Prolog <prolog@swi.psy.uva.nl>
Subject: Re: [SWIPL] sumlist to arithmetic function
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hans-Ulrich Zimmermann <zimmermann@h-u-zimmermann.de> 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

