=pod

=encoding utf8

=head1 NAME

Muldis::D::Ext::Counted -
Muldis D extension for count-sensitive relational operators

=head1 VERSION

This document is Muldis::D::Ext::Counted version 0.73.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<Counted> document describes the system-defined I<Muldis D
Counted Extension>, which consists of relational operators that are
sensitive to special q/relation attributes that store count meta-data as if
the q/relation conceptually was a bag of q/tuples rather than a set of
q/tuples.  This extension doesn't introduce any new data types, and its
operators all range over ordinary q/relations.  The operators do not assume
that their argument q/relations have attributes of any particular names,
including that count-containing attributes have any particular names;
rather, each operator is told what attributes to treat as special by taking
extra explicit parameters specifying their names.  The operators are all
short-hands for generic relational operators either in the language core or
in other language extensions.  The I<Muldis D Counted Extension> differs
from the I<Muldis D QBag Extension> in that the latter deals just with
C<QBag> binary q/relations with specific attribute names while the former
works with any q/relations at all.

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 SYSTEM-DEFINED COUNT-CONCERNING RELATIONAL FUNCTIONS

Every one of these functions that takes a C<count_attr_name> argument is
expecting that each of any other applicable arguments will have an
attribute whose name matches that given in C<count_attr_name> and that the
type of this attribute is C<PInt>; said functions will fail if these
conditions aren't met.  For brevity, this documentation will hereafter
refer to the attribute named in C<count_attr_name> as C<tcount>, and
moreafter it will refer to the collection of all attributes except
C<tcount> as C<tattrs>.

Each C<assuming> parameter is optional and defaults to the zero-attribute
tuple if no explicit argument is given to it.

=head2 sys.std.Counted.add_count_attr

C<< function sys.std.Counted.add_count_attr (QRelation <-- QRelation
$topic, Name $count_attr_name) >>

This function is a shorthand for C<sys.std.Core.QRelation.static_extension>
that adds to C<topic> a single C<tcount> attribute whose value for all
tuples is 1.  This function conceptually converts a set of tuples into a
bag of tuples, of multiplicity 1 per tuple.

=head2 sys.std.Counted.remove_count_attr

C<< function sys.std.Counted.remove_count_attr (QRelation <-- QRelation
$topic, Name $count_attr_name) >>

This function is a shorthand for C<sys.std.Core.QRelation.cmpl_projection>
that removes from C<topic> the single C<tcount> attribute.  This function
conceptually converts a bag of tuples into a set of tuples, elimimating all
duplicates.

=head2 sys.std.Counted.counted_cardinality

C<< function sys.std.Counted.counted_cardinality (NNInt <--
QRelation $topic, Name $count_attr_name) >>

This function is like C<sys.std.Core.QRelation.cardinality> but that it
accounts for the greater-than-one conceptual multiplicity of q/tuples in
its C<topic> argument; it results in the sum of the C<tcount> attribute of
its C<topic> argument.

=head2 sys.std.Counted.counted_is_member

C<< function sys.std.Counted.counted_is_member (Bool <-- QRelation $r,
QTuple $t, Name $count_attr_name) >>

This function is the same as C<sys.std.Core.QRelation.is_member> except
that C<t> must have one fewer attribute than C<r> does, specifically
C<tcount> (and otherwise they must have the same headings).

=head2 sys.std.Counted.counted_is_not_member

C<< function sys.std.Counted.counted_is_not_member (Bool <-- QRelation $r,
QTuple $t, Name $count_attr_name) >>

This function is exactly the same as C<sys.std.Counted.counted_is_member>
except that it results in the opposite boolean value when given the same
arguments.

=head2 sys.std.Counted.counted_insertion

C<< function sys.std.Counted.counted_insertion (QRelation <-- QRelation $r,
QTuple $t, Name $count_attr_name) >>

This function is the same as C<sys.std.Core.QRelation.insertion> as per
C<counted_is_member> but that its result differs depending on whether C<t>
already exists in C<r>; if it does, then no new q/tuple is added, but the
C<tcount> attribute for the matching q/tuple is incremented by 1; if it
does not, then a new q/tuple is added where its C<tattrs> is C<t> and its
C<tcount> is 1.  Actually this function differs in another way, such that
it is semantically the single-q/tuple case of
C<sys.std.Counted.counted_union_sum>, and is not the single-q/tuple case of
C<sys.std.Counted.counted_union> (which is the direct analogy to set
union).

=head2 sys.std.Counted.counted_deletion

C<< function sys.std.Counted.counted_deletion (QRelation <-- QRelation $r,
QTuple $t, Name $count_attr_name) >>

This function is the same as C<sys.std.Core.QRelation.deletion> as per
C<counted_is_member> but that its result differs depending on what the
C<tcount> for any q/tuple matching C<t> that already exists in C<r> is; if
the C<tcount> is greater than 1, then it is decremented by 1; if it is
equal to 1, then the q/tuple whose C<tattrs> is C<t> is deleted.

=head2 sys.std.Counted.counted_projection

C<< function sys.std.Counted.counted_projection (QRelation <--
QRelation $topic, set_of.Name $attr_names, Name $count_attr_name) >>

This function is the same as C<sys.std.Core.QRelation.projection> except
that the C<counted_cardinality> of the result is guaranteed to be the same
as that of C<topic> rather than possibly less.  The C<topic> argument must
have a C<tcount> attribute and C<attr_names> must not specify that
attribute; the result has the just attributes of C<topic> named by
C<attr_names> plus the C<tcount> attribute.

=head2 sys.std.Counted.counted_cmpl_projection

C<< function sys.std.Counted.counted_cmpl_projection (QRelation <--
QRelation $topic, set_of.Name $attr_names, Name $count_attr_name) >>

This function is the same as C<sys.std.Core.QRelation.cmpl_projection>
except that the C<counted_cardinality> of the result is guaranteed to be
the same as that of C<topic> rather than possibly less.  The C<topic>
argument must have a C<tcount> attribute and C<attr_names> must not specify
that attribute; the result has the just the attributes of C<topic> not
named by C<attr_names> including the C<tcount> attribute.

=head2 sys.std.Counted.counted_reduction

C<< function sys.std.Counted.counted_reduction (QTuple <--
QRelation $topic, FuncRef $func, QTuple $assuming?, QTuple $identity,
Name $count_attr_name) >>

This function is the same as C<sys.std.QRelation.reduction> except that
C<func> is invoked extra times, where both its C<v1> and C<v2> arguments
might be different instances of the same C<tattrs> tuple having >= 2
multiplicity.  This function's C<topic> argument has a C<tcount> attribute
while its C<identity> argument does not, and both the result q/tuple of
C<func> and its C<v1> and C<v2> arguments don't have the C<tcount>
attribute either.

=head2 sys.std.Counted.counted_maybe_reduction

C<< function sys.std.Counted.counted_maybe_reduction
(quasi_maybe_of.QTuple <-- QRelation $topic, FuncRef $func,
QTuple $assuming?, Name $count_attr_name) >>

This function is to C<sys.std.Core.QRelation.maybe_reduction> as
C<sys.std.Counted.counted_reduction> is to C<sys.std.QRelation.reduction>.

=head2 sys.std.Counted.counted_map

C<< function sys.std.Counted.counted_map (QRelation <-- QRelation $topic,
set_of.Name $result_attr_names, FuncRef $func, QTuple $assuming?,
Name $count_attr_name) >>

This function is the same as C<sys.std.QRelation.map> except that the
C<counted_cardinality> of the result is guaranteed to be the same as that
of C<topic> rather than possibly less.  The C<topic> argument must have a
C<tcount> attribute and C<result_attr_names> must not specify that
attribute; the result has the attributes named in C<result_attr_names> plus
the C<tcount> attribute.  Both the result q/tuple of C<func> and its
C<topic> argument don't have the C<tcount> attribute.

=head2 sys.std.Counted.counted_is_subset

C<< function sys.std.Counted.counted_is_subset (Bool <--
QRelation $look_in, QRelation $look_for, Name $count_attr_name) >>

This function is like C<sys.std.Core.QRelation.is_subset> but that it
accounts for the greater-than-one multiplicity of C<tattrs> in its
C<look_for> and C<look_in> arguments, both of which have a C<tcount>
attribute; this function returns C<Bool:true> iff the multiplicity of each
C<look_for> value is less than or equal to the multiplicity of its
counterpart C<look_in> value.

=head2 sys.std.Counted.counted_is_not_subset

C<< function sys.std.Counted.counted_is_not_subset (Bool <--
QRelation $look_in, QRelation $look_for, Name $count_attr_name) >>

This function is like C<sys.std.Core.QRelation.is_not_subset> as per
C<counted_is_subset>.

=head2 sys.std.Counted.counted_is_proper_subset

C<< function sys.std.Counted.counted_is_proper_subset (Bool <--
QRelation $look_in, QRelation $look_for, Name $count_attr_name) >>

This function is like C<sys.std.QRelation.is_proper_subset> as per
C<counted_is_subset>.  I<TODO: What is its definition?>

=head2 sys.std.Counted.counted_is_not_proper_subset

C<< function sys.std.Counted.counted_is_not_proper_subset (Bool <--
QRelation $look_in, QRelation $look_for, Name $count_attr_name) >>

This function is like C<sys.std.QRelation.is_not_proper_subset> as per
C<counted_is_subset>.  I<TODO: What is its definition?>

=head2 sys.std.Counted.counted_union

C<< function sys.std.Counted.counted_union (QRelation <--
quasi_set_of.QRelation $topic, Name $count_attr_name) >>

This function is like C<sys.std.Core.QRelation.union> but that it just
looks at the C<tattrs> attributes of its argument elements when determining
what element q/tuples correspond; then for each q/tuple in the result, its
C<tcount> attribute value is the maximum of the C<tcount> attribute values
of its corresponding input element q/tuples.

=head2 sys.std.Counted.counted_union_sum

C<< function sys.std.Counted.counted_union_sum (QRelation <--
quasi_bag_of.QRelation $topic, Name $count_attr_name) >>

This function is like C<sys.std.Counted.counted_union> but that for each
pair of argument elements being unioned, the output C<tcount> value is the
sum of the input C<tcount> values rather than being the maximum of the
inputs.  This function is the nearest Muldis D analogy to the SQL "UNION
ALL" operation, versus C<sys.std.Core.QRelation.union> which is the nearest
analogy to "UNION DISTINCT".

=head2 sys.std.Counted.counted_intersection

C<< function sys.std.Counted.counted_intersection (QRelation <--
quasi_set_of.QRelation $topic, Name $count_attr_name) >>

This function is like C<sys.std.Core.QRelation.intersection> as
C<counted_union> is like C<sys.std.Core.QRelation.union>; the minimum of
C<tcount> attribute values is used rather than the maximum.

=head2 sys.std.Counted.counted_difference

C<< function sys.std.Counted.counted_difference (QRelation <--
QRelation $source, QRelation $filter, Name $count_attr_name) >>

This function is like C<sys.std.Core.QRelation.difference> as
C<counted_union> is like C<sys.std.Core.QRelation.union>; for corresponding
input q/tuples, the result only has a q/tuple with the same C<tattrs> if
the C<tcount> of the C<source> q/tuple is greater than the C<tcount> of the
C<filter> q/tuple, and the C<tcount> of the result q/tuple is the
difference of those two.

=head2 sys.std.Counted.counted_substitution

C<< function sys.std.Counted.counted_substitution (QRelation <--
QRelation $topic, set_of.Name $attr_names, FuncRef $func,
QTuple $assuming?, Name $count_attr_name) >>

This function is the same as C<sys.std.QRelation.substitution> except that
the C<counted_cardinality> of the result is guaranteed to be the same as
that of C<topic> rather than possibly less.  The C<topic> argument must
have a C<tcount> attribute and C<attr_names> must not specify that
attribute.

=head2 sys.std.Counted.counted_static_substitution

C<< function sys.std.Counted.counted_static_substitution (QRelation <--
QRelation $topic, QTuple $attrs, Name $count_attr_name) >>

This function is the same as C<sys.std.QRelation.static_substitution>
except that the C<counted_cardinality> of the result is guaranteed to be
the same as that of C<topic> rather than possibly less.  The C<topic>
argument must have a C<tcount> attribute and C<attrs> must not have that
attribute.

=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, 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
