Groups

This module contains the primitives to construct, derive, and perform statistical operations on BATs representing groups. The default scheme in MonetDB is to assume the head to represent the group identifier and the tail an element in the group.

Groups play an important role in data science, where they are used to construct cross-tables. Such cross tables over a single BAT are already supported by the histogram function. This module provides extensions to support identification of groups in a (multi-)dimensional space.

The module implementation has a long history. The first implementation provided several alternatives to produce/derive the grouping. A more complete (and complex) scheme was derived during its extensive use in the context of the Data Distilleries product. The current implementation is partly a cleanup of this code-base, but also enables provides better access to the intermediate structures produced in the process, i.e. the histogram and the sub-group mapping. They can be used for various optimization schemes at the MAL level.

The prime limitation of the current implementation is that an underlying database of oid->any BATs is assumed. This enables representation of each group using an oid, and the value representation of the group can be accordingly be retrieved easily. An optimized implementation in which we use positional integer id's (as embodied by Monet's void type) is also available.

Algorithms

There are several approaches to build a cross table. The one chosen here is aimed at incremental construction, such that re-use of intermediates becomes possible. Starting with the first dimension, a BAT is derived to represent the various groups, called a GRP BAT or cross-table BAT.

Cross Table (GRP)

A cross table is an <oid,oid> BAT where the first (head) denotes a tuple in the cross table and the second (tail) marks all identical lists. The tail-oids contain group identifiers; that is, this value is equal iff two tuples belong to the same group. The group identifiers are chosen from the domain of the tuple-identifiers. This simplifies getting back to the original tuples, when talking about a group. If the tuple-oid of 'John' is chosen as a group-id, you might view this as saying that each member of the group is 'like John' with respect to the grouping-criterion.

Successively the subgroups can be identified by modifying the GRP BAT or to derive a new GRP BAT for the subgroups. After all groups have been identified this way, a BAT histogram operation can be used to obtain the counts of each data cube. Other aggregation operations using the MIL set aggregate construct (bat) can be used as well; note for instance that histogram == (b.reverse()).

The Monet interface module specification is shown below. Ideally we should defined stronger type constraints, e.g. command group.new(attr:bat[,:any_1]

The group macro is split along three dimensions:

DimensionDescription
[type:]Type specific implementation for selecting the right hash function and data size etc.
[clustered:]The select the appropriate algorithm, i.e., with or without taking advantage of an order of values in the parent groups
[physical properties:]Values , choosing between a fixed predefined and a custom hash mask. Custom allows the user to determine the size of the hash mask (and indirectly the estimated size of the result). The hash mask is 2^n - 1 where n is given by the user, or 1023 otherwise, and the derived result size is 4 ... 2^n

Further research should point out whether fitting a simple statistical model (possibly a simple mixture model) can help choose these parameters automatically; the current idea is that the user (which could be a domain-specific extension of the higher-level language) knows the properties of the data, especially for IR in which the standard grouping settings differ significantly from the original data science application.

MODULE group;

COMMAND group.group(X_0:bat[:any_1]):bat[:oid];
COMMENT "";

COMMAND group.group(X_0:bat[:any_1]) (X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:lng]);
COMMENT "";

COMMAND group.group(X_0:bat[:any_1], X_1:bat[:oid]):bat[:oid];
COMMENT "";

COMMAND group.group(X_0:bat[:any_1], X_1:bat[:oid]) (X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:lng]);
COMMENT "";

COMMAND group.group(X_0:bat[:any_1]) (X_1:bat[:oid], X_2:bat[:oid]);
COMMENT "";

COMMAND group.group(X_0:bat[:any_1], X_1:bat[:oid]) (X_2:bat[:oid], X_3:bat[:oid]);
COMMENT "";

COMMAND group.groupdone(X_0:bat[:any_1]):bat[:oid];
COMMENT "";

COMMAND group.groupdone(X_0:bat[:any_1]) (X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:lng]);
COMMENT "";

COMMAND group.groupdone(X_0:bat[:any_1], X_1:bat[:oid]):bat[:oid];
COMMENT "";

COMMAND group.groupdone(X_0:bat[:any_1], X_1:bat[:oid]) (X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:lng]);
COMMENT "";

COMMAND group.groupdone(X_0:bat[:any_1]) (X_1:bat[:oid], X_2:bat[:oid]);
COMMENT "";

COMMAND group.groupdone(X_0:bat[:any_1], X_1:bat[:oid]) (X_2:bat[:oid], X_3:bat[:oid]);
COMMENT "";

PATTERN group.multicolumn(X_0:bat[:any]...) (X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:any]);
COMMENT "Derivation of a group index over multiple columns.";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid]):bat[:oid];
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid]) (X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:lng]);
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid]):bat[:oid];
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid]) (X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:lng]);
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:lng]):bat[:oid];
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:lng]) (X_4:bat[:oid], X_5:bat[:oid], X_6:bat[:lng]);
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:lng]):bat[:oid];
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:lng]) (X_5:bat[:oid], X_6:bat[:oid], X_7:bat[:lng]);
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid]) (X_2:bat[:oid], X_3:bat[:oid]);
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid]) (X_3:bat[:oid], X_4:bat[:oid]);
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:lng]) (X_4:bat[:oid], X_5:bat[:oid]);
COMMENT "";

COMMAND group.subgroup(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:lng]) (X_5:bat[:oid], X_6:bat[:oid]);
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid]):bat[:oid];
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid]) (X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:lng]);
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid]):bat[:oid];
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid]) (X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:lng]);
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:lng]):bat[:oid];
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:lng]) (X_4:bat[:oid], X_5:bat[:oid], X_6:bat[:lng]);
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:lng]):bat[:oid];
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:lng]) (X_5:bat[:oid], X_6:bat[:oid], X_7:bat[:lng]);
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid]) (X_2:bat[:oid], X_3:bat[:oid]);
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid]) (X_3:bat[:oid], X_4:bat[:oid]);
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:lng]) (X_4:bat[:oid], X_5:bat[:oid]);
COMMENT "";

COMMAND group.subgroupdone(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:lng]) (X_5:bat[:oid], X_6:bat[:oid]);
COMMENT "";

Aggr module

MODULE aggr;

COMMAND aggr.Collect(X_0:bat[:wkb]):wkb;
COMMENT "TODO";

COMMAND aggr.MakeLine(X_0:bat[:wkb]):wkb;
COMMENT "Gets a BAT with point or linestring geometries and returns a single linestring geometry";

COMMAND aggr.all(X_0:bat[:any_1]):any_1;
COMMENT "if all values in b are equal return this, else nil";

PATTERN aggr.allnotequal(X_0:bat[:any_1], X_1:bat[:any_1]):bit;
COMMENT "if all values in r are not equal to l, return true, else if r has nil, return nil, else return false";

PATTERN aggr.anyequal(X_0:any_1, X_1:any_1):bit;
COMMENT "";

PATTERN aggr.anyequal(X_0:bat[:any_1], X_1:bat[:any_1]):bit;
COMMENT "if any value in r is equal to l, return true, else if r has nil, return nil, else return false";

COMMAND aggr.avg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail average on bte";

COMMAND aggr.avg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail average on dbl";

COMMAND aggr.avg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail average on flt";

COMMAND aggr.avg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail average on int";

COMMAND aggr.avg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail average on lng";

COMMAND aggr.avg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail average on sht";

COMMAND aggr.avg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:int):bat[:dbl];
COMMENT "Grouped tail average on bte";

COMMAND aggr.avg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:int):bat[:dbl];
COMMENT "Grouped tail average on dbl";

COMMAND aggr.avg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:int):bat[:dbl];
COMMENT "Grouped tail average on flt";

COMMAND aggr.avg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:int):bat[:dbl];
COMMENT "Grouped tail average on int";

COMMAND aggr.avg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:int):bat[:dbl];
COMMENT "Grouped tail average on lng";

COMMAND aggr.avg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:int):bat[:dbl];
COMMENT "Grouped tail average on sht";

COMMAND aggr.avg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]) (X_3:bat[:dbl], X_4:bat[:lng]);
COMMENT "Grouped tail average on bte, also returns count";

COMMAND aggr.avg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1]) (X_3:bat[:dbl], X_4:bat[:lng]);
COMMENT "Grouped tail average on dbl, also returns count";

COMMAND aggr.avg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1]) (X_3:bat[:dbl], X_4:bat[:lng]);
COMMENT "Grouped tail average on flt, also returns count";

COMMAND aggr.avg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]) (X_3:bat[:dbl], X_4:bat[:lng]);
COMMENT "Grouped tail average on int, also returns count";

COMMAND aggr.avg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1]) (X_3:bat[:dbl], X_4:bat[:lng]);
COMMENT "Grouped tail average on lng, also returns count";

COMMAND aggr.avg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]) (X_3:bat[:dbl], X_4:bat[:lng]);
COMMENT "Grouped tail average on sht, also returns count";

COMMAND aggr.avg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:int) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped tail average on bte, also returns count";

COMMAND aggr.avg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:int) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped tail average on dbl, also returns count";

COMMAND aggr.avg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:int) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped tail average on flt, also returns count";

COMMAND aggr.avg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:int) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped tail average on int, also returns count";

COMMAND aggr.avg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:int) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped tail average on lng, also returns count";

COMMAND aggr.avg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:int) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped tail average on sht, also returns count";

PATTERN aggr.avg(X_0:bat[:bte], X_1:bat[:oid], X_2:bit) (X_3:bte, X_4:lng, X_5:lng);
COMMENT "Calculate aggregate average of B.";

PATTERN aggr.avg(X_0:bat[:int], X_1:bat[:oid], X_2:bit) (X_3:int, X_4:lng, X_5:lng);
COMMENT "Calculate aggregate average of B.";

PATTERN aggr.avg(X_0:bat[:lng], X_1:bat[:oid], X_2:bit) (X_3:lng, X_4:lng, X_5:lng);
COMMENT "Calculate aggregate average of B.";

PATTERN aggr.avg(X_0:bat[:sht], X_1:bat[:oid], X_2:bit) (X_3:sht, X_4:lng, X_5:lng);
COMMENT "Calculate aggregate average of B.";

PATTERN aggr.avg(X_0:bat[:bte], X_1:bat[:lng], X_2:bat[:lng]):bte;
COMMENT "Average aggregation combiner.";

PATTERN aggr.avg(X_0:bat[:int], X_1:bat[:lng], X_2:bat[:lng]):int;
COMMENT "Average aggregation combiner.";

PATTERN aggr.avg(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:lng]):lng;
COMMENT "Average aggregation combiner.";

PATTERN aggr.avg(X_0:bat[:sht], X_1:bat[:lng], X_2:bat[:lng]):sht;
COMMENT "Average aggregation combiner.";

PATTERN aggr.avg(X_0:bat[:any_2]):dbl;
COMMENT "Gives the avg of all tail values";

PATTERN aggr.avg(X_0:bat[:any_2], X_1:int):dbl;
COMMENT "Gives the avg of all tail values";

COMMAND aggr.cardinality(X_0:bat[:any_2]):lng;
COMMENT "Return the cardinality of the BAT tail values.";

COMMAND aggr.corr(X_0:bat[:bte], X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Correlation aggregate";

COMMAND aggr.corr(X_0:bat[:dbl], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Correlation aggregate";

COMMAND aggr.corr(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Correlation aggregate";

COMMAND aggr.corr(X_0:bat[:int], X_1:bat[:int], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Correlation aggregate";

COMMAND aggr.corr(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Correlation aggregate";

COMMAND aggr.corr(X_0:bat[:sht], X_1:bat[:sht], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Correlation aggregate";

COMMAND aggr.corr(X_0:bat[:any_2], X_1:bat[:any_2]):dbl;
COMMENT "Gives the correlation of all tail values";

COMMAND aggr.count(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bit):bat[:lng];
COMMENT "";

COMMAND aggr.count(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2]):bat[:lng];
COMMENT "Grouped count";

COMMAND aggr.count(X_0:bat[:any], X_1:bat[:oid]):lng;
COMMENT "Return the current size (in number of elements) in a BAT.";

COMMAND aggr.count(X_0:bat[:any], X_1:bat[:oid], X_2:bit):lng;
COMMENT "Return the number of elements currently in a BAT ignores\nBUNs with nil-tail iff ignore_nils==TRUE.";

COMMAND aggr.count(X_0:bat[:any]):lng;
COMMENT "Return the current size (in number of elements) in a BAT.";

COMMAND aggr.count(X_0:bat[:any], X_1:bit):lng;
COMMENT "Return the number of elements currently in a BAT ignores\nBUNs with nil-tail iff ignore_nils==TRUE.";

COMMAND aggr.count_no_nil(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2]):bat[:lng];
COMMENT "";

COMMAND aggr.count_no_nil(X_0:bat[:any_2], X_1:bat[:oid]):lng;
COMMENT "Return the number of elements currently\nin a BAT ignoring BUNs with nil-tail";

COMMAND aggr.count_no_nil(X_0:bat[:any_2]):lng;
COMMENT "Return the number of elements currently\nin a BAT ignoring BUNs with nil-tail";

COMMAND aggr.covariance(X_0:bat[:bte], X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance sample aggregate";

COMMAND aggr.covariance(X_0:bat[:dbl], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance sample aggregate";

COMMAND aggr.covariance(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance sample aggregate";

COMMAND aggr.covariance(X_0:bat[:int], X_1:bat[:int], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance sample aggregate";

COMMAND aggr.covariance(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance sample aggregate";

COMMAND aggr.covariance(X_0:bat[:sht], X_1:bat[:sht], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance sample aggregate";

COMMAND aggr.covariance(X_0:bat[:any_2], X_1:bat[:any_2]):dbl;
COMMENT "Gives the covariance of all tail values";

COMMAND aggr.covariancep(X_0:bat[:bte], X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance population aggregate";

COMMAND aggr.covariancep(X_0:bat[:dbl], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance population aggregate";

COMMAND aggr.covariancep(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance population aggregate";

COMMAND aggr.covariancep(X_0:bat[:int], X_1:bat[:int], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance population aggregate";

COMMAND aggr.covariancep(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance population aggregate";

COMMAND aggr.covariancep(X_0:bat[:sht], X_1:bat[:sht], X_2:bat[:oid], X_3:bat[:any_1]):bat[:dbl];
COMMENT "Covariance population aggregate";

COMMAND aggr.covariancep(X_0:bat[:any_2], X_1:bat[:any_2]):dbl;
COMMENT "Gives the covariance of all tail values";

COMMAND aggr.exist(X_0:bat[:any_2], X_1:any_1):bit;
COMMENT "";

PATTERN aggr.exist(X_0:any_1):bit;
COMMENT "";

COMMAND aggr.jsonaggr(X_0:bat[:dbl]):str;
COMMENT "Aggregate the double values to array.";

COMMAND aggr.jsonaggr(X_0:bat[:str]):str;
COMMENT "Aggregate the string values to array.";

COMMAND aggr.max(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2]):bat[:any_1];
COMMENT "";

COMMAND aggr.max(X_0:bat[:any_2]):any_2;
COMMENT "Return the highest tail value or nil.";

COMMAND aggr.max(X_0:bat[:any_2], X_1:bit):any_2;
COMMENT "Return the highest tail value or nil.";

COMMAND aggr.median(X_0:bat[:any_1]):any_1;
COMMENT "Median aggregate";

COMMAND aggr.median_avg(X_0:bat[:any_1]):dbl;
COMMENT "Median aggregate";

COMMAND aggr.min(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2]):bat[:any_1];
COMMENT "";

COMMAND aggr.min(X_0:bat[:any_2]):any_2;
COMMENT "Return the lowest tail value or nil.";

COMMAND aggr.min(X_0:bat[:any_2], X_1:bit):any_2;
COMMENT "Return the lowest tail value or nil.";

PATTERN aggr.not_anyequal(X_0:any_1, X_1:any_1):bit;
COMMENT "";

PATTERN aggr.not_exist(X_0:any_1):bit;
COMMENT "";

COMMAND aggr.not_unique(X_0:bat[:oid]):bit;
COMMENT "check if the tail sorted bat b doesn't have unique tail values";

COMMAND aggr.null(X_0:bat[:any_1]):bit;
COMMENT "if b has a nil return true, else false";

COMMAND aggr.prod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:bte];
COMMENT "Grouped tail product on bte";

COMMAND aggr.prod(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail product on dbl";

COMMAND aggr.prod(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail product on flt";

COMMAND aggr.prod(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1]):bat[:flt];
COMMENT "Grouped tail product on flt";

COMMAND aggr.prod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:int];
COMMENT "Grouped tail product on bte";

COMMAND aggr.prod(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]):bat[:int];
COMMENT "Grouped tail product on int";

COMMAND aggr.prod(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:int];
COMMENT "Grouped tail product on sht";

COMMAND aggr.prod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:lng];
COMMENT "Grouped tail product on bte";

COMMAND aggr.prod(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]):bat[:lng];
COMMENT "Grouped tail product on int";

COMMAND aggr.prod(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1]):bat[:lng];
COMMENT "Grouped tail product on lng";

COMMAND aggr.prod(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:lng];
COMMENT "Grouped tail product on sht";

COMMAND aggr.prod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:sht];
COMMENT "Grouped tail product on bte";

COMMAND aggr.prod(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:sht];
COMMENT "Grouped tail product on sht";

PATTERN aggr.prod(X_0:bat[:bte]):bte;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:bte]):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:bte]):int;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:bte]):lng;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:bte]):sht;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bat[:oid]):bte;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bat[:oid]):int;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bat[:oid]):lng;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bat[:oid]):sht;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bat[:oid], X_2:bit):bte;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bat[:oid], X_2:bit):int;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bat[:oid], X_2:bit):lng;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bat[:oid], X_2:bit):sht;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bit):bte;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bit):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bit):int;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bit):lng;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:bte], X_1:bit):sht;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:dbl]):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:dbl], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:dbl], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:dbl], X_1:bit):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:flt]):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:flt]):flt;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:flt], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:flt], X_1:bat[:oid]):flt;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:flt], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:flt], X_1:bat[:oid], X_2:bit):flt;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:flt], X_1:bit):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:flt], X_1:bit):flt;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:int]):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:int]):int;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:int]):lng;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:int], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:int], X_1:bat[:oid]):int;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:int], X_1:bat[:oid]):lng;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:int], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:int], X_1:bat[:oid], X_2:bit):int;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:int], X_1:bat[:oid], X_2:bit):lng;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:int], X_1:bit):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:int], X_1:bit):int;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:int], X_1:bit):lng;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:lng]):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:lng]):lng;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:lng], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:lng], X_1:bat[:oid]):lng;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:lng], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:lng], X_1:bat[:oid], X_2:bit):lng;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:lng], X_1:bit):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:lng], X_1:bit):lng;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:sht]):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:sht]):int;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:sht]):lng;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:sht]):sht;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bat[:oid]):int;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bat[:oid]):lng;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bat[:oid]):sht;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bat[:oid], X_2:bit):int;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bat[:oid], X_2:bit):lng;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bat[:oid], X_2:bit):sht;
COMMENT "Calculate aggregate product of B with candidate list.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bit):dbl;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bit):int;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bit):lng;
COMMENT "Calculate aggregate product of B.";

PATTERN aggr.prod(X_0:bat[:sht], X_1:bit):sht;
COMMENT "Calculate aggregate product of B.";

COMMAND aggr.quantile(X_0:bat[:any_1], X_1:bat[:dbl]):any_1;
COMMENT "Quantile aggregate";

COMMAND aggr.quantile(X_0:bat[:any_1], X_1:dbl):any_1;
COMMENT "Quantile aggregate";

COMMAND aggr.quantile_avg(X_0:bat[:any_1], X_1:bat[:dbl]):dbl;
COMMENT "Quantile aggregate";

COMMAND aggr.quantile_avg(X_0:bat[:any_1], X_1:dbl):dbl;
COMMENT "Quantile aggregate";

COMMAND aggr.stdev(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (sample/non-biased) on bte";

COMMAND aggr.stdev(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (sample/non-biased) on dbl";

COMMAND aggr.stdev(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (sample/non-biased) on flt";

COMMAND aggr.stdev(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (sample/non-biased) on int";

COMMAND aggr.stdev(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (sample/non-biased) on lng";

COMMAND aggr.stdev(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (sample/non-biased) on sht";

COMMAND aggr.stdev(X_0:bat[:any_2]):dbl;
COMMENT "Gives the standard deviation of all tail values";

COMMAND aggr.stdevp(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (population/biased) on bte";

COMMAND aggr.stdevp(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (population/biased) on dbl";

COMMAND aggr.stdevp(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (population/biased) on flt";

COMMAND aggr.stdevp(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (population/biased) on int";

COMMAND aggr.stdevp(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (population/biased) on lng";

COMMAND aggr.stdevp(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail standard deviation (population/biased) on sht";

COMMAND aggr.stdevp(X_0:bat[:any_2]):dbl;
COMMENT "Gives the standard deviation of all tail values";

COMMAND aggr.str_group_concat(X_0:bat[:str], X_1:bat[:oid], X_2:bat[:any_1]):bat[:str];
COMMENT "Grouped string tail concat";

COMMAND aggr.str_group_concat(X_0:bat[:str], X_1:bat[:str], X_2:bat[:oid], X_3:bat[:any_1]):bat[:str];
COMMENT "Grouped string tail concat with custom separator";

PATTERN aggr.str_group_concat(X_0:bat[:str]):str;
COMMENT "Calculate aggregate string concatenate of B.";

PATTERN aggr.str_group_concat(X_0:bat[:str], X_1:bat[:oid]):str;
COMMENT "Calculate aggregate string concatenate of B with candidate list.";

PATTERN aggr.str_group_concat(X_0:bat[:str], X_1:bat[:oid], X_2:bit):str;
COMMENT "Calculate aggregate string concatenate of B with candidate list.";

PATTERN aggr.str_group_concat(X_0:bat[:str], X_1:bat[:str]):str;
COMMENT "Calculate aggregate string concatenate of B with separator SEP.";

PATTERN aggr.str_group_concat(X_0:bat[:str], X_1:bat[:str], X_2:bat[:oid]):str;
COMMENT "Calculate aggregate string concatenate of B with candidate list and separator SEP.";

PATTERN aggr.str_group_concat(X_0:bat[:str], X_1:bat[:str], X_2:bat[:oid], X_3:bit):str;
COMMENT "Calculate aggregate string concatenate of B with candidate list and separator SEP.";

PATTERN aggr.str_group_concat(X_0:bat[:str], X_1:bat[:str], X_2:bit):str;
COMMENT "Calculate aggregate string concatenate of B with separator SEP.";

PATTERN aggr.str_group_concat(X_0:bat[:str], X_1:bit):str;
COMMENT "Calculate aggregate string concatenate of B.";

COMMAND aggr.subCollect(X_0:bat[:wkb], X_1:bat[:oid], X_2:bat[:oid], X_3:bit):bat[:wkb];
COMMENT "TODO";

COMMAND aggr.subCollect(X_0:bat[:wkb], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:wkb];
COMMENT "TODO";

COMMAND aggr.subMakeLine(X_0:bat[:wkb], X_1:bat[:oid], X_2:bat[:oid], X_3:bit):bat[:wkb];
COMMENT "TODO";

COMMAND aggr.subMakeLine(X_0:bat[:wkb], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:wkb];
COMMENT "TODO";

PATTERN aggr.suball(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:oid], X_4:bit):bat[:any_1];
COMMENT "if all values in l are equal (per group) return the value, else nil";

PATTERN aggr.suball(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bit):bat[:any_1];
COMMENT "if all values in l are equal (per group) return the value, else nil";

PATTERN aggr.suballnotequal(X_0:bat[:any_1], X_1:bat[:any_1], X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit];
COMMENT "if all values in r are not equal to l, return true, else if r has nil return nil, else return false, except if rid is nil (ie empty) then return true; with candidate list";

PATTERN aggr.suballnotequal(X_0:bat[:any_1], X_1:bat[:any_1], X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid], X_5:bit):bat[:bit];
COMMENT "if all values in r are not equal to l, return true, else if r has nil return nil, else return false, except if rid is nil (ie empty) then return true";

PATTERN aggr.suballnotequal(X_0:bat[:any_1], X_1:bat[:any_1], X_2:bat[:oid], X_3:bat[:oid], X_4:bit):bat[:bit];
COMMENT "if all values in r are not equal to l, return true, else if r has nil, return nil else return false";

PATTERN aggr.subanyequal(X_0:bat[:any_1], X_1:bat[:any_1], X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid], X_5:bat[:oid], X_6:bit):bat[:bit];
COMMENT "if any value in r is equal to l, return true, else if r has nil, return nil, else return false, except if rid is nil (ie empty) then return false; with candidate list";

PATTERN aggr.subanyequal(X_0:bat[:any_1], X_1:bat[:any_1], X_2:bat[:oid], X_3:bat[:oid], X_4:bat[:oid], X_5:bit):bat[:bit];
COMMENT "if any value in r is equal to l, return true, else if r has nil, return nil, else return false, except if rid is nil (ie empty) then return false";

PATTERN aggr.subanyequal(X_0:bat[:any_1], X_1:bat[:any_1], X_2:bat[:oid], X_3:bat[:oid], X_4:bit):bat[:bit];
COMMENT "if any value in r is equal to l, return true, else if r has nil, return nil, else return false";

COMMAND aggr.subavg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit) (X_5:bat[:bte], X_6:bat[:lng], X_7:bat[:lng]);
COMMENT "Grouped average aggregation";

COMMAND aggr.subavg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit) (X_5:bat[:int], X_6:bat[:lng], X_7:bat[:lng]);
COMMENT "Grouped average aggregation";

COMMAND aggr.subavg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit) (X_5:bat[:lng], X_6:bat[:lng], X_7:bat[:lng]);
COMMENT "Grouped average aggregation";

COMMAND aggr.subavg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit) (X_5:bat[:sht], X_6:bat[:lng], X_7:bat[:lng]);
COMMENT "Grouped average aggregation";

COMMAND aggr.subavg(X_0:bat[:bte], X_1:bat[:lng], X_2:bat[:lng], X_3:bat[:oid], X_4:bat[:any_1], X_5:bit):bat[:bte];
COMMENT "Grouped average aggregation combiner";

COMMAND aggr.subavg(X_0:bat[:int], X_1:bat[:lng], X_2:bat[:lng], X_3:bat[:oid], X_4:bat[:any_1], X_5:bit):bat[:int];
COMMENT "Grouped average aggregation combiner";

COMMAND aggr.subavg(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:lng], X_3:bat[:oid], X_4:bat[:any_1], X_5:bit):bat[:lng];
COMMENT "Grouped average aggregation combiner";

COMMAND aggr.subavg(X_0:bat[:sht], X_1:bat[:lng], X_2:bat[:lng], X_3:bat[:oid], X_4:bat[:any_1], X_5:bit):bat[:sht];
COMMENT "Grouped average aggregation combiner";

COMMAND aggr.subavg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int):bat[:dbl];
COMMENT "Grouped average aggregate";

COMMAND aggr.subavg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int):bat[:dbl];
COMMENT "Grouped average aggregate with candidates list";

COMMAND aggr.subavg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit) (X_4:bat[:dbl], X_5:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit, X_4:int) (X_5:bat[:dbl], X_6:bat[:lng]);
COMMENT "Grouped average aggregate, also returns count";

COMMAND aggr.subavg(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int) (X_6:bat[:dbl], X_7:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int) (X_6:bat[:dbl], X_7:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int) (X_6:bat[:dbl], X_7:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int) (X_6:bat[:dbl], X_7:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int) (X_6:bat[:dbl], X_7:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subavg(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit, X_5:int) (X_6:bat[:dbl], X_7:bat[:lng]);
COMMENT "Grouped average aggregate with candidates list, also returns count";

COMMAND aggr.subcorr(X_0:bat[:bte], X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate";

COMMAND aggr.subcorr(X_0:bat[:dbl], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate";

COMMAND aggr.subcorr(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate";

COMMAND aggr.subcorr(X_0:bat[:int], X_1:bat[:int], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate";

COMMAND aggr.subcorr(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate";

COMMAND aggr.subcorr(X_0:bat[:sht], X_1:bat[:sht], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate";

COMMAND aggr.subcorr(X_0:bat[:bte], X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate with candidate list";

COMMAND aggr.subcorr(X_0:bat[:dbl], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate with candidate list";

COMMAND aggr.subcorr(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate with candidate list";

COMMAND aggr.subcorr(X_0:bat[:int], X_1:bat[:int], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate with candidate list";

COMMAND aggr.subcorr(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate with candidate list";

COMMAND aggr.subcorr(X_0:bat[:sht], X_1:bat[:sht], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped correlation aggregate with candidate list";

COMMAND aggr.subcount(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bit):bat[:lng];
COMMENT "Grouped count aggregate";

COMMAND aggr.subcount(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bat[:oid], X_4:bit):bat[:lng];
COMMENT "Grouped count aggregate with candidates list";

COMMAND aggr.subcovariance(X_0:bat[:bte], X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate";

COMMAND aggr.subcovariance(X_0:bat[:dbl], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate";

COMMAND aggr.subcovariance(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate";

COMMAND aggr.subcovariance(X_0:bat[:int], X_1:bat[:int], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate";

COMMAND aggr.subcovariance(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate";

COMMAND aggr.subcovariance(X_0:bat[:sht], X_1:bat[:sht], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate";

COMMAND aggr.subcovariance(X_0:bat[:bte], X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate with candidate list";

COMMAND aggr.subcovariance(X_0:bat[:dbl], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate with candidate list";

COMMAND aggr.subcovariance(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate with candidate list";

COMMAND aggr.subcovariance(X_0:bat[:int], X_1:bat[:int], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate with candidate list";

COMMAND aggr.subcovariance(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate with candidate list";

COMMAND aggr.subcovariance(X_0:bat[:sht], X_1:bat[:sht], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance sample aggregate with candidate list";

COMMAND aggr.subcovariancep(X_0:bat[:bte], X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate";

COMMAND aggr.subcovariancep(X_0:bat[:dbl], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate";

COMMAND aggr.subcovariancep(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate";

COMMAND aggr.subcovariancep(X_0:bat[:int], X_1:bat[:int], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate";

COMMAND aggr.subcovariancep(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate";

COMMAND aggr.subcovariancep(X_0:bat[:sht], X_1:bat[:sht], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate";

COMMAND aggr.subcovariancep(X_0:bat[:bte], X_1:bat[:bte], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate with candidate list";

COMMAND aggr.subcovariancep(X_0:bat[:dbl], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate with candidate list";

COMMAND aggr.subcovariancep(X_0:bat[:flt], X_1:bat[:flt], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate with candidate list";

COMMAND aggr.subcovariancep(X_0:bat[:int], X_1:bat[:int], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate with candidate list";

COMMAND aggr.subcovariancep(X_0:bat[:lng], X_1:bat[:lng], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate with candidate list";

COMMAND aggr.subcovariancep(X_0:bat[:sht], X_1:bat[:sht], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped covariance population aggregate with candidate list";

PATTERN aggr.subexist(X_0:bat[:any], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:oid], X_4:bit):bat[:bit];
COMMENT "";

PATTERN aggr.subexist(X_0:bat[:any], X_1:bat[:oid], X_2:bat[:oid], X_3:bit):bat[:bit];
COMMENT "";

COMMAND aggr.subjsonaggr(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:str];
COMMENT "Grouped aggregation of values.";

COMMAND aggr.subjsonaggr(X_0:bat[:str], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:str];
COMMENT "Grouped aggregation of values.";

COMMAND aggr.subjsonaggr(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:str];
COMMENT "Grouped aggregation of values with candidates list.";

COMMAND aggr.subjsonaggr(X_0:bat[:str], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:str];
COMMENT "Grouped aggregation of values with candidates list.";

COMMAND aggr.submax(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bit):bat[:oid];
COMMENT "Grouped maximum aggregate";

COMMAND aggr.submax(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bit):bat[:any_1];
COMMENT "Grouped maximum aggregate";

COMMAND aggr.submax(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bat[:oid], X_4:bit):bat[:oid];
COMMENT "Grouped maximum aggregate with candidates list";

COMMAND aggr.submax(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bat[:oid], X_4:bit):bat[:any_1];
COMMENT "Grouped maximum aggregate with candidates list";

COMMAND aggr.submedian(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bit):bat[:any_1];
COMMENT "Grouped median aggregate";

COMMAND aggr.submedian(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bat[:oid], X_4:bit):bat[:any_1];
COMMENT "Grouped median aggregate with candidate list";

COMMAND aggr.submedian_avg(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bit):bat[:dbl];
COMMENT "Grouped median aggregate";

COMMAND aggr.submedian_avg(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped median aggregate with candidate list";

COMMAND aggr.submin(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bit):bat[:oid];
COMMENT "Grouped minimum aggregate";

COMMAND aggr.submin(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bit):bat[:any_1];
COMMENT "Grouped minimum aggregate";

COMMAND aggr.submin(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bat[:oid], X_4:bit):bat[:oid];
COMMENT "Grouped minimum aggregate with candidates list";

COMMAND aggr.submin(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:any_2], X_3:bat[:oid], X_4:bit):bat[:any_1];
COMMENT "Grouped minimum aggregate with candidates list";

PATTERN aggr.subnot_exist(X_0:bat[:any], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:oid], X_4:bit):bat[:bit];
COMMENT "";

PATTERN aggr.subnot_exist(X_0:bat[:any], X_1:bat[:oid], X_2:bat[:oid], X_3:bit):bat[:bit];
COMMENT "";

PATTERN aggr.subnull(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bat[:oid], X_4:bit):bat[:bit];
COMMENT "if any value in l is nil with in a group return true for that group, else false; with candidate list";

PATTERN aggr.subnull(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bit):bat[:bit];
COMMENT "if any value in l is nil with in a group return true for that group, else false";

COMMAND aggr.subprod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:bte];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:flt];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:int];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:int];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:int];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:lng];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:lng];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:lng];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:lng];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:sht];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:sht];
COMMENT "Grouped product aggregate";

COMMAND aggr.subprod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:bte];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:flt];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:int];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:int];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:int];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:lng];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:lng];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:lng];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:lng];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:sht];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subprod(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:sht];
COMMENT "Grouped product aggregate with candidates list";

COMMAND aggr.subquantile(X_0:bat[:any_1], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_2], X_4:bit):bat[:any_1];
COMMENT "Grouped quantile aggregate";

COMMAND aggr.subquantile(X_0:bat[:any_1], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_2], X_4:bat[:oid], X_5:bit):bat[:any_1];
COMMENT "Grouped quantile aggregate with candidate list";

COMMAND aggr.subquantile_avg(X_0:bat[:any_1], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_2], X_4:bit):bat[:dbl];
COMMENT "Grouped quantile aggregate";

COMMAND aggr.subquantile_avg(X_0:bat[:any_1], X_1:bat[:dbl], X_2:bat[:oid], X_3:bat[:any_2], X_4:bat[:oid], X_5:bit):bat[:dbl];
COMMENT "Grouped quantile aggregate with candidate list";

COMMAND aggr.substdev(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate";

COMMAND aggr.substdev(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate";

COMMAND aggr.substdev(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate";

COMMAND aggr.substdev(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate";

COMMAND aggr.substdev(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate";

COMMAND aggr.substdev(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate";

COMMAND aggr.substdev(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate with candidates list";

COMMAND aggr.substdev(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate with candidates list";

COMMAND aggr.substdev(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate with candidates list";

COMMAND aggr.substdev(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate with candidates list";

COMMAND aggr.substdev(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate with candidates list";

COMMAND aggr.substdev(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (sample/non-biased) aggregate with candidates list";

COMMAND aggr.substdevp(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate";

COMMAND aggr.substdevp(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate";

COMMAND aggr.substdevp(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate";

COMMAND aggr.substdevp(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate";

COMMAND aggr.substdevp(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate";

COMMAND aggr.substdevp(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate";

COMMAND aggr.substdevp(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate with candidates list";

COMMAND aggr.substdevp(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate with candidates list";

COMMAND aggr.substdevp(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate with candidates list";

COMMAND aggr.substdevp(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate with candidates list";

COMMAND aggr.substdevp(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate with candidates list";

COMMAND aggr.substdevp(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped standard deviation (population/biased) aggregate with candidates list";

COMMAND aggr.substr_group_concat(X_0:bat[:str], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:str];
COMMENT "Grouped string concat";

COMMAND aggr.substr_group_concat(X_0:bat[:str], X_1:bat[:str], X_2:bat[:oid], X_3:bat[:any_1], X_4:bit):bat[:str];
COMMENT "Grouped string concat with custom separator";

COMMAND aggr.substr_group_concat(X_0:bat[:str], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:str];
COMMENT "Grouped string concat with candidates list";

COMMAND aggr.substr_group_concat(X_0:bat[:str], X_1:bat[:str], X_2:bat[:oid], X_3:bat[:any_1], X_4:bat[:oid], X_5:bit):bat[:str];
COMMENT "Grouped string concat with candidates list with custom separator";

COMMAND aggr.subsum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:bte];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:flt];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:int];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:int];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:int];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:lng];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:lng];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:lng];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:lng];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:sht];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:sht];
COMMENT "Grouped sum aggregate";

COMMAND aggr.subsum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:bte];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:flt];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:int];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:int];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:int];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:lng];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:lng];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:lng];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:lng];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:sht];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subsum(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:sht];
COMMENT "Grouped sum aggregate with candidates list";

COMMAND aggr.subvariance(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate";

COMMAND aggr.subvariance(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate";

COMMAND aggr.subvariance(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate";

COMMAND aggr.subvariance(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate";

COMMAND aggr.subvariance(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate";

COMMAND aggr.subvariance(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate";

COMMAND aggr.subvariance(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate with candidates list";

COMMAND aggr.subvariance(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate with candidates list";

COMMAND aggr.subvariance(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate with candidates list";

COMMAND aggr.subvariance(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate with candidates list";

COMMAND aggr.subvariance(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate with candidates list";

COMMAND aggr.subvariance(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (sample/non-biased) aggregate with candidates list";

COMMAND aggr.subvariancep(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate";

COMMAND aggr.subvariancep(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate";

COMMAND aggr.subvariancep(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate";

COMMAND aggr.subvariancep(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate";

COMMAND aggr.subvariancep(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate";

COMMAND aggr.subvariancep(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate";

COMMAND aggr.subvariancep(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate with candidates list";

COMMAND aggr.subvariancep(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate with candidates list";

COMMAND aggr.subvariancep(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate with candidates list";

COMMAND aggr.subvariancep(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate with candidates list";

COMMAND aggr.subvariancep(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate with candidates list";

COMMAND aggr.subvariancep(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1], X_3:bat[:oid], X_4:bit):bat[:dbl];
COMMENT "Grouped variance (population/biased) aggregate with candidates list";

COMMAND aggr.subzero_or_one(X_0:bat[:any_1], X_1:bat[:oid], X_2:bat[:oid], X_3:bit):bat[:any_1];
COMMENT "";

COMMAND aggr.sum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:bte];
COMMENT "Grouped tail sum on bte";

COMMAND aggr.sum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail sum on bte";

COMMAND aggr.sum(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail sum on dbl";

COMMAND aggr.sum(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail sum on flt";

COMMAND aggr.sum(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail sum on int";

COMMAND aggr.sum(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail sum on lng";

COMMAND aggr.sum(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail sum on sht";

COMMAND aggr.sum(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1]):bat[:flt];
COMMENT "Grouped tail sum on flt";

COMMAND aggr.sum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:int];
COMMENT "Grouped tail sum on bte";

COMMAND aggr.sum(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]):bat[:int];
COMMENT "Grouped tail sum on int";

COMMAND aggr.sum(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:int];
COMMENT "Grouped tail sum on sht";

COMMAND aggr.sum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:lng];
COMMENT "Grouped tail sum on bte";

COMMAND aggr.sum(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]):bat[:lng];
COMMENT "Grouped tail sum on int";

COMMAND aggr.sum(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1]):bat[:lng];
COMMENT "Grouped tail sum on lng";

COMMAND aggr.sum(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:lng];
COMMENT "Grouped tail sum on sht";

COMMAND aggr.sum(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:sht];
COMMENT "Grouped tail sum on bte";

COMMAND aggr.sum(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:sht];
COMMENT "Grouped tail sum on sht";

PATTERN aggr.sum(X_0:bat[:bte]):bte;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:bte]):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:bte]):int;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:bte]):lng;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:bte]):sht;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bat[:oid]):bte;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bat[:oid]):int;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bat[:oid]):lng;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bat[:oid]):sht;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bat[:oid], X_2:bit):bte;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bat[:oid], X_2:bit):int;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bat[:oid], X_2:bit):lng;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bat[:oid], X_2:bit):sht;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bit):bte;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bit):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bit):int;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bit):lng;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:bte], X_1:bit):sht;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:dbl]):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:dbl], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:dbl], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:dbl], X_1:bit):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:flt]):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:flt]):flt;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:flt], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:flt], X_1:bat[:oid]):flt;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:flt], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:flt], X_1:bat[:oid], X_2:bit):flt;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:flt], X_1:bit):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:flt], X_1:bit):flt;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:int]):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:int]):int;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:int]):lng;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:int], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:int], X_1:bat[:oid]):int;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:int], X_1:bat[:oid]):lng;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:int], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:int], X_1:bat[:oid], X_2:bit):int;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:int], X_1:bat[:oid], X_2:bit):lng;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:int], X_1:bit):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:int], X_1:bit):int;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:int], X_1:bit):lng;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:lng]):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:lng]):lng;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:lng], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:lng], X_1:bat[:oid]):lng;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:lng], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:lng], X_1:bat[:oid], X_2:bit):lng;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:lng], X_1:bit):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:lng], X_1:bit):lng;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:msk]):bte;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:msk]):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:msk]):int;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:msk]):lng;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:msk]):sht;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bat[:oid]):bte;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bat[:oid]):int;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bat[:oid]):lng;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bat[:oid]):sht;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bat[:oid], X_2:bit):bte;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bat[:oid], X_2:bit):int;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bat[:oid], X_2:bit):lng;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bat[:oid], X_2:bit):sht;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bit):bte;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bit):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bit):int;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bit):lng;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:msk], X_1:bit):sht;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:sht]):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:sht]):int;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:sht]):lng;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:sht]):sht;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bat[:oid]):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bat[:oid]):int;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bat[:oid]):lng;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bat[:oid]):sht;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bat[:oid], X_2:bit):dbl;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bat[:oid], X_2:bit):int;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bat[:oid], X_2:bit):lng;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bat[:oid], X_2:bit):sht;
COMMENT "Calculate aggregate sum of B with candidate list.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bit):dbl;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bit):int;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bit):lng;
COMMENT "Calculate aggregate sum of B.";

PATTERN aggr.sum(X_0:bat[:sht], X_1:bit):sht;
COMMENT "Calculate aggregate sum of B.";

COMMAND aggr.variance(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (sample/non-biased) on bte";

COMMAND aggr.variance(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (sample/non-biased) on dbl";

COMMAND aggr.variance(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (sample/non-biased) on flt";

COMMAND aggr.variance(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (sample/non-biased) on int";

COMMAND aggr.variance(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (sample/non-biased) on lng";

COMMAND aggr.variance(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (sample/non-biased) on sht";

COMMAND aggr.variance(X_0:bat[:any_2]):dbl;
COMMENT "Gives the variance of all tail values";

COMMAND aggr.variancep(X_0:bat[:bte], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (population/biased) on bte";

COMMAND aggr.variancep(X_0:bat[:dbl], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (population/biased) on dbl";

COMMAND aggr.variancep(X_0:bat[:flt], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (population/biased) on flt";

COMMAND aggr.variancep(X_0:bat[:int], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (population/biased) on int";

COMMAND aggr.variancep(X_0:bat[:lng], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (population/biased) on lng";

COMMAND aggr.variancep(X_0:bat[:sht], X_1:bat[:oid], X_2:bat[:any_1]):bat[:dbl];
COMMENT "Grouped tail variance (population/biased) on sht";

COMMAND aggr.variancep(X_0:bat[:any_2]):dbl;
COMMENT "Gives the variance of all tail values";

COMMAND aggr.zero_or_one(X_0:bat[:any_1]):any_1;
COMMENT "if col contains exactly one value return this. Incase of more raise an exception else return nil";

COMMAND aggr.zero_or_one(X_0:bat[:any_1], X_1:bit):any_1;
COMMENT "if col contains exactly one value return this. Incase of more raise an exception if err is true else return nil";

COMMAND aggr.zero_or_one(X_0:bat[:any_1], X_1:bat[:bit]):any_1;
COMMENT "if col contains exactly one value return this. Incase of more raise an exception if err is true else return nil";

Bataggr module

MODULE bataggr;

PATTERN bataggr.allnotequal(X_0:bat[:any_1], X_1:bat[:any_1]):bit;
COMMENT "if all values in r are not equal to l, return true, else if r has nil, return nil, else return false";

PATTERN bataggr.anyequal(X_0:bat[:any_1], X_1:bat[:any_1]):bat[:bit];
COMMENT "if any value in r is equal to l, return true, else if r has nil, return nil, else return false";

PATTERN bataggr.exist(X_0:any_1):bat[:bit];
COMMENT "";

PATTERN bataggr.exist(X_0:bat[:any_1]):bat[:bit];
COMMENT "";

PATTERN bataggr.exist(X_0:bat[:any_1]):bit;
COMMENT "";

PATTERN bataggr.not_exist(X_0:any_1):bat[:bit];
COMMENT "";

PATTERN bataggr.not_exist(X_0:bat[:any_1]):bat[:bit];
COMMENT "";

PATTERN bataggr.not_exist(X_0:bat[:any_1]):bit;
COMMENT "";