From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: a07f3367d7,e9dfe478ced46adc X-Google-Attributes: gida07f3367d7,public,usenet X-Google-NewGroupId: yes X-Google-Language: ENGLISH,ASCII Path: g2news2.google.com!postnews.google.com!o15g2000prh.googlegroups.com!not-for-mail From: Adam Beneschan Newsgroups: comp.lang.ada Subject: Re: Abstract operator does not hide predefined operator Date: Fri, 12 Nov 2010 08:56:02 -0800 (PST) Organization: http://groups.google.com Message-ID: <76885893-2ff1-4175-91c0-fb45b3dfbe15@o15g2000prh.googlegroups.com> References: NNTP-Posting-Host: 66.126.103.122 Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable X-Trace: posting.google.com 1289580962 8328 127.0.0.1 (12 Nov 2010 16:56:02 GMT) X-Complaints-To: groups-abuse@google.com NNTP-Posting-Date: Fri, 12 Nov 2010 16:56:02 +0000 (UTC) Complaints-To: groups-abuse@google.com Injection-Info: o15g2000prh.googlegroups.com; posting-host=66.126.103.122; posting-account=duW0ogkAAABjRdnxgLGXDfna0Gc6XqmQ User-Agent: G2/1.0 X-HTTP-UserAgent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; WOW64; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.5.21022; .NET CLR 3.5.30729; .NET CLR 3.0.30618; .NET4.0C),gzip(gfe) Xref: g2news2.google.com comp.lang.ada:16419 Date: 2010-11-12T08:56:02-08:00 List-Id: On Nov 12, 7:04=A0am, Stefan.Lu...@uni-weimar.de wrote: > Hi all, > > I've implemented a small generic package for modular arithmetic. Note tha= t > 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 > =A0 =A0type Mod_T is mod <>; > package Mod_Arith is > =A0 =A0type Modular is new Mod_T; > =A0 =A0function "/"(Left, Right: Modular) return Modular; > =A0 =A0function Inverse(Value: Modular) return Modular; > =A0 =A0function "not"(Value: Modular) return Modular is abstract; > end Mod_Arith; > > For testing that package, I first instantiated it: > > =A0 =A0type M3343 is mod 3343; > =A0 =A0package M is new Mod_Arith(Mod_T =3D> M3343); > =A0 =A0use type M.Modular; > =A0 =A0S,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: > > =A0 =A0S :=3D 3; > =A0 =A0T :=3D S/(2*S); -- T becomes the multiplicative Inverse of 2 mod 3= 343; > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0-- the same expression's result in M33= 43 would be zero. > =A0 =A0Ada.Text_IO.Put_Line(M.Modular'Image(T) & > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 M.Modular'Image(M.Inv= erse(2))); > =A0 =A0-- The output is "1672 1672", as expected. > > But, unfortunately, the compiler (gnat) also accepts the following: > > =A0 =A0U :=3D not S; -- this should not be possible, because the "not" op= erator > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0-- has been defined abstract ... but inste= ad, the > =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0-- predefined "not" from M3343 seems to be= used > =A0 =A0Ada.Text_IO.Put_Line(M.Modular'Image(U)); > =A0 =A0-- The output is "3339", which actually is not(M3343(S)) =3D 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 > > =A0 =A0U :=3D 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