[mercury-users] Bit-fields in Mercury
Peter Moulder
Peter.Moulder at infotech.monash.edu.au
Sun Jul 9 14:22:24 AEST 2006
You can have one or two opaque types to represent bits, with:
:- interface.
:- type my_bitfield.
:- type my_option == my_bitfield.
% Or can keep my_option as another opaque type, especially
% if using list notation instead of ‘\/’ (see below).
:- func opt1 = my_option.
...
:- func my_bitfield `\/` my_bitfield = my_bitfield.
:- pred fold(pred(my_option, A, A), my_bitfield, A, A).
:- mode fold(pred(in, in, out) is det, in, in, out) is det
% or whatever modes you need.
:- pred my_option `member` my_bitmap.
:- mode in `member` in is semidet.
:- implementation.
:- type my_bitfield == int.
X `\/` Y = X `'int.\/'` Y.
Opt `member` Field :-
Opt /\ Field \= 0.
fold(Pred, Opts, !Acc):-
( if Opts = 0 then
true
else
Rest_opts = Opts /\ (Opts - 1),
Low_opt = Opts - Rest_opts,
Pred(Low_opt, !Acc),
fold(Pred, Rest_opts, !Acc)
).
(All code untested, but you get the idea.)
If you want the ‘out `member` out is nondet’ mode too,
then *see (mercury_ref)Different clauses for different modes.
Suggested code:
:- pragma promise_pure(member/2).
% Mercury 0.13 has a more specific pragma (see aforementioned
% section of the documentation), though I think promise_pure is
% good enough for our purposes.
Opt::in `member` Opts::in :-
Opt /\ Field \= 0.
Opt::out `member` Opts::in :-
( if Opts = 0 then
false
else
Rest_opts = Opts /\ (Opts - 1),
(
Opt = Opts - Rest_opts
;
Opt `member` Rest_opts
)
).
An interesting alternative to using ‘\/’ (Mercury's bitwise-or operator)
is to use list notation:
:- func [] = my_bitfield.
:- func [my_option | my_bitfield] = my_bitfield.
...
[] = 0.
[Opt | Rest] = Opt \/ Rest.
This allows constructing option sets with [opt1, opt2, opt5]. Note that
you probably still want to use the fold predicate (or function) rather
than adding a ‘[out | out] = in’ mode, assuming you want [opt1, opt2] to
be equivalent to [opt2, opt1, opt1] but want to iterate in a det
fashion.
pjrm.
--------------------------------------------------------------------------
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