--- ai12s/ai12-0208-1.txt 2018/03/02 03:50:56 1.6 +++ ai12s/ai12-0208-1.txt 2018/03/30 02:44:40 1.7 @@ -1,18 +1,14 @@ -!standard A.20(0) 18-03-01 AI12-0208-1/01 +!standard A.20(0) 18-03-28 AI12-0208-1/02 !class Amendment 16-12-19 !status work item 16-12-19 !status received 16-09-27 !priority Low !difficulty Medium -!subject Predefined bignum support +!subject Predefined Big numbers support !summary -Define a "bignum" package. +Define Big Numbers packages to support arbitrary precision mathematics. -[Editor's note: I surely hope that we have a better name for it than "bignum", -which is as non-Ada a name as possible (two words with no underscore and an -unnecessary abbreviation.] - !problem Some applications need larger numbers than Standard.Integer. All Ada compilers @@ -26,263 +22,282 @@ !wording -package Big_Numbers is - type Number is interface; +A.5.5 Big Numbers - function "=" (L, R : Number) return Boolean is abstract; - function "<" (L, R : Number) return Boolean is abstract; - function "<=" (L, R : Number) return Boolean is abstract; - function ">" (L, R : Number) return Boolean is abstract; - function ">=" (L, R : Number) return Boolean is abstract; - - function To_String (Arg : Number) return String is abstract; - function From_String (Arg : String) return Number is abstract; - function "+" (Arg : Integer) return Number is abstract; - - function "-" (L : Number) return Number is abstract; - function "abs" (L : Number) return Number is abstract; - function "+" (L, R : Number) return Number is abstract; - function "-" (L, R : Number) return Number is abstract; - function "*" (L, R : Number) return Number is abstract; - function "/" (L, R : Number) return Number is abstract; - function Min (L, R : Number) return Number is abstract; - function Max (L, R : Number) return Number is abstract; -end Big_Numbers; - ----------------------------------------------------------------- - -package Big_Numbers.Big_Integers is - type Big_Integer is new Number with private; - -- Defaults to zero. It would be nice to state this other than in a - -- comment but we don't have SPARK's Default_Initial_Condition aspect. - - overriding function "=" (L, R : Big_Integer) return Boolean; - overriding function "<" (L, R : Big_Integer) return Boolean; - overriding function "<=" (L, R : Big_Integer) return Boolean; - overriding function ">" (L, R : Big_Integer) return Boolean; - overriding function ">=" (L, R : Big_Integer) return Boolean; - - overriding function "+" (Arg : Integer) return Big_Integer; - function To_Big_Integer (Arg : Integer) return Big_Integer renames "+"; - - subtype Big_Positive is Big_Integer with - Dynamic_Predicate => Big_Positive > +0, - Predicate_Failure => (raise Constraint_Error); - - subtype Big_Natural is Big_Integer with - Dynamic_Predicate => Big_Natural >= +0, - Predicate_Failure => (raise Constraint_Error); - - function In_Range (Arg, Lo, Hi : Big_Integer) return Boolean is - ((Lo <= Arg) and (Arg <= Hi)); - - function To_Integer (Arg : Big_Integer) return Integer with - Pre => In_Range (Arg, Lo => +Integer'First, Hi => +Integer'Last) - or else (raise Constraint_Error); +Support is provided for integer arithmetic involving values larger than +than those supported by the target machine, and for arbitrary-precision +rationals. + +The package Ada.Numerics.Big_Numbers has the following declaration: + + package Ada.Numerics.Big_Numbers is + type Number is Interface; + + function "=" (L, R : Number) return Boolean is abstract; + function "<" (L, R : Number) return Boolean is abstract; + function "<=" (L, R : Number) return Boolean is abstract; + function ">" (L, R : Number) return Boolean is abstract; + function ">=" (L, R : Number) return Boolean is abstract; + + function To_String (Arg : Number) return String is abstract; + function From_String (Arg : String) return Number is abstract; + function "+" (Arg : Integer) return Number is abstract; + + function "-" (L : Number) return Number is abstract; + function "abs" (L : Number) return Number is abstract; + function "+" (L, R : Number) return Number is abstract; + function "-" (L, R : Number) return Number is abstract; + function "*" (L, R : Number) return Number is abstract; + function "/" (L, R : Number) return Number is abstract; + function Min (L, R : Number) return Number is abstract; + function Max (L, R : Number) return Number is abstract; + end Ada.Numerics.Big_Numbers; + +[TBD: aspects specified for this package? Pure, Nonblocking, others? +Same question applies to other packages declared in later sections. +Would these aspects constrain implementations in undesirable ways?] + +[TBD: It would be nice to use subtypes in parameter profiles (e.g., +a Nonzero_Number subtype for second argument of "/", but this requires +AI12-0243 and the future of that AI is very uncertain.] + +A.5.5.1 Big Integers + +The package Ada.Numerics.Big_Numbers.Big_Integers has the following definition: + + package Ada.Numerics.Big_Numbers.Big_Integers is + type Big_Integer is new Number with private with + Default_Initial_Condition => Big_Integer = 0, + Integer_Literal => From_String; + +[TBD: Remove Integer_Literal aspect spec if AI12-0249-1 not approved. +If Default_Initial_Condition AI12-0265-1 is approved and Integer_Literal AI is +not then replace "0" with "+0" in the condition and as needed in +subsequent conditions.] + + overriding function "=" (L, R : Big_Integer) return Boolean; + overriding function "<" (L, R : Big_Integer) return Boolean; + overriding function "<=" (L, R : Big_Integer) return Boolean; + overriding function ">" (L, R : Big_Integer) return Boolean; + overriding function ">=" (L, R : Big_Integer) return Boolean; - generic - type Int is range <>; - package Signed_Conversions is - function To_Big_Integer (Arg : Int) return Big_Integer; - function From_Big_Integer (Arg : Big_Integer) return Int with - Pre => In_Range - (Arg, Lo => To_Big_Integer (Int'First), - Hi => To_Big_Integer (Int'Last)) - or else (raise Constraint_Error); - end Signed_Conversions; + overriding function "+" (Arg : Integer) return Big_Integer; + function To_Big_Integer (Arg : Integer) return Big_Integer renames "+"; + + subtype Big_Positive is Big_Integer + with Dynamic_Predicate => Big_Positive > 0, + Predicate_Failure => (raise Constraint_Error); + + subtype Big_Natural is Big_Integer + with Dynamic_Predicate => Big_Natural >= 0, + Predicate_Failure => (raise Constraint_Error); + + function In_Range (Arg, Lo, Hi : Big_Integer) return Boolean is + ((Lo <= Arg) and (Arg <= Hi)); + +[TBD: In_Range formal parameter names. "Lo & Hi" vs. "Low & High"?] + + function To_Integer (Arg : Big_Integer) return Integer + with Pre => In_Range (Arg, Lo => +Integer'First, Hi => +Integer'Last) + or else (raise Constraint_Error); + + generic + type Int is range <>; + package Signed_Conversions is + function To_Big_Integer (Arg : Int) return Big_Integer; + function From_Big_Integer (Arg : Big_Integer) return Int + with Pre => In_Range (Arg, + Lo => To_Big_Integer (Int'First), + Hi => To_Big_Integer (Int'Last)) + or else (raise Constraint_Error); + end Signed_Conversions; + + generic + type Int is mod <>; + package Unsigned_Conversions is + function To_Big_Integer (Arg : Int) return Big_Integer; + function From_Big_Integer (Arg : Big_Integer) return Int + with Pre => In_Range (Arg, + Lo => To_Big_Integer (Int'First), + Hi => To_Big_Integer (Int'Last)) + or else (raise Constraint_Error); + end Unsigned_Conversions; + + overriding function To_String (Arg : Big_Integer) return String; + overriding function From_String (Arg : String) return Big_Integer; + + overriding function "-" (L : Big_Integer) return Big_Integer; + overriding function "abs" (L : Big_Integer) return Big_Integer; + overriding function "+" (L, R : Big_Integer) return Big_Integer; + overriding function "-" (L, R : Big_Integer) return Big_Integer; + overriding function "*" (L, R : Big_Integer) return Big_Integer; + overriding function "/" (L, R : Big_Integer) return Big_Integer; + function "mod" (L, R : Big_Integer) return Big_Integer; + function "rem" (L, R : Big_Integer) return Big_Integer; + function "**" (L : Big_Integer; R : Natural) return Big_Integer; + overriding function Min (L, R : Big_Integer) return Big_Integer; + overriding function Max (L, R : Big_Integer) return Big_Integer; + + function Greatest_Common_Divisor + (L, R : Big_Integer) return Big_Integer with + Pre => (L /= 0 and R /= 0) or else (raise Constraint_Error), + Post => (Big_Integer'Result > 0); + + private + ... -- not specified by the language + end Ada.Numerics.Big_Numbers.Big_Integers; + +To_String and From_String behave like Integer'Image and Integer'Value except +that more digits are produced and accepted. [In particular, +the low bound of To_String'Result is 1, To_String'Result includes a leading +blank in the case of a nonnegative argument, and Constraint_Error is raised if +the argument to From_String is syntactically incorrect.] + +The other functions have their usual mathematical meanings. + +[TBD: GCD should return Big_Positive, not Big_Integer, if AI12-0243 +somehow allows this.] + +A.5.5.1.1 Bounded Big Integers + +An instance of the language-defined generic package +Numerics.Big_Numbers.Bounded_Big_Integers provides a Big_Integer type and +operations corresponding to those declared in +Numerics.Big_Numbers.Big_Integers, but with the difference that the maximum +storage (and, consequently, the set of representable values) is bounded. +The generic package Ada.Numerics.Big_Numbers.Bounded_Big_Integers has the +following definition: + generic - type Int is mod <>; - package Unsigned_Conversions is - function To_Big_Integer (Arg : Int) return Big_Integer; - function From_Big_Integer (Arg : Big_Integer) return Int with - Pre => In_Range - (Arg, Lo => To_Big_Integer (Int'First), - Hi => To_Big_Integer (Int'Last)) - or else (raise Constraint_Error); - end Unsigned_Conversions; - - overriding function To_String (Arg : Big_Integer) return String; - overriding function From_String (Arg : String) return Big_Integer; - -- Accepts same syntax as Integer'Value (although accepts more digits); - -- progagates Constraint_Error if input doesn't meet this requirement. - - overriding function "-" (L : Big_Integer) return Big_Integer; - overriding function "abs" (L : Big_Integer) return Big_Integer; - overriding function "+" (L, R : Big_Integer) return Big_Integer; - overriding function "-" (L, R : Big_Integer) return Big_Integer; - overriding function "*" (L, R : Big_Integer) return Big_Integer; - overriding function "/" (L, R : Big_Integer) return Big_Integer; - function "mod" (L, R : Big_Integer) return Big_Integer; - function "rem" (L, R : Big_Integer) return Big_Integer; - function "**" (L : Big_Integer; R : Natural) return Big_Integer; - overriding function Min (L, R : Big_Integer) return Big_Integer; - overriding function Max (L, R : Big_Integer) return Big_Integer; + Capacity : Natural; + package Ada.Numerics.Big_Numbers.Bounded_Big_Integers is -private - type Big_Integer is new Number with null record; -- bogus completion -end Big_Numbers.Big_Integers; + <all the same visible declarations as those in Big_Numbers.Big_Integers, + including declaration of Bounded_Big_Integers.Big_Integer type> ----------------------------------------------------------------- + function Last return Big_Integer is ((+256) ** Capacity); + function First return Big_Integer is (-Last); + private + ... -- not specified by the language + end Ada.Numerics.Big_Numbers.Bounded_Big_Integers; + +Each operation behaves like the corresponding Big_Numbers.Big_Integers +operation except that Constraint_Error is raised if a result R +would fail the test In_Range (R, First, Last). This includes the +streaming operations Big_Integer'Read and Big_Integer'Input. + +AARM Note: Roughly speaking, behavior is as if the type invariant for +Bounded_Big_Integer is + In_Range (Bounded_Big_Integer, First, Last) or else (raise Constraint_Error) +although that is not specified explicitly because that would +require introducing some awkward code in order to avoid infinite +recursion. + +Implementation Requirements + +For each instance of Bounded_Big_Integers, the output generated by +Big_Integer'Output or Big_Integer'Write shall be readable by the +corresponding Input or Read operations of the Big_Integer type +declared in either another instance of Bounded_Big_Integers or in +the package Numerics.Big_Numbers.Big_Integers. [This is subject to the +preceding requirement that Constraint_Error is raised in some cases.] + +Implementation Advice + +The implementation of (an instance of) Bounded_Big_Integers should not +make use of controlled types or dynamic allocation. + +[end of Implementation Advice] + +The generic unit Ada.Numerics.Big_Numbers.Bounded_Big_Integers.Conversions +provides operations for converting between the Big_Integer types declared +in Big_Numbers.Big_Integers and in an instance of + Big_Numbers.Bounded_Big_Integers. -generic - Capacity : Natural; -package Big_Numbers.Bounded_Big_Integers is - -- Unlike the expected implementation of Big_Numbers.Big_Integers, - -- the expected implementation of (an instance of) Bounded_Big_Integers - -- is not expected to require use of allocators or controlled types. - -- The only difference between the specs of the bounded and unbounded - -- versions is the addition of the First and Last functions. - - type Big_Integer is new Number with private; - -- Defaults to zero. - -- - -- Type_Invariant for Bounded_Big_Integer is effectively - -- In_Range (Bounded_Big_Integer, First, Last) - -- or else (raise Constraint_Error) - -- although we don't specify that here in visible part because - -- the operators called in the type invariant itself have - -- to be special in order to avoid infinite recursion. - -- Note that First and Last are defined below. - - overriding function "=" (L, R : Big_Integer) return Boolean; - overriding function "<" (L, R : Big_Integer) return Boolean; - overriding function "<=" (L, R : Big_Integer) return Boolean; - overriding function ">" (L, R : Big_Integer) return Boolean; - overriding function ">=" (L, R : Big_Integer) return Boolean; - - overriding function "+" (Arg : Integer) return Big_Integer; - function To_Big_Integer (Arg : Integer) return Big_Integer renames "+"; - subtype Big_Positive is Big_Integer with - Dynamic_Predicate => Big_Positive > +0, - Predicate_Failure => (raise Constraint_Error); - - subtype Big_Natural is Big_Integer with - Dynamic_Predicate => Big_Natural >= +0, - Predicate_Failure => (raise Constraint_Error); - - function In_Range (Arg, Lo, Hi : Big_Integer) return Boolean is - ((Lo <= Arg) and (Arg <= Hi)); - - function To_Integer (Arg : Big_Integer) return Integer with - Pre => In_Range (Arg, Lo => +Integer'First, Hi => +Integer'Last) - or else (raise Constraint_Error); +The generic package Ada.Numerics.Big_Numbers.Bounded_Big_Integers.Conversions +has the following definition: + with Ada.Numerics.Big_Numbers.Big_Integers; generic - type Int is range <>; - package Signed_Conversions is - function To_Big_Integer (Arg : Int) return Big_Integer; - function From_Big_Integer (Arg : Big_Integer) return Int with - Pre => In_Range - (Arg, Lo => To_Big_Integer (Int'First), - Hi => To_Big_Integer (Int'Last)) - or else (raise Constraint_Error); - end Signed_Conversions; + package Ada.Numerics.Big_Numbers.Bounded_Big_Integers.Conversions is + function From_Unbounded + (Arg : Big_Integers.Big_Integer) return Big_Integer; + function To_Unbounded + (Arg : Big_Integer) return Big_Integers.Big_Integer; + end Ada.Numerics.Big_Numbers.Bounded_Big_Integers.Conversions; + +AARM Note:This unit is declared as a child unit because we don't want +Big_Integers to be in the closure of Bounded_Big_Integers. It is a generic +package because its parent cannot have a non-generic child unit. + +[TBD: This could be done differently by using a formal instance instead +of declaring the Conversions package as a child of Bounded_Big_Integers. +Would there be any advantage to this approach? The advantage of the +proposed approach is visibility of the private part, but it does seem +awkward to have a generic with no generic formals and no local state.] + +A.5.5.2 Big Rationals + +The package Ada.Numerics.Big_Numbers.Big_Rationals has the following definition: + + with Ada.Numerics.Big_Numbers.Big_Integers; + package Ada.Numerics.Big_Numbers.Big_Rationals is + use Big_Integers; + + type Big_Rational is new Number with private + Default_Initial_Condition => Big_Rational = 0.0, + Real_Literal => From_String; - generic - type Int is mod <>; - package Unsigned_Conversions is - function To_Big_Integer (Arg : Int) return Big_Integer; - function From_Big_Integer (Arg : Big_Integer) return Int with - Pre => In_Range - (Arg, Lo => To_Big_Integer (Int'First), - Hi => To_Big_Integer (Int'Last)) - or else (raise Constraint_Error); - end Unsigned_Conversions; - - overriding function To_String (Arg : Big_Integer) return String; - overriding function From_String (Arg : String) return Big_Integer; - -- Accepts same syntax as Integer'Value (although accepts more digits); - -- progagates Constraint_Error if input doesn't meet this requirement. - - overriding function "-" (L : Big_Integer) return Big_Integer; - overriding function "abs" (L : Big_Integer) return Big_Integer; - overriding function "+" (L, R : Big_Integer) return Big_Integer; - overriding function "-" (L, R : Big_Integer) return Big_Integer; - overriding function "*" (L, R : Big_Integer) return Big_Integer; - overriding function "/" (L, R : Big_Integer) return Big_Integer; - function "mod" (L, R : Big_Integer) return Big_Integer; - function "rem" (L, R : Big_Integer) return Big_Integer; - function "**" (L : Big_Integer; R : Natural) return Big_Integer; - overriding function Min (L, R : Big_Integer) return Big_Integer; - overriding function Max (L, R : Big_Integer) return Big_Integer; + function "/" (Num, Den : Big_Integer) return Big_Rational + with Pre => (Den /= 0) or else (raise Constraint_Error); - function Last return Big_Integer is ((+256)**Capacity); - function First return Big_Integer is (-Last); -private - type Big_Integer is new Number with null record; -- bogus completion -end Big_Numbers.Bounded_Big_Integers; + function Numerator (Arg : Big_Rational) return Big_Integer; + function Denominator (Arg : Big_Rational) return Big_Positive; ----------------------------------------------------------------- + overriding function "+" (Arg : Integer) return Big_Rational is + ((+Arg) / 1); -with Big_Numbers.Big_Integers; -generic -package Big_Numbers.Bounded_Big_Integers.Conversions is - -- This unit is a child unit because we don't want - -- Big_Integers to be in the closure of Bounded_Big_Integers. - - function From_Unbounded (Arg : Big_Integers.Big_Integer) return Big_Integer; - function To_Unbounded (Arg : Big_Integer) return Big_Integers.Big_Integer; -end Big_Numbers.Bounded_Big_Integers.Conversions; - ----------------------------------------------------------------- - -with Big_Numbers.Big_Integers; -package Big_Numbers.Big_Rationals is - use Big_Integers; - - type Big_Rational is new Number with private; - -- Defaults to zero. - -- - -- Type_Invariant for Big_Rational is effectively - -- (Big_Rational = +0) or else - -- (GCD (abs Numerator (Big_Rational), - -- Denominator (Big_Rational)) = +1) or else - -- (raise Constraint_Error) - -- although we don't specify that here in visible part because - -- the operators called in the type invariant itself have - -- to be special in order to avoid infinite recursion. - - function "/" (Num, Den : Big_Integer) return Big_Rational with - Pre => (Den /= +0) or else (raise Constraint_Error); - - function Numerator (Arg : Big_Rational) return Big_Integer; - function Denominator (Arg : Big_Rational) return Big_Positive; - - overriding function "+" (Arg : Integer) return Big_Rational is - ((+Arg) / Big_Integer'(+1)); - - function To_Big_Rational (Arg : Integer) return Big_Rational renames "+"; - - overriding function "=" (L, R : Big_Rational) return Boolean; - overriding function "<" (L, R : Big_Rational) return Boolean; - overriding function "<=" (L, R : Big_Rational) return Boolean; - overriding function ">" (L, R : Big_Rational) return Boolean; - overriding function ">=" (L, R : Big_Rational) return Boolean; - - overriding function To_String (Arg : Big_Rational) return String is - (To_String (Numerator (Arg)) & " /" & To_String (Denominator (Arg))); - overriding function From_String (Arg : String) return Big_Rational; - -- inverse of To_String; propagates Constraint_Error in error cases. - - overriding function "-" (L : Big_Rational) return Big_Rational; - overriding function "abs" (L : Big_Rational) return Big_Rational; - overriding function "+" (L, R : Big_Rational) return Big_Rational; - overriding function "-" (L, R : Big_Rational) return Big_Rational; - overriding function "*" (L, R : Big_Rational) return Big_Rational; - overriding function "/" (L, R : Big_Rational) return Big_Rational; - function "**" (L : Big_Rational; R : Integer) return Big_Rational; - overriding function Min (L, R : Big_Rational) return Big_Rational; - overriding function Max (L, R : Big_Rational) return Big_Rational; -private - type Big_Rational is new Number with null record; -- bogus completion -end Big_Numbers.Big_Rationals; + function To_Big_Rational (Arg : Integer) return Big_Rational renames "+"; + overriding function "=" (L, R : Big_Rational) return Boolean; + overriding function "<" (L, R : Big_Rational) return Boolean; + overriding function "<=" (L, R : Big_Rational) return Boolean; + overriding function ">" (L, R : Big_Rational) return Boolean; + overriding function ">=" (L, R : Big_Rational) return Boolean; + + overriding function To_String (Arg : Big_Rational) return String is + (To_String (Numerator (Arg)) & " /" & To_String (Denominator (Arg))); + overriding function From_String (Arg : String) return Big_Rational; + + overriding function "-" (L : Big_Rational) return Big_Rational; + overriding function "abs" (L : Big_Rational) return Big_Rational; + overriding function "+" (L, R : Big_Rational) return Big_Rational; + overriding function "-" (L, R : Big_Rational) return Big_Rational; + overriding function "*" (L, R : Big_Rational) return Big_Rational; + overriding function "/" (L, R : Big_Rational) return Big_Rational; + function "**" (L : Big_Rational; R : Integer) return Big_Rational; + overriding function Min (L, R : Big_Rational) return Big_Rational; + overriding function Max (L, R : Big_Rational) return Big_Rational; + private + ... -- not specified by the language + end Ada.Numerics.Big_Numbers.Big_Rationals; + +From_String implements the inverse function of To_String; Constraint_Error is +propagated in error cases. +The other functions have their usual mathematical meanings. + +Any Big_Rational result R returned by any of these functions satisifies the +condition + (R = 0.0) or else + (Greatest_Common_Denominator (Numerator (R), Denominator (R)) = 1). -** Semantics rules TBD. +AARM Note: No Bounded_Big_Rationals generic package is provided. !discussion +** None yet. + !ASIS No ASIS effect (assuming this is ONLY a library). @@ -2975,5 +2990,156 @@ interface, which suggests that AI12-0249-1 needs a bit of extension.) Otherwise, I didn't notice anything that I would change. + +**************************************************************** + +From: Steve Baird +Sent: Sunday, March 4, 2018 1:00 AM + +> Shouldn't this be some set of children of Ada.Numerics? These kinda +> seem like numbers.;-) +> + +Good point. +So the root package for this stuff becomes Ada.Numerics.Big_Numbers. + + +> You don't have the numeric literal definitions (see AI12-0249-1) -- +> that seems necessary for usability. (One wonders if the literals +> should be defined on g interface, which suggests that AI12-0249-1 +> needs a bit of +> extension.) + +We decided earlier that we didn't want that inter-AI dependency. + +But I agree that if we we are willing to introduce that dependency then of +course support for literals would make sense. + +Should it be conditional, as in "if AI12-0249 is approved, then this AI also +includes blah, blah"? + +**************************************************************** + +From: Randy Brukardt +Sent: Sunday, March 4, 2018 1:16 AM + +Yes, I'd write it that way. I'd probably stay away from other AI dependencies, +but literals are pretty fundamental - supporting them makes the package way +more usable. + +**************************************************************** + +From: Steve Baird +Sent: Wednesday, March 28, 2018 6:50 PM + +Attached is proposed wording for this AI. [This is version /02 of this +AI - ED]. + +There are some TBDs interspersed. + +**************************************************************** + +From: Randy Brukardt +Sent: Thursday, March 29, 2018 7:48 PM + +> Attached is proposed wording for this AI. +> +> There are some TBDs interspersed. + +Here's a few thoughts: + +>[TBD: aspects specified for this package? Pure, Nonblocking, others? +>Same question applies to other packages declared in later sections. +>Would these aspects constrain implementations in undesirable ways?] + +All of the packages should be nonblocking. I don't think any reasonable +implementation would need access to delay statements. ;-) + +The interface package should be Pure (why not, it doesn't have any +implementation). The bounded package also should be pure (we do that for all +of the bounded forms elsewhere. + +The others probably should be preelaborated (and the types having +preelaborable_initialization), lest we make it too hard to use the needed +dynamic allocation. + +>[TBD: It would be nice to use subtypes in parameter profiles (e.g., +>a Nonzero_Number subtype for second argument of "/", but this requires +>AI12-0243 and the future of that AI is very uncertain.] + +You can always use a Pre'Class as an alternative to a subtype. It's not +quite as convenient, but it makes the same check, and presuming that +AI12-0112-1 stays are currently envisioned, that check would be suppressible +with "pragma Suppress (Numerics_Check);". + +>[TBD: Remove Integer_Literal aspect spec if AI12-0249-1 not approved. +>If Default_Initial_Condition AI12-0265-1 is approved and Integer_Literal AI +is +>not then replace "0" with "+0" in the condition and as needed in +>subsequent conditions.] + +I put the AI number in here for Default_Initial_Condition. + +>[TBD: In_Range formal parameter names. "Lo & Hi" vs. "Low & High"?] + +Ada usually doesn't use abbreviations, and saving one or two characters this +way isn't appealing. Use Low and High. + +> A.5.5.1.1 Bounded Big Integers + +Umm, please, no 5 level subclauses. Since there are currently no four level +items in the RM, we need to discuss that explicitly. I had to add a fourth +level for ASIS, but Ada only uses three levels. And the ACATS only uses two +levels in the annexes, which is already a problem for the containers (there +being only one set of sequence numbers for all of the containers tests). + +>AARM Note: Roughly speaking, behavior is as if the type invariant for +> Bounded_Big_Integer is +> In_Range (Bounded_Big_Integer, First, Last) or else (raise +Constraint_Error) +>although that is not specified explicitly because that would +>require introducing some awkward code in order to avoid infinite +>recursion. + +Awkward code? Please explain. Type invariants are explicitly not enforced on +'in' parameters of functions specifically to avoid infinite recursion in the +type invariant expression. You'd probably need a function for this purpose +(to avoid the functions First and Last -- is that what you meant??), say: + In_Base_Range (Bounded_Big_Integer) or else (raise Constraint_Error) +where In_Base_Range is equivalent to In_Range (Bounded_Big_Integer, First, +Last) with the expressions of First and Last substituted. One could also +make those expressions the defaults for Low and High. + +>[TBD: This could be done differently by using a formal instance instead +>of declaring the Conversions package as a child of Bounded_Big_Integers. +>Would there be any advantage to this approach? The advantage of the +>proposed approach is visibility of the private part, but it does seem +>awkward to have a generic with no generic formals and no local state.] + +Well, it would be easier to implement in Janus/Ada, where we never got +sprouting to work. But that's hardly a reason. I suspect it would be more +obvious what's going on than a generic child -- as a data point, all of the +extra operations of Ada.Strings.Bounded take formal packages rather than +being children -- but that may have been driven by other considerations. + +One argument for making it a formal package is that this conversion package +really belongs to both big number packages -- it's somewhat artificial to +make it live in the hierarchy of one or the other. + +>Any Big_Rational result R returned by any of these functions satisifies the +>condition +> (R = 0.0) or else +> (Greatest_Common_Denominator (Numerator (R), Denominator (R)) = 1). + +Arguably, that should be a postcondition, since the implementation isn't +required to check it (it it required to *pass* it). Then a separate rule +isn't needed. You'd probably want to declare a function with this meaning, +'cause duplicating the above 2 dozen times would be annoying. + +>AARM Note: No Bounded_Big_Rationals generic package is provided. + +We've discussed why, but there needs to be a version of that discussion +either in this note or in the (sadly empty) !discussion section. Future +readers will be puzzled otherwise (including, most likely, us). ****************************************************************

Questions? Ask the ACAA Technical Agent