NAME

Language::MuldisD::Ext::Nonscalar - Muldis D extension adding more generic relational operators

VERSION

This document is Language::MuldisD::Ext::Nonscalar version 0.20.0.

PREFACE

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

DESCRIPTION

Muldis D has a mandatory core set of system-defined (eternally available) entities, which is referred to as the Muldis D core or the 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 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 Nonscalar document describes the system-defined Muldis D Nonscalar Extension, which consists of many generic relational operators (for generic tuples or relations), adding to the minimum few defined in the language core.

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 Language::MuldisD::Core.

This documentation is pending.

SYSTEM-DEFINED GENERIC TUPLE-CONCERNING FUNCTIONS

These functions are applicable to mainly tuple types, but are generic in that they typically work with any tuple types.

function sys.Nonscalar.Tuple.degree result UInt params { topic(Tuple) }

This function results in the degree of its argument (that is, the count of attributes it has).

function sys.Nonscalar.Tuple.attr_from_Tuple result ScaTupRel params { topic(Tuple) }

This function results in the scalar or nonscalar value of the sole attribute of its argument. This function will fail if its argument is not of degree 1.

function sys.Nonscalar.Tuple.Tuple_from_attr result Tuple params { name(Cat.Name), value(ScaTupRel) }

This function results in the Tuple value which has just one attribute whose name is given by name and whose value is given by value; the attribute's declared type is the same as that of value.

function sys.Nonscalar.Tuple.substitution_in_default result Tuple params { of(Cat.NameChain), subst(Tuple) }

This function results in the tuple value that is the default value of the tuple data type whose name is given in the of argument, but that zero or more of its attribute values have been substituted by values given in the subst argument. This function is a short-hand for sys.Core.Tuple.multi_update on the result of sys.Core.Universal.default. This function will fail if either default would fail for the same of argument, or if its result isn't a tuple type, or if the heading of subst isn't a subset of the heading of the default. The purpose of this function is to support greater brevity in Muldis D coding such that users can define just part of a desired tuple value and have the remainder filled in from defaults for them; particularly useful with tuples that conceptually have some optional attributes.

SYSTEM-DEFINED GENERIC SINGLE INPUT RELATION FUNCTIONS

These functions are applicable to mainly relation types, but are generic in that they typically work with any relation types.

function sys.Nonscalar.Relation.degree result UInt params { topic(Relation) }

This function results in the degree of its argument (that is, the count of attributes it has).

function sys.Nonscalar.Relation.is_empty result Bool params { topic(Relation) }

This function results in Bool:true iff its argument has zero tuples, and Bool:false otherwise. Note that if you are using a Maybe to represent a sparse data item, analagously to a SQL nullable context, then testing the Maybe with is_empty is analagous to testing a SQL nullable with is null.

function sys.Nonscalar.Relation.is_not_empty result Bool params { topic(Relation) }

This function is exactly the same as sys.Nonscalar.Relation.is_empty except that it results in the opposite boolean value when given the same argument. And following the analogy with is_empty, is_not_empty is analagous to SQL's is not null.

function sys.Nonscalar.Relation.empty result Relation params { topic(Relation) }

This function results in the empty relation of the same heading of its argument; it has zero tuples.

function sys.Nonscalar.Relation.universal result Relation params { topic(Relation) }

This function results in the universal relation of the same heading of its argument; that is, the relation having all the tuples that could ever exist in a relation with that heading. This function will fail if said universal relation is impossible or impractically large to represent, such as when any attributes are of infinite types.

function sys.Nonscalar.Relation.power_set result SetOfRelation params { topic(Relation) }

This function results in the power set of its argument. The result is a Set whose sole attribute is Relation-typed (its type is nominally the same as that of the argument) and which has a tuple for every distinct subset of tuples in the argument. The cardinality of the result is equal to 2 raised to the power of the cardinality of the argument (which may easily lead to a very large result, so use this function with care). Note that the N-ary relational union of the power set of some relation is that relation; the N-ary intersection of any power set is the empty relation.

function sys.Nonscalar.Relation.negation result Relation params { topic(Relation) }

This function results in the relational negation/not of its argument. The result relation has the same heading as its argument, and its body contains all of the tuples that are in the universal relation of the same heading and that are not in the argument; that is, the result is the relational difference when the argument is subtracted from said universal relation. This function will fail on any argument that sys.Nonscalar.Relation.universal would fail on.

function sys.Nonscalar.Relation.transitive_closure result Relation params { topic(Relation) }

This function results in the transitive closure of its argument. The argument is a binary relation whose attributes are both of the same declared type, and the result is a relation having the same heading and a body which is a superset of the argument's tuples. Assuming that the argument represents all of the node pairs in a directed graph that have an arc between them, and so each argument tuple represents an arc, transitive_closure will determine all of the node pairs in that graph which have a path between them (a recursive operation), so each tuple of the result represents a path. The result is a superset since all arcs are also complete paths. The transitive_closure function is intended to support recursive queries, such as in connection with the "part explosion problem" (the problem of finding all components, at all levels, of some specified part).

function sys.Nonscalar.Relation.reduction result Tuple params { topic(Relation), func(Cat.NameChain), assuming(Tuple), identity(Tuple) }

This function is a generic reduction operator that recursively takes each pair of tuples in topic and applies an argument-specified tuple value-resulting function (which is both commutative and associative) to the pair until just one input tuple is left, which is the result. The function to apply is named in the func argument, and that function must have 3 arguments named v1, v2, assuming; the last parameter is curried with the same-named argument of reduction, and the first 2 parameters are the 2 input tuples for an invocation. If topic has zero tuples, then reduction results in the tuple given in identity. Note that identity may be changed to take a function name rather than a value, for consistency with func. This function will fail if the declared headings of identity and topic aren't compatible.

function sys.Nonscalar.Relation.maybe_reduction result MaybeOfTuple params { topic(Relation), func(Cat.NameChain), assuming(Tuple) }

This function is exactly the same as sys.Nonscalar.Relation.reduction except that it does not take an assuming argument, and it results in a Maybe of what is otherwise the result type, and that result has zero elements if the argument has zero elements.

function sys.Nonscalar.Relation.map result Relation params { topic(Relation), func(Cat.NameChain), assuming(Tuple) }

This function provides a convenient one-place generalization of per-tuple transformations that otherwise might require the chaining of up to a half-dozen other operators like restriction, extension, and rename. This function results in a relation each of whose tuples is the result of applying, to each of the tuples of its topic argument, the Tuple-resulting function named in its func argument when the latter function is curried by its assuming argument. There is no restriction on what attributes the result tuple of func may have (except that all tuples from func must have compatible headings); this tuple from func would completely replace the original tuple from topic. The result relation has a cardinality that is the same as that of topic, unless the result of func was redundant tuples, in which case the result has appropriately fewer tuples. As a trivial case, if func is defined to unconditionally result in the same tuple as its own topic argument, then this function results simply in topic; or, if func is defined to have a static result, then this function's result will have just 0..1 tuples.

SYSTEM-DEFINED GENERIC MULTIPLE INPUT RELATION FUNCTIONS

These functions are applicable to mainly relation types, but are generic in that they typically work with any relation types.

function sys.Nonscalar.Relation.is_proper_subset result Bool params { look_in(Relation), look_for(Relation) }

This function is exactly the same as sys.Core.Relation.is_subset except that it results in Bool:false if its 2 arguments are equal.

function sys.Nonscalar.Relation.is_not_proper_subset result Bool params { look_in(Relation), look_for(Relation) }

This function is exactly the same as sys.Nonscalar.Relation.is_proper_subset except that it results in the opposite boolean value when given the same arguments.

function sys.Nonscalar.Relation.exclusion result Relation params { topic(BagOfRelation) }

This function results in the relational exclusion/exclusive-or of the N element values of its argument; it is a reduction operator that recursively takes each pair of input values and relationally excludes (which is both commutative and associative) them together until just one is left, which is the result. The result relation has the same heading as all of its inputs, and its body contains every tuple that is in just an odd number of the input relations. If topic has zero values, then exclusion results in the empty relation with the same heading, which is the per-distinct-heading identity value for relational exclusion. Note that this operation is also legitimately known as symmetric difference.

function sys.Nonscalar.Relation.composition result Relation params { r1(Relation), r2(Relation) }

This function results in the relational composition of its 2 arguments. It is conceptually a short-hand for first doing an ordinary relational join between its 2 arguments, and then performing a relational projection on all of the attributes that only one of the arguments has; that is, the result has all of and just the attributes that were not involved in matching the tuples of the 2 arguments. This function will fail any time that join would fail on the same 2 input relations.

function sys.Nonscalar.Relation.join_with_group result Relation params { primary(Relation), secondary(Relation), group_attr(Cat.Name) }

This function is a short-hand for first taking a (natural inner) join of its primary and secondary arguments, and then taking a group on all of the attributes that only the secondary argument had, such that the attribute resulting from the group has the name group_attr. The result has 1 tuple for every tuple of primary where at least 1 matching tuple exists in secondary. This function will fail if group_attr is the same name as any source attribute that wasn't grouped. This function is a convenient tool for gathering both parent and child records from a database using a single query while avoiding duplication of the parent record values.

SYSTEM-DEFINED RELATIONAL SUBSTITUTION FUNCTIONS

These additional functions are specific to supporting substitutions.

function sys.Nonscalar.Relation.substitution result Relation params { topic(Relation), func(Cat.NameChain), assuming(Tuple) }

This function is similar to extension except that it substitutes values of existing relation attributes rather than adding new attributes. The result relation has the same heading as topic. The result tuple of the function named in func must have a heading that is a subset of the heading of topic; corresponding values resulting from the function named in func will replace the values of the tuples of topic. The result relation has a cardinality that is the same as that of topic, unless the result of any substitutions was redundant tuples, in which case the result has appropriately fewer tuples. As a trivial case, if func is defined to unconditionally result in either the degree-zero tuple or in the same tuple as its own topic argument, then this function results simply in topic; or, if func is defined to have a static result and it replaces all attributes, then this function's result will have just 0..1 tuples.

function sys.Nonscalar.Relation.static_substitution result Relation params { topic(Relation), attrs(Tuple) }

This function is a simpler-syntax alternative to sys.Nonscalar.Relation.substitution in the typical scenario where every tuple of a relation, given in the topic argument, is updated with identical values for the same attributes; the new attribute values are given in the attrs argument.

function sys.Nonscalar.Relation.substitution_in_restriction result Relation params { topic(Relation), restr_func(Cat.NameChain), restr_assuming(Tuple), subst_func(Cat.NameChain), subst_assuming(Tuple) }

This function is like substitution except that it only transforms a subset of the tuples of topic rather than all of them. It is a short-hand for first separating the tuples of topic into 2 groups where those passed by a relational restriction (defined by restr_func and restr_assuming) are then transformed (defined by subst_func and subst_assuming), then the result of the substitution is unioned with the un-transformed group. See also the substitution_in_semijoin function, which is a simpler-syntax alternative for substitution_in_restriction in its typical usage where restrictions are composed simply of anded or ored tests for attribute value equality.

function sys.Nonscalar.Relation.static_substitution_in_restriction result Relation params { topic(Relation), restr_func(Cat.NameChain), restr_assuming(Tuple), subst(Tuple) }

This function is to sys.Nonscalar.Relation.substitution_in_restriction what sys.Nonscalar.Relation.static_substitution is to sys.Nonscalar.Relation.substitution. See also the static_substitution_in_semijoin function.

function sys.Nonscalar.Relation.substitution_in_semijoin result Relation params { topic(Relation), restr(Relation), subst_func(Cat.NameChain), subst_assuming(Tuple) }

This function is like substitution_in_restriction except that the subset of the tuples of topic to be transformed is determined by those matched by a semijoin with restr rather than those that pass a generic relational restriction.

function sys.Nonscalar.Relation.static_substitution_in_semijoin result Relation params { topic(Relation), restr(Relation), subst(Tuple) }

This function is to sys.Nonscalar.Relation.substitution_in_semijoin what sys.Nonscalar.Relation.static_substitution is to sys.Nonscalar.Relation.substitution.

SYSTEM-DEFINED RELATIONAL OUTER-JOIN FUNCTIONS

These additional functions are specific to supporting outer-joins.

function sys.Nonscalar.Relation.outer_join_with_group result Relation params { primary(Relation), secondary(Relation), group_attr(Cat.Name) }

This function is the same as sys.Nonscalar.Relation.join_with_group except that it results in a half-outer natural join rather than an inner natural join; every tuple of primary has exactly 1 corresponding tuple in the result, but where there were no matching secondary tuples, the result attribute named by group_attr contains zero tuples rather than 1+.

function sys.Nonscalar.Relation.outer_join_with_maybes result Relation params { primary(Relation), secondary(Relation) }

This function results in a plain half-outer natural join of its primary and secondary arguments where all the result attributes that come from just secondary are Maybe-typed; for result tuples from matched source tuples, each secondary attribute value is a Single; for result tuples from non-matched primary tuples, each secondary attribute value is a Nothing. The outer_join_with_maybes function is Muldis D's answer to the SQL LEFT OUTER JOIN where SQL NULL is implicitly used in result rows that were a non-match.

function sys.Nonscalar.Relation.outer_join_with_defaults result Relation params { primary(Relation), secondary(Relation) }

This function is the same as sys.Nonscalar.Relation.outer_join_with_maybes but that secondary-sourced result attributes are not converted to Maybe; rather, for result tuples from non-matches, the declared types of the secondary attributes are considered, and the default values of those types are used to fill in missing result values.

function sys.Nonscalar.Relation.outer_join_with_product result Relation params { primary(Relation), secondary(Relation), filler(Tuple) }

This function is the same as sys.Nonscalar.Relation.outer_join_with_defaults but that missing values are provided explicitly from the filler argument, which is a tuple whose heading matches the projection of secondary's attributes that aren't in common with primary, and whose body is the literal values to use for those missing attribute values. This function gets its name in that conceptually the result tuples from non-matches are the result of performing a relational cross-product between the un-matched primary tuples and the single filler tuple. This function could alternately be named outer_join_with_static_extension.

function sys.Nonscalar.Relation.outer_join_with_extension result Relation params { primary(Relation), secondary(Relation), exten_func(Cat.NameChain), exten_assuming(Tuple) }

This function is the same as sys.Nonscalar.Relation.outer_join_with_product but that the result tuples from non-matches are the result of performing a relational extension on the un-matched primary tuples such that each said result tuple is determined by applying the function named in exten_func to each said primary tuple when the named function is curried using the exten_assuming argument.

SEE ALSO

Go to Language::MuldisD for the majority of distribution-internal references, and Language::MuldisD::SeeAlso for the majority of distribution-external references.

AUTHOR

Darren Duncan (perl@DarrenDuncan.net)

LICENSE AND COPYRIGHT

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

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

See the LICENSE AND COPYRIGHT of Language::MuldisD for details.

ACKNOWLEDGEMENTS

The ACKNOWLEDGEMENTS in Language::MuldisD apply to this file too.