[mercury-users] Another Mercury Modes Problem

Ralph Becket rafe at cs.mu.OZ.AU
Tue May 28 15:01:07 AEST 2002


You haven't given enough information for us to offer much help.  There
are a number of problems here; here's what I can come up with (I've
added some cleaned up bits of code that I wrote to help me think):

Bob McKay, Tuesday, 28 May 2002:
> I'm sorry to trouble you all with fairly trivial misunderstandings
> of Mercury, but unfortunately I have hit another. I have
> declared
> 
> :- type individual
>         --->    individual(
>                         definition,
>                         maybe(fitness)
>                 ).
> 
> :- inst init_individual == bound(individual(ground, bound(no))).
> #:- inst individual == bound(individual(ground, bound(yes(ground)))).
> :- inst init_individual_list == unique(list(init_individual)).
> #:- inst individual_list == unique(list(individual)).

Why do the lists have to be unique?  This is probably going to be a
source of pain.

Problem: list/1 is not a data constructor or a parametric inst.  You
probably mean list_skel/1.

[clean up:]

:- type individual
        --->    individual(definition, maybe(fitness)).

:- inst init_individual  ==  bound(individual(ground, bound(no)).
:- inst individual       ==  bound(individual(ground, bound(yes(ground))).

:- type individuals == list(individual).

:- inst init_individuals == list_skel(init_individual).
:- inst individuals      == list_skel(individual).

Tip: just appending an `s' to a name often saves adding `_list'.

We'll use modes di/1 and uo/1 for these insts where necessary to
indicate uniqueness (see next.)

> :- mode create_ind == free >> init_individual.
> :- mode eval_ind == free >> individual.
> :- mode create_ind_list == free >> init_individual_list.
> #:- mode eval_ind_list == free >> individual_list.

Use built-in modes in, out, in(I), out(I), di(I), and uo(I)
for I in {init_individual, individual, init_individuals, individuals}
in preference to your named modes (it's better to have mode names that
make the direction of data flow clear.)

    % These should be built-in, but aren't...
    %
:- mode di(I) == unique(I) >> dead.
:- mode uo(I) ==      free >> unique(I).

> :- pred eval_ind(individual,individual,
> 	message,message,supply,supply).
> :- mode eval_ind(in,eval_ind,out,out,mdi,muo) is det.

Tip: spaces after commas makes a big difference to readability.

[clean up:]

:- pred eval_ind(individual, individual, message, message, supply, supply).
:- mode eval_ind(in, out(individual), out, out, mdi, muo) is det.

> :- pred eval_population(list(P),list(P),list(message),
> 		pred(P,P,message,message,supply,supply),
> 		supply,supply).
> :- mode eval_population(in,eval_ind_list,out,
>   in(pred(in,eval_ind,out,out,mdi,muo)is det),mdi,muo) is det.

Several problems here.

Tip: it's a good idea to name complex higher order types and modes:

:- type eval_pred(T) == (pred(T, T, message, message, supply, supply)).
:- inst eval_pred    == (pred(in, uo(individuals), out, out, mdi, muo) is det).

This is for the pred(...) argument to eval_population/6.

Problem: the first two arguments are polymorphic, but the second mode
applies only to type list(individual).  This is clearly wrong.  Do you
mean `individuals' rather than `T'?  Or should you be using type classes
instead (in which case we need to be a bit more sophisticated...)  Let's
assume the former, so the correct declarations are

:- type eval_pred == (pred(individual, individual, message, message,
				            supply, supply)).
:- inst eval_pred == (pred(in, uo(individual), out, out, mdi, muo) is det).


:- pred eval_population(individuals, individuals, messages, eval_pred,
                            supply, supply).
:- mode eval_population(in, uo(individuals), out, in(eval_pred),
                            mdi, muo) is det.

> #eval_population([],[],[],_) --> !.
> #eval_population([IUneval|IUnevals],[IEval|IEvals],
>   [Indmessage,Fitmessage|Messages],Process) -->
>         Process(IUneval,IEval,Indmessage,Fitmessage),
>         eval_population(IUnevals,IEvals,Messages,Process).

Problem: !/0 is an old Prologism, has no meaning in Mercury (it is
currently defined as true), and will go away in the near future (it is
being used for state variable syntax.)

Here's something that should work:

eval_population([],            [],          [],            _,     S,  S).

eval_population([U | Unevals], [E | Evals], [I, F | Msgs], EvalP, S0, S) :-
    EvalP(U, E, I, F, S0, S1),
    eval_population(Unevals, Evals, Msgs, EvalP, S1, S).

Hope this helps,

Ralph
--------------------------------------------------------------------------
mercury-users mailing list
post:  mercury-users at cs.mu.oz.au
administrative address: owner-mercury-users at cs.mu.oz.au
unsubscribe: Address: mercury-users-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-users-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the users mailing list