[mercury-users] User-defined Extension of builtin__copy?

Kral Stefan skral at mips.complang.tuwien.ac.at
Thu Sep 15 01:35:09 AEST 2005


Hi.

Zoltan, thank you for elaborately answering my question.

On Wed, 14 Sep 2005, Zoltan Somogyi wrote:
> On 13-Sep-2005, Kral Stefan <skral at mips.complang.tuwien.ac.at> wrote:
> > Currently working on GMP bindings for Mercury,
> > I am missing some way of telling the compiler
> > how a (unique) copy of some value (of a 
> > foreign type) can be created. [...]
> > 
> > Is there a way to solve the problem?
> 
> I am not sure which of several related problems you actually want to solve.
> I am pretty sure in each case the answer is "yes", but the solutions of
> course do difer.
> [...]
> Copying values of foreign types is not allowed by default. [...]
I was not aware of that.  That restriction basically solves my initial
problem (being sure that the generated code is correct if it is accepted
by the Mercury compiler.)

To allow the creation of unique copies, the GMP binding(s) will
offer dedicated functions/predicates, like the following.
	   % +(X) = 
	   %	X, returned as a unique copy of the value.
	   % copy(X0,X) <=>
	   %	X is a unique copy of X.
	   %
	:- func + gmpint = gmpint.
	:- mode + in     = uo is det.
	:- mode + di     = uo is det.

	:- pred gmpint_copy(gmpint, gmpint).
	:- mode gmpint_copy(in,     uo) is det.
	:- mode gmpint_copy(di,     uo) is det.

>    :- pragma foreign_type("C", gmpint, "GMP_Int *",
>    		[can_pass_as_mercury_type, stable])
>  	    where equality is gmpint_equals,
>  	          comparison is gmpint_compare.
> 
> The first assertion, can_pass_as_mercury_type, says that values of this type
> fit into an MR_Word, the basic type of everything (abstract machine registers,
> stack slots etc) in the Mercury implementation. Since an MR_Word is an
> integer the same size as a pointer, it seems "GMP_Int *" qualifies.
I noticed that using that assertion caused the compiler to omit some
boxing/unboxing statements (which -- I believe -- are optimized away
anyway by the C compiler, as it knows about the sizes of MR_Word and
GMPInt *).

Would you suggest using that assertion anyway?

> The second, stable, says that either the foreign type is either an integer
> (which GMP_Int * by itself isn't) or a pointer to memory whose contents
> will never change. I don't know whether the second part is true or not,
> but I expect you do.
Our current implementation does not alter memory of values that are alive.
However, we reuse memory wherever possible.

	   % X + Y = the sum of X and Y.
	   %	
	:- func gmpint + gmpint = gmpint.
	:- mode in     + in     = uo is det.
	:- mode di     + di     = uo is det.
	% [we also offer 'in+di=uo' and 'di+in=uo']

	:- pragma foreign_proc("C", 
			(A::in) + (B::in) = (D::uo),
			[will_not_call_mercury,thread_safe,promise_pure], 
	"	D = gmpint_alloc();
		mpz_add(D->i, A->i, B->i);
	").
	:- pragma foreign_proc("C", 
		(S1::di) + (S2::di) = (D::uo),
		[will_not_call_mercury,thread_safe,promise_pure], 
	"	D = (mpz_size(S1->i) > mpz_size(S2->i)) ? S1 : S2;
		mpz_add(D->i, S1->i, S2->i);
	").

I am not sure if this suffices to quality the type as stable.

> It you can't say that gmpint is stable, then you can consider simply
> replacing any code that copies gmpints, or terms containing gmpints,
> with code that (falsely, if necessary) promises them to be unique. Whether
> that will work depends on why you want gmpints to be unique in the first
> place; you'd have to tell me more about that.
We already use unsafe_promise_unique, in a context where we
would want to write
	min(A::di,B::di) = (Min::uo) :- Min = ( A < B -> A ; B ).

But that does not work, because of the lack of support for 
unique-input modes in the compiler.
Right now, we use unsafe_promise_unique instead as a hack.

Best regards,
Stefan.

--------------------------------------------------------------------------
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