=pod

=encoding utf8

=head1 NAME

Muldis::D::Core::Types -
Muldis D general purpose data types

=head1 VERSION

This document is Muldis::D::Core::Types version 0.132.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.  Moreover, you
should read the L<Muldis::D::Core> document before this current
document, as that forms its own tree beneath a root document branch.

=head1 DESCRIPTION

These core data types are general-purpose in nature and are intended
for use in defining or working with normal user data.

=head1 TYPE SUMMARY

This section shows all the data types and data type factories described in
this document, arranged in a type graph according to their proper
sub|supertype relationships.  Since there are a number of types with
multiple parents, those types may appear multiple times in the graph;
moreover, the graph is displayed in multiple slices, some of which are
different views of the same type relationships.  As a notable exception,
C<sys.std.Core.Type.Empty> is a proper subtype of I<all> of the other types
in this graph, but it is only shown once.

This graph slice shows all of the top-level types as is relevant from the
user's point of view:

    sys.std.Core.Type.Universal
        sys.std.Core.Type.Empty
        sys.std.Core.Type.Scalar
            sys.std.Core.Type.DHScalar
                sys.std.Core.Type.Bool
                sys.std.Core.Type.Int
                sys.std.Core.Type.Rat
                sys.std.Core.Type.Blob
                sys.std.Core.Type.Text
        sys.std.Core.Type.Tuple
            sys.std.Core.Type.DHTuple
                sys.std.Core.Type.Database
        sys.std.Core.Type.Relation
            sys.std.Core.Type.DHRelation
        sys.std.Core.Type.External

This arrangement is user-significant for 2 main reasons.  The first reason
is that general semantics and intended interpretations of values and types
fall into 4 main lines, represented by C<Scalar|Tuple|Relation|External>.
The second reason is that only values of the 3 deeply-homogeneous types
shown above (C<DH[Scalar|Tuple|Relation]>) may be used in a database; all
values not of those types may only be used transiently.  The fact that
C<Int> is atomic while the other scalar types aren't is not relevant to
users in the general case.

This graph slice shows all of those same top-level types, plus a few more,
as is relevant from the implementer's point of view:

    sys.std.Core.Type.Universal
        sys.std.Core.Type.Int
        sys.std.Core.Type.Cat.List
            sys.std.Core.Type.Cat.Structure
                sys.std.Core.Type.Cat.String
                sys.std.Core.Type.Tuple
                    sys.std.Core.Type.DHTuple
                        sys.std.Core.Type.Database
                sys.std.Core.Type.Relation
                    sys.std.Core.Type.DHRelation
                sys.std.Core.Type.Cat.ScalarWP
                    sys.std.Core.Type.Cat.DHScalarWP
                        sys.std.Core.Type.Bool
                        sys.std.Core.Type.Rat
                        sys.std.Core.Type.Blob
                        sys.std.Core.Type.Text
                sys.std.Core.Type.External
            sys.std.Core.Type.Cat.Nonstructure

This arrangement is implementer-significant because it best illustrates the
conceptual implementation of the types; C<Int> and C<List> are the only 2
types that actually introduce values into the type system, and all other
types are subset and/or union types composing their values; so, I<every>
Muldis D value either I<is> an C<Int> or I<is> a C<List>.  The fact that
C<Scalar> composes both C<Int> and C<List> values while
C<Tuple|Relation|External> compose only C<List> values is less important.

This graph slice shows all of the general-purpose system-defined scalar
types:

    sys.std.Core.Type.Universal
        sys.std.Core.Type.Scalar
            sys.std.Core.Type.Cat.ScalarWP
                sys.std.Core.Type.Cat.DHScalarWP
            sys.std.Core.Type.DHScalar
                sys.std.Core.Type.Int
                    sys.std.Core.Type.NNInt
                        sys.std.Core.Type.PInt
                            sys.std.Core.Type.PInt2_N
                sys.std.Core.Type.Cat.String
                sys.std.Core.Type.Cat.DHScalarWP
                    sys.std.Core.Type.Bool
                        sys.std.Core.Type.Bool.*
                    sys.std.Core.Type.Rat
                        sys.std.Core.Type.NNRat
                            sys.std.Core.Type.PRat
                    sys.std.Core.Type.Blob
                        sys.std.Core.Type.OctetBlob
                    sys.std.Core.Type.Text

To be clear, C<ScalarWP> is the intersection type of C<List> and C<Scalar>,
and C<DHScalarWP> is the intersection type of C<ScalarWP> and C<DHScalar>;
or, C<Scalar> is the union type of just C<Int>, C<String> and C<ScalarWP>,
and C<DHScalar> is the union type of just C<Int>, C<String> and
C<DHScalarWP>.

This graph slice shows all of the general-purpose system-defined nonscalar
type factories:

    sys.std.Core.Type.Universal
        sys.std.Core.Type.Cat.List
            sys.std.Core.Type.Cat.Structure

                sys.std.Core.Type.Tuple
                    sys.std.Core.Type.DHTuple
                        sys.std.Core.Type.Database
                    sys.std.Core.Type.Set.T
                        sys.std.Core.Type.DHSet.T
                    sys.std.Core.Type.Array.T
                        sys.std.Core.Type.DHArray.T
                    sys.std.Core.Type.Bag.T
                        sys.std.Core.Type.DHBag.T
                    sys.std.Core.Type.SPInterval
                        sys.std.Core.Type.DHSPInterval

                sys.std.Core.Type.Relation
                    sys.std.Core.Type.DHRelation
                    sys.std.Core.Type.Set
                        sys.std.Core.Type.DHSet
                        sys.std.Core.Type.Maybe
                            sys.std.Core.Type.DHMaybe
                            sys.std.Core.Type.Just
                                sys.std.Core.Type.DHJust
                    sys.std.Core.Type.Array
                        sys.std.Core.Type.DHArray
                    sys.std.Core.Type.Bag
                        sys.std.Core.Type.DHBag
                    sys.std.Core.Type.MPInterval
                        sys.std.Core.Type.DHMPInterval

This graph slice shows all of those same nonscalar types, with a different
view of their relationships:

    sys.std.Core.Type.Universal
        sys.std.Core.Type.Cat.List
            sys.std.Core.Type.Cat.Structure

                sys.std.Core.Type.Tuple
                    sys.std.Core.Type.DHTuple
                        sys.std.Core.Type.Database
                        sys.std.Core.Type.DHSet.T
                        sys.std.Core.Type.DHArray.T
                        sys.std.Core.Type.DHBag.T
                        sys.std.Core.Type.DHSPInterval
                    sys.std.Core.Type.Set.T
                    sys.std.Core.Type.Array.T
                    sys.std.Core.Type.Bag.T
                    sys.std.Core.Type.SPInterval

                sys.std.Core.Type.Relation
                    sys.std.Core.Type.DHRelation
                        sys.std.Core.Type.DHSet
                            sys.std.Core.Type.DHMaybe
                                sys.std.Core.Type.DHJust
                        sys.std.Core.Type.DHArray
                        sys.std.Core.Type.DHBag
                        sys.std.Core.Type.DHMPInterval
                    sys.std.Core.Type.Set
                        sys.std.Core.Type.Maybe
                            sys.std.Core.Type.Just
                    sys.std.Core.Type.Array
                    sys.std.Core.Type.Bag
                    sys.std.Core.Type.MPInterval

To be clear, all of the nonscalar C<DH>-prefixed types except for
C<DH[Tuple|Relation]> are intersection types of one of the latter two plus
the same-named types sans the prefix.

This graph slice shows all of the general-purpose system-defined types that
compose any mixin types, shown grouped under the mixin types that they
compose:

    sys.std.Core.Type.Universal

        sys.std.Core.Type.Ordered

            sys.std.Core.Type.Rat
            sys.std.Core.Type.Blob
            sys.std.Core.Type.Text

            sys.std.Core.Type.Ordinal

                sys.std.Core.Type.Bool
                sys.std.Core.Type.Int

        sys.std.Core.Type.Numeric

            sys.std.Core.Type.Int
            sys.std.Core.Type.Rat

        sys.std.Core.Type.Stringy

            sys.std.Core.Type.Blob
            sys.std.Core.Type.Text
            sys.std.Core.Type.Array

=head1 MAXIMAL AND MINIMAL DATA TYPES

These core data types are special and are the only Muldis D types (except
for C<sys.std.Core.Type.Cat.[List|Structure]>) that are neither just scalar
nor nonscalar nor external nor nonstructure types.  They are all
system-defined and it is impossible for users to define more types of this
nature.

=head2 sys.std.Core.Type.Universal

The C<Universal> type is the maximal
type of the entire Muldis D type system, and contains every value that can
possibly exist.  Every other (non-aliased) type is implicitly a proper
subtype of C<Universal>, and C<Universal> is implicitly a union type over
all other types.  Its default value is C<Bool:False>.  The cardinality of
this type is infinity.  Considering the low-level type system, C<Universal>
is conceptually the union type of just the 2 types C<Int> and C<List>.

=head2 sys.std.Core.Type.Empty

The C<Empty> type is the minimal type of
the entire Muldis D type system, and is the only type that contains exactly
zero values.  Every other (non-aliased) type is implicitly a proper
supertype of C<Empty> and C<Empty> is implicitly an intersection type over
all other types.  It has no default value.  The cardinality of this type is
zero.  Considering the low-level type system, C<Empty> is
conceptually the intersection type of just the 2 types C<Int> and C<List>.

=head1 GENERIC MIXIN DATA TYPES

=head2 sys.std.Core.Type.Ordered

The C<Ordered> type is a mixin (union) type that is intended to be
explicitly composed by all other types that are considered I<ordered>.  An
ordered type is a type for which one can take all of its values and place
them on a line such that each value is definatively considered I<before>
all of the values one one side and I<after> all of the values on the other
side.  A typical ordered type is a scalar type, but not-scalar types can
also be ordered.  Almost all system-defined scalar types are also ordered
types, including: C<Bool>, C<Int>, C<Rat>, C<Blob>, C<Text>.  The
cardinality of C<Ordered> is infinity.  The default value of C<Ordered> is
C<Bool:False>.  The minimum and maximum values of C<Ordered> are C<-Inf>
and C<Inf>, respectively; these 2 values are special singleton scalar types
that are canonically considered to be before and after, respectively,
I<every> other value of the Muldis D type system, regardless of whether
those values are composed into an ordered type.

=head2 sys.std.Core.Type.Ordinal

The C<Ordinal> type is a mixin (union) type that is intended to be
explicitly composed by all other types that are considered I<ordinal>.  An
ordinal type is an ordered type for which one can take any one of its
values and derive a definitive predecessor or successor value, iff the
initial value isn't the first or last value on the line.  Similarly, one
can take any two values of an ordinal type and produce an ordered list of
all of that value's types which are on the line between those two values.
The C<Ordinal> type explicitly composes the C<Ordered> mixin type, and so
every type which explicitly composes C<Ordinal> also implicitly composes
C<Ordered>.  Just a few system-defined ordered types are also ordinal
types, including: C<Bool>, C<Int>.  A primary quality of a type that is
ordered but not ordinal is that you can take any two values of that type
and then find a third value of that type which lies between the first two
on the line; by definition for an ordinal type, there is no third value
between one of its values and that value's predecessor or successor value.
The cardinality of C<Ordinal> is infinity; its default and minimum and
maximum values are the same as those of C<Ordered>.

For some ordinal types, there is the concept of a I<quantum> or I<step
size>, where every consecutive pair of values on that type's value line are
conceptually spaced apart at equal distances; this distance would be the
quantum, and all steps along the value line are at exact multiples of that
quantum.  However, ordinal types in general don't need to be like this, and
there can be different amounts of conceivable distance between consecutive
values; an ordinal type is just required to know where all the values are.

=head2 sys.std.Core.Type.Numeric

The C<Numeric> type is a mixin (union) type that is intended to be
explicitly composed by all other types that are considered I<numeric>.  A
numeric type is a type with whose values it would be reasonable to apply
all of the common mathematical operators like C<+>, C<->, C<*>, C</>.  Just
a few primary system-defined types are numeric types, including C<Int> and
C<Rat>.  The cardinality of C<Numeric> is infinity.  The default value of
C<Numeric> is the C<Int> value zero.  The C<Numeric> type is not itself
ordered, but often a type which is numeric is also ordered.  Muldis D does
not currently have any system-defined complex number types, but if it did,
they conceivably would also compose C<Numeric>; but in that case, it may
prove useful to split the C<Numeric> mixin into itself and a C<Real> mixin.

=head2 sys.std.Core.Type.Stringy

The C<Stringy> type is a mixin (union) type that is intended to be
explicitly composed by all other types that are considered I<stringy>,
which for the moment also includes any types whose values are an ordered
collection of elements, such as arrays.  A stringy type is a type with
whose values it would be reasonable to apply all of the common string or
array operators like C<~> or C<x>.  Just a few primary system-defined types
are stringy types, including C<Blob>, C<Text>, and C<Array>.  The
cardinality of C<Stringy> is infinity.  The default value of C<Stringy> is
the C<Text> value empty string.  The C<Stringy> type is not itself ordered,
but often a type which is stringy is also ordered.

=head1 GENERIC SCALAR DATA TYPES

These core scalar data types are the most fundamental Muldis D types.
Plain Text Muldis D provides a specific syntax per type to select a value
of every one of these types (or of their super/subtypes), which does not
look like a routine invocation, but rather like a scalar literal in a
typical programming language; details of that syntax are not given here,
but in L<Muldis::D::Dialect::PTMD_STD>.  Hosted Data Muldis D as hosted in
another language will essentially use literals of corresponding host
language types, whatever they use for eg booleans and integers and
character strings, but tagged with extra metadata if the host language is
more weakly typed or lacks one-to-one type correspondence; see
L<Muldis::D::Dialect::HDMD_Perl6_STD> or
L<Muldis::D::Dialect::HDMD_Perl5_STD> for a Perl 6|5-based example.  These
types, except for C<Scalar> and C<DHScalar>, are all ordered.

=head2 sys.std.Core.Type.Scalar

The C<Scalar> type is the maximal type of all Muldis D scalar types, and
contains every scalar value that can possibly exist.  Every other
(non-aliased) scalar type is implicitly a proper subtype of C<Scalar>, and
C<Scalar> is implicitly a union type over all other scalar types.  Its
default value is C<Bool:False>.  The cardinality of this type is infinity.
Considering the low-level type system, C<Scalar> is just the union type of
these 3 types: C<Int>, C<String>, C<ScalarWP>.

=head2 sys.std.Core.Type.DHScalar

C<DHScalar> is a proper subtype of
C<Scalar> where every one of its possreps' attributes is restricted to be
of just certain categories of data types, rather than allowing any data
types at all; related to this restriction, any dh-scalar value is allowed
to be stored in a global/persisting relational database but any other
scalar value may only be used for transient data.  The C<DHScalar> type is
the maximal type of all Muldis D dh-scalar types, and contains every
dh-scalar value that can possibly exist.  Every other (non-aliased)
dh-scalar type is implicitly a proper subtype of C<DHScalar>, and
C<DHScalar> is implicitly a union type over all other dh-scalar types.  Its
default value is C<Bool:False>.  The cardinality of this type is infinity.
Considering the low-level type system, C<Scalar> is just the union type of
these 3 types: C<Int>, C<String>, C<DHScalarWP>.

=head2 sys.std.Core.Type.Bool

The C<Bool> type is explicitly defined
as a union type over just these 2 singleton types having
C<sys.std.Core.Type.Bool.*>-format names:
C<False> and C<True>.  A C<Bool> represents a truth value, and is the
result type of any C<is_identical> or C<is_not_identical> routine; it is
the only essential general-purpose scalar data type of a generic B<D>
language, although not the only essential one in Muldis D.
The default and minimum value of C<Bool> is
C<False>; its maximum value is C<True>.  The cardinality of this type is 2.
The C<Bool> type explicitly composes the C<Ordinal> mixin type, and by
extension also implicitly composes the C<Ordered> mixin type.
The C<Bool> type has a default ordering algorithm that corresponds directly
to the sequence in which its values are documented here; C<False> is
ordered before C<True>.

The value C<Bool:False> is also known as C<False> and I<contradiction> and
C<⊥>.  The value C<Bool:True> is also known as C<True> and I<tautology> and
C<⊤>.

=head2 sys.std.Core.Type.Bool.*

There are exactly 2 types having C<sys.std.Core.Type.Bool.*>-format names;
for the rest of this description,
the type name C<Bool.Value> will be used as a proxy for each and every one
of them.  A C<Bool.Value> has 1 system-defined possrep whose name is the
empty string and which has zero attributes.  The cardinality of this type
is 1, and its only value is its default and minimum and maximum value.

=head2 sys.std.Core.Type.Int

An C<Int> is a single exact integral number
of any magnitude.  The C<Int> type explicitly composes the C<Numeric> mixin
type.  Its default value is zero; its minimum and maximum
values are conceptually infinities and practically impossible.  C<Int> is
one of just two scalar root types (the other is C<String>) that do I<not>
have any possreps.  C<Int> is also
the only atomic type in the Muldis D type system.  The cardinality of
this type is infinity; to define a most-generalized finite C<Int> subtype,
you must specify the 2 integer end-points of the inclusive range that all
its values are in.  The C<Int> type explicitly composes the C<Ordinal>
mixin type, and by extension also implicitly composes the C<Ordered> mixin
type.  The C<Int> type has a default ordering algorithm; for 2
distinct C<Int> values, the value closer to negative infinity is ordered
before the value closer to positive infinity.

=head2 sys.std.Core.Type.NNInt

C<NNInt> (non-negative integer) is a
proper subtype of C<Int> where all member values are greater than or equal
to zero.  Its minimum value is zero.

=head2 sys.std.Core.Type.PInt

C<PInt> (positive integer) is a proper
subtype of C<NNInt> where all member values are greater than zero.  Its
default and minimum value is 1.

=head2 sys.std.Core.Type.PInt2_N

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.Core.Type.Rat

A C<Rat> (scalar) is a single exact
rational number of any magnitude and precision.  The C<Rat> type explicitly
composes the C<Numeric> mixin type.  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 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 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 explicitly composes the C<Ordered> mixin type.
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.Core.Type.NNRat

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.Core.Type.PRat

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.Core.Type.Blob

A C<Blob> is an undifferentiated string of
bits.  The C<Blob> type explicitly composes the C<Stringy> mixin
type.  A C<Blob> has 1 system-defined possrep named C<bits> which consists
of 1 C<BString>-typed attribute whose name is the empty string; each
element of C<bits> is either C<0> to represent a low bit or C<1> to
represent a high bit.  The C<Blob> type explicitly composes the C<Ordered>
mixin type.  A C<Blob> is a simple wrapper for a C<BString> and
all of its other details such as default and minimum and maximum values and
cardinality and default ordering algorithm all correspond directly.  But
C<Blob> is explicitly disjoint from C<BString> due to having a different
intended interpretation.

=head2 sys.std.Core.Type.OctetBlob

C<OctetBlob> is a proper subtype of
C<Blob> where all member values have a length in bits that is an even
multiple of 8 (or is zero).  An C<OctetBlob> adds 1 system-defined possrep
named C<octets> which consists of 1 C<OString>-typed attribute whose name
is the empty string.  The C<octets> and C<bits> possreps correspond as you
might expect, such that each element of the sole attribute of C<octets>
maps to 8 consecutive elements of the sole attribute of C<bits>; with each
8 bits corresponding to an octet, the lowest-element-indexed bit
corresponds to the highest bit of the octet when the latter is encoded as a
standard two's complement binary unsigned integer, and the
highest-element-indeed bit corresponds to the lowest bit of the octet.  The
reason the C<OctetBlob> type is system-defined as distinct from C<Blob> is
for convenience of users since it is likely the vast majority of C<Blob>
values consist of whole octets and users would want to work with them in
those terms.

=head2 sys.std.Core.Type.Text

A C<Text> is a string of Unicode abstract
characters which is formatted as a sequence of Unicode abstract codepoints
in canonical decomposed normal form (NFD).  The C<Text> type explicitly
composes the C<Stringy> mixin type.  Two C<Text> will generally
match at the grapheme abstraction level.  Of course, a Muldis D
implementation doesn't actually have to store character data in NFD; but
default matching semantics need to be as if it did.  A C<Text> has 1
system-defined possrep named C<nfd_codes> which consists of 1
C<UCPString>-typed attribute whose name is the empty string; each element
of C<nfd_codes> represents a Unicode standard version 5.2.0 character
abstract codepoint number.  The C<Text> type explicitly composes the
C<Ordered> mixin type.  A C<Text> is a simple wrapper for a
C<UCPString> and all of its other details such as default and minimum and
maximum values and cardinality and default ordering algorithm (sorting is
numeric by abstract codepoint number) all correspond directly.  But C<Text>
is explicitly disjoint from C<UCPString> due to having a different intended
interpretation.  In regards to ordering, possibly the standard Unicode
Collation Algorithm (UCA) also works this way, assuming it is totally
ordered, but that's unsure.  I<TODO: Support customization parameters for
default text sorting.>

=head1 GENERIC NONSCALAR DATA TYPES

These core nonscalar data types permit transparent/user-visible
compositions of multiple values into other conceptual values.  For all
nonscalar types, their cardinality is mainly or wholly dependent on the
data types they are composed of.

=head2 sys.std.Core.Type.Tuple

The C<Tuple> type is the maximal type of
all Muldis D tuple (nonscalar) types, and contains every
tuple value that could possibly exist.  A C<Tuple> is an unordered
heterogeneous collection of 0..N named attributes (the count of attributes
being its I<degree>), where all attribute names are mutually distinct, and
each attribute may be of distinct types; the mapping of a tuple's
attribute names and their declared data types is called the tuple's
I<heading>.  Its default value is the sole tuple value
that has zero attributes.  The cardinality of a I<complete> C<Tuple>
type (if it has no type constraints other than those of its constituent
attribute types) is equal to the product of the N-adic multiplication where
there is an input to that multiplication for each attribute of the
tuple and the value of the input is the cardinality of the declared
type of the attribute; for a C<Tuple> subtype to be finite, all of its
attribute types must be.  Considering the low-level type system, C<Tuple>
is just a proper subtype of C<Structure> consisting of
every C<Structure> value whose first element is the C<Int> value C<2>.

=head2 sys.std.Core.Type.DHTuple

C<DHTuple> is a proper subtype of
C<Tuple> where every one of its attributes is restricted to be of just
certain categories of data types, rather than allowing any data types at
all; related to this restriction, any dh-tuple value is allowed to be
stored in a global/persisting relational database but any other tuple value
may only be used for transient data.  The C<DHTuple> type is the maximal
type of all Muldis D dh-tuple (dh-nonscalar) types, and contains every
dh-tuple value that could possibly exist.  Its default value is the same as
that of C<Tuple> and matters of its cardinality are determined likewise.

The only member value of C<DHTuple> that has exactly zero attributes is
also known by the special name C<Tuple:D0> aka C<D0>, which serves as the
default value of the 3 types C<[|DH]Tuple> and C<Database>.

=head2 sys.std.Core.Type.Database

C<Database> is a proper subtype of
C<DHTuple> where all of its attributes are each of dh-relation types or of
database types (the leaves of this recursion are all dh-relation types); it
is otherwise the same.  The 2 system-defined user-data variables named
C<[fed|nlx].data> are all of "just" the C<Database> type, or are of
its proper subtypes.

=head2 sys.std.Core.Type.Set.T

C<Set.T> is a proper subtype of
C<Tuple>, and it exists in order for the relation type
C<Set> (and C<Maybe> and C<Just>) to be defined partly in terms of it.  A
C<Set.T> has 1 attribute, C<value> (a C<Universal>).  Its default value a
C<value> of C<Bool:False>.

=head2 sys.std.Core.Type.DHSet.T

C<DHSet.T> is the intersection type of
C<Set.T> and C<DHTuple>, and it exists in order for the dh-relation type
C<DHSet> (and C<DHMaybe>, C<DHJust>) to be defined partly in terms of it.

=head2 sys.std.Core.Type.Array.T

C<Array.T> is a proper subtype of
C<Tuple>, and it exists in order for the relation type
C<Array> to be defined partly in terms of it.  An C<Array.T>
has 2 attributes, C<index> (a C<NNInt>) and C<value> (a C<Universal>).  Its
default value has an C<index> of zero and a C<value> of C<Bool:False>.

=head2 sys.std.Core.Type.DHArray.T

C<DHArray.T> is the intersection type of
C<Array.T> and C<DHTuple>, and it exists in order for the dh-relation type
C<DHArray> to be defined partly in terms of it.

=head2 sys.std.Core.Type.Bag.T

C<Bag.T> is a proper subtype of
C<Tuple>, and it exists in order for the relation type
C<Bag> to be defined partly in terms of it.  A C<Bag.T>
has 2 attributes, C<value> (a C<Universal>) and C<count> (a C<PInt>).  Its
default value has a C<value> of C<Bool:False> and a C<count> of 1.

=head2 sys.std.Core.Type.DHBag.T

C<DHBag.T> is the intersection type of
C<Bag.T> and C<DHTuple>, and it exists in order for the dh-relation type
C<DHBag> to be defined partly in terms of it.

=head2 sys.std.Core.Type.SPInterval

An C<SPInterval> (single-piece interval) is a C<Tuple>.  It typically
defines a single I<bounded interval>/I<finite interval> in terms of 2
I<endpoint> values plus an indicator of whether either, both, or none of
the endpoint values are included in the interval.  It can also define an
I<unbounded interval>/I<infinite interval>, which is accomplished by
using an infinity for either or both endpoint values.

An C<SPInterval> has these 4 attributes:

=over

=item C<min|max> - C<Universal>

These are the interval endpoint values; C<min> defines the
I<left|start|from> endpoint and C<max> defines the I<right|end|to>
endpoint.  The endpoint values conceptually must be of the same,
totally-ordered type (typically one of C<Int>, C<Rat>, C<Text>,
C<TAIInstant>, etc), although strictly speaking they may be of any types at
all; in the latter case, to actually make practical use of such intervals,
an C<order-determination> function must explicitly be employed.

=item C<excludes_[min|max]> - C<Bool>

If C<excludes_min> or C<excludes_max> are C<Bool:True>, then C<min> or
C<max> I<is not> considered to be included within the interval,
respectively; otherwise, it I<is> considered to be included within the
interval.  If both endpoints are within the interval (the use case which
Muldis D optimizes its syntax for), the interval is I<closed>; otherwise if
both endpoints are not in the interval, the interval is I<open>.

=back

The C<SPInterval> type supports empty intervals (which include no values at
all) at least as a matter of simplicity in that it doesn't place any
restrictions on the combination of attribute values an C<SPInterval> value
may have, such as that C<max> can't be before C<min>.  This liberal design
is also necessary to support the general case where the relative order of
the C<min> and C<max> values is situation-dependent on what
C<order-determination> function is used with the interval; that function
also determines what type's concept of order is being applied, and so it
also determines whether or not a given interval is considered empty or not.
With respect to each compatible C<order-determination> function, an
C<SPInterval> is considered empty iff at least one of the following is
true:  1. Its C<min> is greater than its C<max>.  2. Its C<min> is equal to
its C<max> I<and> at least one of C<excludes_min> or C<excludes_max> is
true.  3. Both C<excludes_min> and C<excludes_max> are true I<and> C<min>
and C<max> are consecutive values.  And so, there are many distinct
C<SPInterval> values that are conceptually empty intervals, and the
C<is_identical> function should not be used to test an C<SPInterval> for
being empty or not.

The C<SPInterval> type supports I<unbounded>/I<infinite> or I<half-bounded>
intervals that are orthogonal to data type.  This feature is implemented
using the 2 special singleton types C<-Inf> and C<Inf>.  Iff C<min> is
C<-Inf> then the interval is left-unbounded; iff C<max> is C<Inf> then the
interval is right-unbounded.  An interval that is unbounded on both ends is
the maximal interval, in that all Muldis D values are members of it, at
least in the general context lacking any C<order-determination> function.

The default value of C<SPInterval> represents an empty interval where its
C<min> and C<max> attributes are C<Inf> and C<-Inf>, respectively, and its
other 2 attributes are C<Bool:False>.

See also the C<sys.std.Core.Type.MPInterval> type, which is the
canonical means that Muldis D provides of representing the result of
set-unioning 2 C<SPInterval> where the latter do not touch or overlap,
and provides the single I<canonical> empty interval value.

=head2 sys.std.Core.Type.DHSPInterval

C<DHSPInterval> is a proper subtype of
C<SPInterval> where every one of its values is also a C<DHTuple>.  In
general practice, all C<SPInterval> values are C<DHSPInterval> values,
because their endpoints would all be C<DHScalar> values.  The default value
of C<DHSPInterval> is the same as that of C<SPInterval>.

=head2 sys.std.Core.Type.Relation

The C<Relation> type is the maximal type
of all Muldis D relation (nonscalar) types, and contains every
relation value that could possibly exist.  A C<Relation> is
analogous to a set of 0..N tuples where all tuples have the
same heading (the degrees match and all attribute names, and typically
corresponding declared data types, match), but that a C<Relation> data
type still has its own corresponding heading (attribute names and declared
data types) even when it consists of zero tuples.  Its default value
is the sole relation value that has zero tuples and zero
attributes.  The cardinality of a I<complete> C<Relation> type (if it has
no type constraints other than those of its constituent attribute types) is
equal to 2 raised to the power of the cardinality of the I<complete>
C<Tuple> type with the same heading.  A relation data type can also
have (unique) keys each defined over a subset of its attributes, which
constrain its set of values relative to there being no explicit keys, but
having the keys won't turn an infinite relation type into a finite one.
Considering the low-level type system, C<Relation> is just a proper subtype
of C<Structure> consisting of every C<Structure> value whose first element
is the C<Int> value C<3>.

=head2 sys.std.Core.Type.DHRelation

C<DHRelation> is a proper subtype of
C<Relation> where every one of its attributes is restricted to be of just
certain categories of data types, rather than allowing any data types at
all; related to this restriction, any dh-relation value is allowed to be
stored in a global/persisting relational database but any other relation
value may only be used for transient data.  The main difference from its
supertype is that a dh-relation's dh-tuples' headings all have matching
declared data types for corresponding attributes, while with relations they
don't have to.  The C<DHRelation> type is the maximal type of all Muldis D
dh-relation (dh-nonscalar) types, and contains every dh-relation value that
could possibly exist.  Its default value is the same as that of C<Relation>
and matters of its cardinality are determined likewise.

The only member value of C<DHRelation> that has exactly zero attributes and
exactly zero tuples is also known by the special name C<Relation:D0C0> aka
C<D0C0>, which serves as the default value of the 2 types C<[|DH]Relation>.
The only member value of C<DHRelation> that has exactly zero attributes and
exactly one tuple is also known by the special name C<Relation:D0C1> aka
C<D0C1>.  Note that I<The Third Manifesto> also refers to these 2 values by
the special shorthand names I<TABLE_DUM> and I<TABLE_DEE>, respectively.

=head2 sys.std.Core.Type.Set

C<Set> is a proper subtype of
C<Relation> that has 1 attribute, and its name is C<value>; it can be of
any declared type.  A C<Set> subtype is normally used by any
system-defined N-adic operators where the order of their argument elements
or result is not significant, and that duplicate values are not
significant.  Its default value has zero tuples.  Note that, for any
given C<Set> subtype, C<Foo>, where its C<value> attribute has a declared
type of C<Bar>, the type C<Foo> can be considered the I<power set> of the
type C<Bar>.

=head2 sys.std.Core.Type.DHSet

C<DHSet> is the intersection type of
C<Set> and C<DHRelation>.  The cardinality of this type is infinite.

=head2 sys.std.Core.Type.Maybe

C<Maybe> is a proper subtype of C<Set>
where all member values may have at most one element; that is, it is a
unary C<Relation> with a nullary key.  Operators that work specifically
with C<Maybe> subtypes can provide a syntactic shorthand for working with
sparse data; so Muldis D has something which is conceptually close to SQL's
nullable types without actually having 3-valued logic; it would probably be
convenient for code that round-trips SQL by way of Muldis D to use the
C<Maybe> type.  Its default value has zero tuples.

=head2 sys.std.Core.Type.DHMaybe

C<DHMaybe> is the intersection type of
C<Maybe> and C<DHSet>.  The cardinality of this type is infinite.

The only member value of C<DHMaybe> that has exactly zero elements is also
known by the special name C<Maybe:Nothing>, aka C<Nothing>,
aka I<empty set>, aka C<∅>, which serves as
the default value of the 4 types C<[|DH]Maybe> and C<[|DH]Set>.  The single
C<Nothing> value, which is a relation with zero tuples and a single
attribute named C<value>, is Muldis D's answer to the SQL NULL and is
intended to be used for the same purposes; that is, a special marker for
missing or inapplicable information, that does not typically equal any
normal/scalar value; however, in Muldis D, C<Nothing> I<is a value>, and it
I<is> equal to itself.  To be more specific, the SQL NULL is very limited
in what it actually can do, and can not be used to say anything other than
"this isn't a normal value", similar to what Perl's "undef" says; if you
want to actually indicate a reason why we don't have a normal value when
more than one reason could possibly apply in the context, then using simply
C<Nothing> or SQL's NULL can't do it, and instead you'll have to use other
normal values such as status flags to keep the appropriate metadata.

=head2 sys.std.Core.Type.Just

C<Just> is a proper subtype of
C<Maybe> where all member values have exactly 1 element.  Its default
value's only tuple's only attribute has the value C<Bool:False>.  The
C<Just> type consists of all of C<Maybe>'s values except C<Nothing>.

=head2 sys.std.Core.Type.DHJust

C<DHJust> is the intersection type of
C<Just> and C<DHMaybe>.  Subtypes of C<DHJust> are also used to
implement data-carrying database objects that are conceptually scalars
rather than relations; for example, the current state of a sequence
generator might typically be one.  The cardinality of this type is
infinite.

=head2 sys.std.Core.Type.Array

C<Array> is a proper subtype of
C<Relation> that has 2 attributes, and their names are C<index> and
C<value>, where C<index> is a unary primary key and its declared type is a
C<NNInt> subtype (C<value> can be non-unique and of any declared type).  An
C<Array> is considered dense, and all C<index> values in one are numbered
consecutively from 0 to 1 less than the count of tuples, like array
indices in typical programming languages.  An C<Array> subtype is normally
used by any system-defined N-adic operators where the order of their
argument elements or result is significant (and duplicate values are
significant); specifically, C<index> defines an explicit ordering for
C<value>.  Its default value has zero tuples.  The C<Array> type explicitly
composes the C<Stringy> mixin type.

=head2 sys.std.Core.Type.DHArray

C<DHArray> is the intersection type of
C<Array> and C<DHRelation>.  The cardinality of this type is infinite.

=head2 sys.std.Core.Type.Bag

C<Bag> (or I<multiset>) is a
proper subtype of C<Relation> that has 2 attributes, and their names are
C<value> and C<count>, where C<value> is a unary primary key (that can have
any declared type) and C<count> is a C<PInt> subtype.  A C<Bag> subtype is
normally used by any system-defined N-adic operators where the order of
their argument elements or result is not significant, but that duplicate
values are significant; specifically, C<count> defines an explicit count of
occurrences for C<value>, also known as that value's I<multiplicity>.  Its
default value has zero tuples.

=head2 sys.std.Core.Type.DHBag

C<DHBag> is the intersection type of
C<Bag> and C<DHRelation>.  The cardinality of this type is infinite.

=head2 sys.std.Core.Type.MPInterval

C<MPInterval> (multi-piece interval) is a proper subtype of
C<Relation> that is defined directly partly in terms of the tuple type
C<SPInterval>, thereby sharing its I<heading>, but defines no further
constraints of its own.  It defines a single I<multi-piece interval>, which
is conceptually either a set of 0..N intervals or a single larger interval
that had 0..N sub-intervals sliced out.  An C<MPInterval> is the
canonical means that Muldis D provides of representing the result of
set-unioning 2 C<SPInterval> where the latter do not touch or overlap.
Moreover, an C<MPInterval> also empowers Muldis D to have a single
I<canonical> empty interval value, which is the only C<MPInterval> with
zero tuples; this value is also the default value of C<MPInterval>.  The
cardinality of this type is infinite.

=head2 sys.std.Core.Type.DHMPInterval

C<DHMPInterval> is the intersection type of C<MPInterval> and
C<DHRelation>.  The cardinality of this type is infinite.

=head1 GENERIC EXTERNAL DATA TYPES

=head2 sys.std.Core.Type.External

An C<External> is a reference within the
Muldis D virtual machine to a value managed not by the Muldis D
implementation but rather by a peer or host language in the wider program
that includes the VM.  All C<External> values are treated as black boxes by
Muldis D itself.  The cardinality of this type is
infinity.  The default value of this type is implementation-defined.
Considering the low-level type system, C<External> is just a proper subtype
of C<Structure> consisting of every C<Structure> value whose first element
is the C<Int> value C<5>.

=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<darren@DarrenDuncan.net>)

=head1 LICENSE AND COPYRIGHT

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

Muldis D is Copyright © 2002-2010, Muldis Data Systems, Inc.

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
