comp.lang.ada
 help / color / mirror / Atom feed
From: Adam Beneschan <adam@irvine.com>
Subject: Re: Abstract operator does not hide predefined operator
Date: Fri, 12 Nov 2010 08:56:02 -0800 (PST)
Date: 2010-11-12T08:56:02-08:00	[thread overview]
Message-ID: <76885893-2ff1-4175-91c0-fb45b3dfbe15@o15g2000prh.googlegroups.com> (raw)
In-Reply-To: Pine.LNX.4.64.1011121513460.20835@medsec1.medien.uni-weimar.de

On Nov 12, 7:04 am, Stefan.Lu...@uni-weimar.de wrote:
> Hi all,
>
> I've implemented a small generic package for modular arithmetic. Note that
> Ada's "mod N" types define addition subtraction and multiplication right,
> but use the integer division for "/" instead of the proper modular
> division, where A/B is A * Inverse(B). I also tried to get rid of the
> unary "not" operator, who's purpose I don't understand for general
> modular arithmetic. (I understand that it is useful if the modulus is a
> power of two, just like the binary xor operator.)
>
> This is the spec of my generic package:
>
> generic
>    type Mod_T is mod <>;
> package Mod_Arith is
>    type Modular is new Mod_T;
>    function "/"(Left, Right: Modular) return Modular;
>    function Inverse(Value: Modular) return Modular;
>    function "not"(Value: Modular) return Modular is abstract;
> end Mod_Arith;
>
> For testing that package, I first instantiated it:
>
>    type M3343 is mod 3343;
>    package M is new Mod_Arith(Mod_T => M3343);
>    use type M.Modular;
>    S,T,U: M.Modular;
>
> (Sidenote: 3343 is a prime, so addition and multiplication over M.Modular
> are field operations, mathematically.)
>
> Now, my freshly defined division works as expected. The multiplication
> (and addition and subtraction) are inherited from the type M3343:
>
>    S := 3;
>    T := S/(2*S); -- T becomes the multiplicative Inverse of 2 mod 3343;
>                  -- the same expression's result in M3343 would be zero.
>    Ada.Text_IO.Put_Line(M.Modular'Image(T) &
>                           M.Modular'Image(M.Inverse(2)));
>    -- The output is "1672 1672", as expected.
>
> But, unfortunately, the compiler (gnat) also accepts the following:
>
>    U := not S; -- this should not be possible, because the "not" operator
>                -- has been defined abstract ... but instead, the
>                -- predefined "not" from M3343 seems to be used
>    Ada.Text_IO.Put_Line(M.Modular'Image(U));
>    -- The output is "3339", which actually is not(M3343(S)) = 3342-S.
>
> What can I do to get rid of the predefined "not"? If I change the "not"
> from an abstract function to a function always raising an exception, the
> statement
>
>    U := not S;
>
> raises the desired exception. But I would prefer to be told at compile
> time that I must not use "not", rather than at run time. Also, I would
> prefer not to define the type Mod_Arith.Modular as a private type.
>
> Any ideas?

This appears to be a GNAT bug; the inherited "not" subprogram of
Modular, which is inherited from the predefined function of M3343,
exists but should be hidden from all visibility, and therefore cannot
be a possible meaning of "not" in the expression "not S".  So what
you're doing should work, I think.  (P.S. I've confirmed that the
version of GNAT I'm using also accepts the program if I write out M
instead of making it a generic instantiation, and if I use "use"
instead of "use type".  So neither of those appears to be an issue.)

                              -- Adam



  reply	other threads:[~2010-11-12 16:56 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-11-12 15:04 Abstract operator does not hide predefined operator Stefan.Lucks
2010-11-12 16:56 ` Adam Beneschan [this message]
2010-11-12 17:39   ` Alex Mentis
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox