[mercury-users] Types as sets?

Douglas Auclair dauclair at msn.com
Tue Feb 11 11:42:46 AEDT 2003

Dear all,

I've run into a problem quite a few times:  I'm creating a type where I'd 
like one of the members of that type to be some or all the members of 
another type.  So, for example:

:- type natural ---> ???.  % how do I put only all the positive integers 
:- type whole ---> zero; ?natural?.  % how do I say that whole numbers are 
all the natural numbers and zero?

Wholes could have their own set of predicates, seperate from naturals, so I 
don't think I'm looking for covariant/contravariant inheritance schemes 

Another way of stating the problem is that, for example, I know that a 
particular variable is constrained to a subset of values of another type, 
but the compiler doesn't know this, and I wish to create a new type that 
reflects this knowledge, so that:

:- pred p(two_digit_natural::in, string::out) is det.
p(1, "one").
% ...
p(99, "ninety-nine").

will compile (I know the above is a silly example, but I do run into this 
kind of problem quite often and I prefer the declarative syntax to the 
if-then-else (i.e. ->) spagetti-nested mess).

Is there a way, currently, to create the type two_digit_natural that will 
allow the above code to compile?

An example I used as a work-around is in the apple-darwin port:  
send_money_quickly.m (I've also attached the module to this email) which 
uses the Peano series and DCG to solve a cryptarithmetic problem 40x faster 
than the same problem solved using ints in crypt.m (proving that there is 
indeed a practical application to implementing the Peano series ... that is, 
besides assigning to (under)grad students as a homework assignment).  
Although effective, I see it as a hack (please don't tell Peano I said 
that).  I'd prefer to define the new type as a (limited) subset of another 
type or as a union of some predefined types.  Is this possible in Mercury?

Another workaround that I've used commonly is to declare a helper predicate 
as (cc_)multi to a det main predicate and follow this pattern:

:- pred column_as_int(int::in, char::out) is det.
column_as_int(Int, promise_only_solution(convert_int_to_char(Int))).

:- pred convert_int_to_char(int::in, char::out) is cc_multi.
convert_int_to_char(1, 'a').
% ...
convert_int_to_char(8, 'h').
convert_int_to_char(_, '_').

which, of course, it very hackish.  Is there a clean alternative to that?  
I've also done:

convert_int_to_char(X, '_') :- (X < 1; X > 8) -> error("Integer input is out 
of range").

as the last alternative for the helper predicate, but I don't like that 
either:  one is deferring a check until runtime that should be handled by 
the compiler.  In either case, I believe that a well-defined type system 
should eliminate the need for the "catchall" that the user writes.

So, the problem is that I'm working with predefined types that are unbound 
or very large, and I know that my system has a limited subset of values of 
these types or a combination of these types, but the compiler rejects my 
programs because I have not found a way to express this knowledge to it.  Is 
there a way to do this well in Mercury (expressively in the code and, e.g., 
speeds up the executable because the compiler can use the information on the 
limited/combined types to eliminate type/value checks later on)?  Is your 
group conducting research along these lines to implement in future versions 
of the compiler if it's not there now?

Doug Auclair

Add photos to your messages with MSN 8. Get 2 months FREE*.  
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: send_money_quickly.m
URL: <http://lists.mercurylang.org/archives/users/attachments/20030211/63cc80a5/attachment.ksh>

More information about the users mailing list