[Agda] Raw natural numbers

Alan Jeffrey ajeffrey at bell-labs.com
Fri Oct 22 00:02:26 CEST 2010


I'm afraid there's still a coercion left, for example (# 2) ends up as:

   (MAlonzo.Data.Natural.d2
     (Unsafe.Coerce.unsafeCoerce
       (MAlonzo.Data.Nat.mazIntegerToNat
         ((2) :: Integer))))

so can't be optimized.

The fix for this particular instance is to add an FFI binding to 
Data,Nat, but boy it would be nice to have a coerce function that played 
well with RULES.

A.

On 10/21/2010 01:44 PM, Jeffrey, Alan S A (Alan) wrote:
> I'm building the new compiler now...  Fingers crossed!
>
> A more general solution to the problem of unsafeCoerce getting in the
> way would be for Agda to use its own coerce function, defined something
> like:
>
>     {-# INLINE [1] coerce #-}
>     coerce = Unsafe.Coerce.unsafeCoerce
>
>     {-# RULES "coerce-id" forall (x :: a) . coerce x = x #-}
>
> This would at least remove all the identity coercions, and would allow
> other FFI bindings to define their own RULES.
>
> A.
>
> On 10/21/2010 04:48 AM, Ulf Norell wrote:
>>
>> On Thu, Oct 21, 2010 at 12:22 AM, Alan Jeffrey<ajeffrey at bell-labs.com
>> <mailto:ajeffrey at bell-labs.com>>  wrote:
>>
>>      Hi everyone,
>>
>>      I did some simple bindings for raw natural numbers:
>>
>>      http://github.com/agda/agda-system-io/tree/master/src/Data/Natural
>>
>>      The interesting thing is that we can almost optimize away many of
>>      the uses of unary numbers -- in particular to get constants such as
>>      #1000000 to be represented in native form rather than unary.
>>
>>      The idea would be to add a rule to Haskell's rewrite engine:
>>
>>      {-# RULES "int2nat2int" forall x .
>>        MAlonzo.Data.Nat.mazNatToInteger (MAlonzo.Data.Nat.mazIntegerToNat x)
>>          = x #-}
>>
>>      This almost works.  The two things stopping it are:
>>
>>      a) There isn't an FFI binding for Nat (grr) which means the compiler
>>      inserts some unsafeCoerce operations which then stop rewrites from
>>      firing.
>>
>>      b) The definitions of mazNatToInteger and mazIntegerToNat define a
>>      local variable, which isn't in scope for rewriting.
>>
>>
>> I removed the unnecessary coercion of integer literals, so now you get
>>
>>     Unsafe.Coerce.unsafeCoerce (mazIntegerToNat ((10) :: Integer))
>>
>> instead of
>>
>>     Unsafe.Coerce.unsafeCoerce (mazIntegerToNat
>> (Unsafe.Coerce.unsafeCoerce ((10) :: Integer)))
>>
>> when using natural number literals. I also changed the implementation of
>> mazNatToInteger/IntegerToNat to
>>
>> mazNatToInteger
>>     = \ x ->  case x of { C2 ->  0 :: Integer; C3 x ->  1 + (mazNatToInteger
>> (Unsafe.Coerce.unsafeCoerce x)) }
>> mazIntegerToNat
>>     = \ x ->  if x<= (0 :: Integer) then C2 else C3
>> (Unsafe.Coerce.unsafeCoerce (mazIntegerToNat (x - 1)))
>>
>> (where C2 and C3 are the constructor names for zero and suc). Hopefully
>> this will help a little.
>>
>> / Ulf
>



More information about the Agda mailing list