=pod

=encoding utf8

=head1 NAME

Muldis::D::Ext::Rational -
Muldis D extension for rational data types and operators

=head1 VERSION

This document is Muldis::D::Ext::Rational version 0.58.0.

=head1 PREFACE

This document is part of the Muldis D language specification, whose root
document is L<Muldis::D>; you should read that root document
before you read this one, which provides subservient details.

=head1 DESCRIPTION

Muldis D has a mandatory core set of system-defined (eternally available)
entities, which is referred to as the I<Muldis D core> or the I<core>; they
are the minimal entities that all Muldis D implementations need to provide;
they are mutually self-describing and are used to bootstrap the language;
any entities outside the core, called I<Muldis D extensions>, are
non-mandatory and are defined in terms of the core or each other, but the
reverse isn't true.

This current C<Rational> document describes the system-defined I<Muldis D
Rational Extension>, which consists of rational data types and operators in
general, and not just integers such as the language core has.

This current document does not describe the polymorphic operators that all
types, or some types including core types, have defined over them; said
operators are defined once for all types in L<Muldis::D::Core>.

I<This documentation is pending.>

=head1 TYPE SUMMARY

Following are all the data types described in this document, arranged in a
type graph according to their proper sub|supertype relationships (but that
a few of them just reappear from the core set to provide a similar context,
and aren't re-described here):

    sys.std.Core.Type.Universal

        sys.std.Core.Type.Empty

        sys.std.Core.Type.QScalar
            sys.std.Core.Type.Scalar

                # The following are all regular ordered scalar types.

                sys.std.Rational.Type.Rat
                    sys.std.Rational.Type.NNRat
                        sys.std.Rational.Type.PRat
                    sys.std.Rational.Type.BRat
                    sys.std.Rational.Type.DRat

                sys.std.Core.Type.Int
                    sys.std.Core.Type.NNInt
                        sys.std.Core.Type.PInt

                            # These are all integer types.

                            sys.std.Rational.Type.PInt2_N

                            # These are all finite integer types.

                            sys.std.Rational.Type.PInt2_36

                # The following are all regular non-ordered scalar types.

                sys.std.Rational.Type.RatRoundMeth

        sys.std.Core.Type.QTuple
            sys.std.Core.Type.Tuple

                # The following are all regular tuple types.

                sys.std.Rational.Type.RatRoundRule

I<This documentation is pending.>

=head1 SYSTEM-DEFINED RATIONAL-CONCERNING DATA TYPES

=head2 sys.std.Rational.Type.PInt2_N

This is an enumeration data type.  C<PInt2_N> is a proper subtype of
C<PInt> where all member values are greater than 1.  Its default and
minimum value is 2.

=head2 sys.std.Rational.Type.PInt2_36

This is an enumeration data type.  C<PInt2_36> is a proper subtype of
C<PInt> where all member values are between 2 and 36.  (The significance of
the number 36 is 10 digits plus 26 letters.)  Its default and minimum value
is 2.  Its maximum value is 36.  The cardinality of this type is 35.

=head2 sys.std.Rational.Type.Rat

This is a structure data type.  A C<Rat> (scalar) is a single exact
rational number of any magnitude and precision.  It is conceptually a
composite type with 2 main system-defined possreps, called C<ratio> and
C<float>, both of which are defined over several C<Int>.

The C<ratio> possrep consists of 2 attributes: C<numerator> (an C<Int>),
C<denominator> (a C<PInt>); the conceptual value of a C<Rat> is the result
of rational-dividing its C<numerator> by its C<denominator>.  Because in
the general case there are an infinite set of [C<numerator>,C<denominator>]
integer pairs that denote the same rational value, the C<ratio> possrep
carries the normalization constraint that C<numerator> and C<denominator>
must be coprime, that is, they have no common integer factors other than 1.

The C<float> possrep consists of 3 attributes: C<mantissa> (an C<Int>),
C<radix> (a C<PInt2_N>), C<exponent> (an C<Int>); the conceptual value
of a C<Rat> is the result of multiplying its C<mantissa> by the result of
taking its C<radix> to the power of its C<exponent>.  The C<float> possrep
carries the normalization constraint that among all the
[C<mantissa>,C<radix>,C<exponent>] triples which would denote the same
rational value, the only allowed triple is the one having both the C<radix>
with the lowest value (that is closest to or equal to 2) and the
C<exponent> with the highest value (that is closest to positive infinity).
I<Note: this constraint could stand to be rephrased for simplification or
correction, eg if somehow the sets of candidate triples sharing the lowest
radix and sharing the highest exponent have an empty intersection.>

The default value of C<Rat> is zero; its minimum and maximum values are
conceptually infinities and practically impossible.  The cardinality of
this type is infinity; to define a most-generalized finite C<Rat> subtype,
you must specify the greatest magnitude value denominator, plus the the 2
integer end-points of the inclusive range of the value numerator; or
alternately you must specify the greatest magnitude value mantissa (the
I<maximum precision> of the number), and specify the greatest magnitude
value radix, plus the the 2 integer end-points of the inclusive range of
the value exponent (the I<maximum scale> of the number).  Common subtypes
specify that the normalized radixes of all their values are either 2 or 10;
types such as these will easily map exactly to common human or physical
numeric representations, so they tend to perform better.

The C<Rat> type has a default ordering algorithm which is conceptually the
same as for C<Int>; for 2 distinct C<Rat> values, the value closer to
negative infinity is ordered before the value closer to positive infinity.

The C<Rat> type has an implementation hint for less intelligent Muldis D
implementations, that suggests using the C<float> possrep as the basis for
the physical representation.

=head2 sys.std.Rational.Type.NNRat

This is an enumeration data type.  C<NNRat> (non-negative rational) is a
proper subtype of C<Rat> where all member values are greater than or equal
to zero (that is, the C<numerator>|C<mantissa> is greater than or equal to
zero).  Its minimum value is zero.

=head2 sys.std.Rational.Type.PRat

This is an enumeration data type.  C<PRat> (positive rational) is a
proper subtype of C<NNRat> where all member values are greater than zero
(that is, the C<numerator>|C<mantissa> is greater than zero).  Its default
and minimum value is 1.

=head2 sys.std.Rational.Type.BRat

This is an enumeration data type.  C<BRat> (binary rational) is a proper
subtype of C<Rat> where the C<radix> is 2; it is the best option to exactly
represent rational numbers that are conceptually binary or octal or
hexadecimal.

=head2 sys.std.Rational.Type.DRat

This is an enumeration data type.  C<DRat> (decimal rational) is a proper
subtype of C<Rat> where the C<radix> is 10 (or if it could be without the
C<float> possrep normalization constraint); it is the best option to
exactly represent rational numbers that are conceptually the decimal
numbers that humans typically work with.

=head2 sys.std.Rational.Type.RatRoundMeth

This is a structure data type.  C<RatRoundMeth> (rounding method) consists
of just the 7 values C<half_down>, C<half_up>, C<half_even>, C<to_floor>,
C<to_ceiling>, C<to_zero>, C<to_inf>.  A C<RatRoundMeth> has 1
system-defined possrep whose name is the empty string, which has 1
C<Name>-typed attribute whose name is the empty string.  When a value
of some ordered type needs to be mapped into a proper subtype that doesn't
contain that value, such as when mapping an arbitrary number to one with
less precision, some rounding method is applied to determine which value of
the subtype is to be mapped to while most accurately reflecting the
original value.  The C<RatRoundMeth> type enumerates the rounding methods
that Muldis D operators can typically apply.  With C<half_down>,
C<half_up>, and C<half_even> (aka I<unbiased rounding>, I<convergent
rounding>, I<statistician's rounding>, or I<bankers' rounding>), the
original value will be mapped to the single target value that it is closest
to, if there is one; otherwise, if it is exactly half-way between 2
adjacent target values, then C<half_down> will round towards negative
infinity, C<half_up> will round towards positive infinity, and C<half_even>
will round towards the nearest "even" target.  With C<to_floor>,
C<to_ceiling>, C<to_zero> (aka I<truncate>), C<to_inf>, the original value
will always be mapped to the single adjacent value that is lower than it,
or higher than it, or towards "zero" from it, or towards the nearer
infinity from it, respectively.  The default value of C<RatRoundMeth> is
C<half_up>, since that is the most commonly used method of rounding.  The
C<RatRoundMeth> type does I<not> have a default ordering algorithm.

=head2 sys.std.Rational.Type.RatRoundRule

This is an enumeration data type.  A C<RatRoundRule> is a C<Tuple>.  It
specifies a controlled (and typically degrading) coercion of a real number
into a rational number having a specific radix and precision.  It is mainly
used to deterministically massage an operation, whose conceptual result is
generally an irrational number, so that its actual result is a best
approximating rational number.  It is also used to define a generic
rounding operation on a rational number that derives a typically less
precise rational.  A C<RatRoundRule> has these 3 attributes: C<radix> (a
C<PInt2_N>), C<max_denom> (a C<PInt>), and C<round_meth> (a
C<RatRoundMeth>).  The rational resulting from the operation is as close as
possible to the conceptual result but that its denominator is a
non-negative power of C<radix> and said denominator is not larger than
C<max_denom>; if rounding is needed, then C<round_meth> dictates the
rounding method.  The default value of C<RatRoundRule> specifies a coersion
to a whole number using the C<half_up> rounding method (its radix is 2 and
its max denom is 1).

=head1 FUNCTIONS FOR RATIONAL MATH

These functions implement commonly used rational numeric operations.

=over

=item C<function sys.std.Rational.abs result NNRat params { topic(Rat) }>

This function results in the absolute value of its argument.

=item C<function sys.std.Rational.sum result Rat params {
addends(bag_of.Rat) }>

This function results in the sum of the N element values of its argument;
it is a reduction operator that recursively takes each pair of input values
and adds (which is both commutative and associative) them together until
just one is left, which is the result.  If C<addends> has zero values, then
C<sum> results in the rational zero, which is the identity value for
addition.

=item C<function sys.std.Rational.difference result Rat params {
minuend(Rat), subtrahend(Rat) }>

This function results in the difference when its C<subtrahend> argument is
subtracted from its C<minuend> argument.

=item C<function sys.std.Rational.abs_difference result Rat params {
topic(Rat), other(Rat) }>

This function results in the absolute difference between its 2 arguments.

=item C<function sys.std.Rational.product result Rat params {
factors(bag_of.Rat) }>

This function results in the product of the N element values of its
argument; it is a reduction operator that recursively takes each pair of
input values and multiplies (which is both commutative and associative)
them together until just one is left, which is the result.  If C<factors>
has zero values, then C<product> results in the rational 1, which is the
identity value for multiplication.

=item C<function sys.std.Rational.quotient result Rat params {
dividend(Rat), divisor(Rat) }>

This function results in the quotient when its C<dividend> argument is
divided by its C<divisor> argument using rational division.  This function
will fail if C<divisor> is zero.

=item C<function sys.std.Rational.maybe_quotient result maybe_of.Rat params
{ dividend(Rat), divisor(Rat) }>

This function is exactly the same as C<sys.std.Rational.quotient> except
that it results in a C<Maybe> of what is otherwise the result, and that
result has zero elements if C<divisor> is zero.

=item C<function sys.std.Rational.range result Rat params {
topic(set_of.Rat) }>

This function results in the difference between the lowest and highest
element values of its argument.  If C<topic> has zero values, then C<range>
results in the rational zero.

=item C<function sys.std.Rational.mean result Rat params {
topic(bag_of.Rat) }>

This function results in the mean or arithmetic average of the N element
values of its argument.  It is equivalent to first taking the sum of the
input values, and dividing that sum by the count of the input values.  If
C<topic> has zero values, then this function will fail.

=item C<function sys.std.Rational.maybe_mean result maybe_of.Rat params {
topic(bag_of.Rat) }>

This function is exactly the same as C<sys.std.Rational.mean> except that
it results in a C<Maybe> of what is otherwise the result, and that result
has zero elements if C<topic> has zero values.

=item C<function sys.std.Rational.median result set_of.Rat params {
topic(bag_of.Rat) }>

This function results in the 1 or 2 median values of the N element values
of its argument; they are returned as a set.  It is equivalent to first
arranging the input values from least to greatest, and then taking the
single middle value, if the count of input values is odd, or taking the 2
middle values, if the count of input values is even (but if the 2 middle
values are the same value, the output has one element).  If C<topic> has
zero values, then the result set is empty.

=item C<function sys.std.Rational.mean_of_median result Rat params {
topic(bag_of.Rat) }>

This function is a wrapper over C<sys.std.Rational.median> that will result
in the mean of its result elements; it will fail if there are zero
elements.

=item C<function sys.std.Rational.mode result set_of.Rat params {
topic(bag_of.Rat) }>

This function results in the mode of the N element values of its argument;
it is the set of values that appear the most often as input elements, and
all have the same count of occurrances.  As a trivial case, if all input
elements have the same count of occurrances, then they will all be in the
output.  If C<topic> has zero values, then the result set is empty.

=item C<function sys.std.Rational.round result Rat params { topic(Rat),
round_rule(RatRoundRule) }>

This function results in the rational that is equal to or otherwise nearest
to its C<topic> argument, where the nearest is determined by the rational
rounding rule specified by the C<round_rule> argument.

=item C<function sys.std.Rational.power result PRat params { radix(PRat),
exponent(Rat) }>

This function results in its (positive rational) C<radix> argument taken to
the power of its C<exponent> argument.  Note that, while this function
might conceptually have multiple real number results for some fractional
C<exponent>, it will always only result in the one that is positive.

=item C<function sys.std.Rational.log result Rat params { topic(PRat),
radix(PRat), round_rule(RatRoundRule) }>

This function results in the logarithm of its C<topic> argument to the base
given in its (positive rational) C<radix> argument.  Since the result would
be an irrational number in the general case, the C<round_rule> argument
specifies how to coerce the conceptual result into a rational number that
is the actual result.

=item C<function sys.std.Rational.natural_power result PRat params {
exponent(Rat), round_rule(RatRoundRule) }>

This function results in the special mathematical constant I<e> (which is
the base of the natural logarithm) taken to the power of its C<exponent>
argument.  The C<round_rule> parameter is as per C<log>.

=item C<function sys.std.Rational.natural_log result Rat params {
topic(PRat), round_rule(RatRoundRule) }>

This function results in the natural logarithm of its C<topic> argument.
The C<round_rule> parameter is as per C<log>.

=back

=head1 FUNCTIONS FOR RATIONAL CONVERSION WITH TEXT

These functions convert between C<Rat> values and canonically formatted
representations of rationals as character strings.

=over

=item C<function sys.std.Rational.Rat_from_Text result Rat params {
text(Text), radix(PInt2_36) }>

This selector function results in the C<Rat> value that its (not-empty)
C<text> argument maps to when the whole character string is evaluated as a
base-C<radix> rational.  Extending the typical formats of [base-2, base-8,
base-10, base-16], this function supports base-2 through base-36; to get
the latter, the characters 0-9 and A-Z represent values in 0-35.  This
function will fail if C<text> can't be mapped as specified.

=item C<function sys.std.Rational.Text_from_Rat result Text params {
rat(Rat), radix(PInt2_36) }>

This selector function results in the (not-empty) C<Text> value where its
C<rat> argument is formatted as a base-C<radix> rational.

=back

=head1 FUNCTIONS FOR RATIONAL CONVERSION WITH INTEGER

These functions convert between C<Rat> values and equal or nearly equal
C<Int> values.

=over

=item C<function sys.std.Rational.Rat_from_Int result Rat params { int(Int)
}>

This selector function results in the C<Rat> value that is conceptually
equal to its C<Int> argument.

=item C<function sys.std.Rational.Int_from_Rat result Int params {
rat(Rat), round_meth(RatRoundMeth) }>

This selector function results in the C<Int> value that is conceptually
equal to or otherwise nearest to its C<rat> argument, where the nearest is
determined by the rounding method specified by the C<round_meth> argument.

=back

=head1 SYSTEM SERVICES FOR RANDOM NUMBER GENERATORS

These system service routines provide ways to get random numbers from the
system.  Where the results are in the range between truly random and
pseudo-random is, for the moment, an implementation detail, but the details
of these functions is subject to become more formalized later.

=over

=item C<system_service sys.std.Rational.fetch_random update { target(Rat) }
read { radix(PInt2_N), max_denom(PInt), min(Rat), max(Rat),
exclude_min(Bool)?, exclude_max(Bool)? }>

This system service routine will update the variable supplied as its
C<target> argument so that it holds a randomly generated rational value in
the range whose bounds are defined by its C<min> and C<max> arguments.  The
denominator attribute of the generated value will be a non-negative power
of C<radix> that is not larger than C<max_denom>.  If C<exclude_min> or
C<exclude_max> are C<Bool:true>, then the randomly generated value will not
be equal to C<min> or C<max>, respectively; otherwise, the generated value
might be equal to C<min> or C<max>.  This function will fail if C<max> is
before C<min>.  Each of the C<exclude_m(in|ax)> parameters is optional and
defaults to C<Bool:false> if no explicit argument is given to it.

=back

=head1 SEE ALSO

Go to L<Muldis::D> for the majority of distribution-internal
references, and L<Muldis::D::SeeAlso> for the majority of
distribution-external references.

=head1 AUTHOR

Darren Duncan (C<perl@DarrenDuncan.net>)

=head1 LICENSE AND COPYRIGHT

This file is part of the formal specification of the Muldis D language.

Muldis D is Copyright © 2002-2009, Darren Duncan.

See the LICENSE AND COPYRIGHT of L<Muldis::D> for details.

=head1 TRADEMARK POLICY

The TRADEMARK POLICY in L<Muldis::D> applies to this file too.

=head1 ACKNOWLEDGEMENTS

The ACKNOWLEDGEMENTS in L<Muldis::D> apply to this file too.

=cut
