[m-users.] Announcement: mercury-rmath library

Mark Clements (gmail) samuel.legotus at gmail.com
Mon Aug 23 18:29:34 AEST 2021


Nice! That's very helpful.

I now have an issue with determinism for the get_seed and set_seed 
predicates. I tried the attached code, but get these errors:

: In `get_seed'(out, out, di, uo):
:   error: invalid determinism for a predicate with I/O state
:   arguments.
:   Valid determinisms are det, cc_multi and erroneous.
: In `set_seed'(in, in, di, uo):
:   error: invalid determinism for a predicate with I/O state
:   arguments.
:   Valid determinisms are det, cc_multi and erroneous.

However, if I use det, then I get these errors:

: In `get_seed'(out, out, di, uo):
:   error: determinism declaration not satisfied.
:   Declared `det', inferred `semidet'.
:   Call to `rmath.get_seed_impure'(out, out) can fail.
: In `set_seed'(in, in, di, uo):
:   error: determinism declaration not satisfied.
:   Declared `det', inferred `semidet'.
:   Call to `rmath.set_seed_impure'(in, in) can fail.

Do I need another promise? Any suggestions would be welcome.

Kindly, Mark.

%%%%%%%%%%%%%%%%%%%%%

:- module test2_rmath.

:- interface.
:- import_module int, io.
% get_seed: get_seed(A,B,!IO)
:- pred get_seed(uint32::out,uint32::out,io::di,io::uo) is semidet.
% set_seed: set_seed(A,B,!IO)
:- pred set_seed(uint32::in,uint32::in,io::di,io::uo) is semidet.

:- implementation.
:- pragma foreign_decl("C", "
#define MATHLIB_STANDALONE
#include \"Rmath.h\"
").

:- impure pred get_seed_impure(uint32::out,uint32::out) is semidet.
:- pragma foreign_proc("C",
     get_seed_impure(A::out,B::out),
     [will_not_call_mercury],
     "get_seed(&A,&B);").
get_seed(A, B, !IO) :-
     promise_pure (
         impure get_seed_impure(A,B),
         !:IO = !.IO
     ).

:- impure pred set_seed_impure(uint32::in,uint32::in) is semidet.
:- pragma foreign_proc("C",
     set_seed_impure(A::in,B::in),
     [will_not_call_mercury],
     "set_seed(A,B);").
set_seed(A, B, !IO) :-
     promise_pure (
         impure set_seed_impure(A, B),
         !:IO = !.IO
     ).

On 23/08/2021 08:53, Julien Fischer wrote:
>
> Hi Mark,
>
> On Mon, 23 Aug 2021, Mark Clements (gmail) wrote:
>
>> The random number functions are marked as being impure. Note that the 
>> random seed is managed opaquely from C. I have tried -- 
>> unsuccessfully -- to wrap these functions using IO state:
>>
>> :- pred wrapped_runif(float::in, float::in, float::out, io::di, io::uo).
>> wrapped_runif(Lower, Upper, U, !IO) :- U = runif(Lower,Upper).
>>
>> Do I also need to make a promise?
>
> Yes, either a promise or a promise_pure scope.  You also need to add the
> impure annotation to the call to runif/2.  So, something like:
>
>     :- pred wrapped_runif(float::in, float::in, float::out, io::di, 
> io::uo).
>     wrapped_runif(Lower, Upper, U, !IO) :-
>       promise_pure (
>           impure U = runif(Lower,Upper),
>           !:IO = !.IO
>       ).
>
> (The unification involving the I/O state is there to document why the
> purity promise is correct.)
>
> Julien.


More information about the users mailing list