Hi,
On Mon, Mar 14, 2005 at 04:39:25AM +0100, chegivara wrote:
> Hi people,
> could you help me ? i need do something like this :
>
> sumList([3..7,5,8..9,0],K)
> -->
> K = 16..21
>
> is my solution right ???
>
> :- lib(fd).
>
> sumList([],Sum) :-
> Sum ::[0].
> sumList([H|Rest],Sum) :-
> sumList(Rest,Sum1),
> A :: H,
> Sum #= A+Sum1.
>
> eclipse 5.6 win
> sometimes happens (instantiation fault in A :: _397{[0 .. 24]})
It looks like one of the items in the list is a variable instead of being
ground - you should check this.
Note also that your solution does not give "K = 16..21". 16..21 is a ground
term with functor '..' and arguments 16 and 21. What you actually get is
K{16..21} - a variable with domain from 16 to 21. Is that what you want?
Note that if you're feeding the output of one sumList into another, that
would give you your instantiation fault, because the output is a variable
not a range.
If you have no particular desire to be using domain variables, you can
implement what you want fairly directly yourself (OK, I've had to guess what
exactly it is that you want, because you were fairly vague):
my_sum_list([], 0..0).
my_sum_list([H | Rest], Sum) :-
my_sum_list(Rest, Sum1),
my_sum(H, Sum1, Sum).
my_sum(X, LoIn..HiIn, LoOut..HiOut) :-
number(X),
LoOut is LoIn + X,
HiOut is HiIn + X.
my_sum(Lo..Hi, LoIn..HiIn, LoOut..HiOut) :-
LoOut is LoIn + Lo,
HiOut is HiIn + Hi.
Note that I've assumed the result will always be an interval Lo..Hi even if
Lo =:= Hi, to keep my_sum/3 simple, but it can obviously be extended to
avoid this if that is what you want.
Note also that if the lists you are summing could be long, it is better to
rearrange my_sum_list/2 to be tail-recursive (that is, the recursive call
should be the last call in the clause), as this allows the compiler to do
some optimisation:
% Tail-recursive version of my_sum_list/2 (much more memory efficient).
my_sum_list(List, Sum) :-
my_sum_list1(List, 0..0, Sum).
my_sum_list1([], Sum, Sum).
my_sum_list1([H | Rest], SumIn, SumOut) :-
my_sum(H, SumIn, Sum1),
my_sum_list1(Rest, Sum1, SumOut). % Tail recursion.
Some other notes:
We discourage the use of the FD library: it is deprecated and buggy and we
don't intend to fix it. Please upgrade to the latest version of ECLiPSe and
use the IC library instead.
Your predicate sumList/2 is very similar in name to sumlist/2, which is
provided by several ECLiPSe libraries. It would be better to use a name
less easily confused (or mis-typed).
Cheers,
Warwick