[mercury-users] Unique mode questions
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Apr 20 14:03:01 AEST 2001
On 19-Apr-2001, Terrence Brannon <princepawn at earthlink.net> wrote:
> In looking at this section of the manual I developed the following
> questions:
>
> 1- The manual states:
>
> Mercury also provides "unique" insts `unique' and `unique(...)' which
> are like `ground' and `bound(...)' respectively, except that they
> carry the additional constraint that there can only be one reference
> to the corresponding value.
>
> So my question is, what is meant by one reference to a value? Does
> that mean I cannot access the memory contents more than once?
It means that you can't have more than one variable
which refers to that value live at the same time.
> For example, here is a predicate with a unique-out variable:
>
> :- pred string__length(string, int).
> :- mode string__length(in, uo) is det.
>
> it is wrong for me to do the following:
>
> string__length(S,L), use_it_once(L), use_it_again(L).
That depends on what the modes for `use_it_once' and `use_it_again' are.
If `use_it_once' has a `di' mode (unique >> dead), then that would not
be allowed. But that example would be OK if `use_it_once' has a `ui'
mode (unique >> unique). (However, `ui' modes are not properly supported
in the current implementation.)
Here's another example which would not be allowed:
:- mode use_it_twice(di, di).
p :-
string__length(S,L),
use_it_twice(L, L).
> 2- Continuing, the manual states:
>
> There is also an inst `dead' which means that there are no references
> to the corresponding value, so the compiler is free to generate code
> that reuses that value.
>
> Now the obvious question is: why would a dead value exist in the first
> place?!
Well, it can start off live, and then later become dead.
> And the neophyte's intuitive explanation would be:
>
> :- pred list__length_2(list(T), int, int).
> :- mode list__length_2(in, in, out) is det.
>
> list__length_2([], N, N).
> list__length_2([_ | L1], N0, N) :-
> N1 is N0 + 1,
> list__length_2(L1, N1, N).
>
>
> ... the _ above is a case where the mode could have been dead but
> unfortunately the tail of the list was needed. So then the question
> remains, why pass something that isn't going to be used? It doesn't
> make much sense to have a mode like this in my eyes.
list__length_2 is not a good example for the use of unique modes.
But you could use a `di' mode for the first argument:
:- mode list__length_2(di, in, out) is det.
This would mean that after the call to list__length_2, the first argument
is dead, i.e. will no longer be used. The compiler could use this information
to do "compile-time garbage collection", i.e. inserting explicit calls to
free() or the equivalent to deallocate the memory for the list cons cells.
If you then write e.g.
:- func num_prime_factors(int) = int.
num_prime_factors(N) = Len :-
PrimeFactorsList = get_prime_factors(N),
list__length_2(PrimeFactorsList, 0, Len).
:- func get_prime_factors(int) = list(int).
:- mode get_prime_factors(in) = uo is det.
get_prime_factors(N) = ...
then `PrimeFactorsList' is live before the call to list__length_2, but dead
afterwards, so it would be OK for this call to list__length_2 to use the `di'
mode of list__length_2.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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