[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