\def\packagedate{13 December 2024} \def\packageversion{2.0} \def\packageshortdate{2024/12/13} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Defines various relational algebra symbols. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % Version History % v1.0 Initial version. % v2.0 Complete rewrite to support Unicode OpenType fonts and LaTeX3. % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \NeedsTeXFormat{LaTeX2e}[2001/06/01] \ProvidesPackage{relalg}% [\packageshortdate\space v\packageversion\space Relational algebra notation] \RequirePackage{amsmath} \RequirePackage{expl3} \RequirePackage{iftex} \ExplSyntaxOn \bool_new:N \__unicode_engine \ifLuaTeX \PackageInfo{relalg}{LuaTeX\space engine\space detected} \bool_set_true:N \__unicode_engine \fi \ifXeTeX \PackageInfo{relalg}{XeTeX\space engine\space detected} \bool_set_true:N \__unicode_engine \fi \bool_if:NTF \__unicode_engine { \RequirePackage[no-math]{fontspec} \RequirePackage{unicode-math} \setmathfont{latinmodern-math.otf} % The various join symbols aren't covered very well by many maths fonts % (including Latin Modern Math, annoyingly), so let's Frankenstein them % in from fonts that do have them. We need to hack the scale to get roughly % proportional looking sizes. % Outer joins (left, right, full): \setmathfont{STIXTwoMath-Regular.otf}[range={"027D5-"027D7}, Scale=0.875] % Inner join: (1.143 = 1 / 0.875) \setmathfont{KpMath-Light.otf}[range={"02A1D}, Scale=1.143] }{ \PackageInfo{relalg}{non-Unicode\space engine\space detected} \RequirePackage{latexsym} % for \Join } \ExplSyntaxOff %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % IDENTIFIERS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % General identifiers. \NewDocumentCommand{\RelIdentifier}{m}{\ensuremath{\mathit{#1}}} % Attribute names. \let\RelAttribute\RelIdentifier \let\RelAttr\RelIdentifier % Relation variable names. \let\RelVariable\RelIdentifier \let\RelVar\RelIdentifier % Attribute sets: \RelAttributeSet{foo,bar,baz}, \RelAttrSet{foo,bar,baz} % <https://tex.stackexchange.com/a/159132>, expl3 manual Section 23 \ExplSyntaxOn \NewDocumentCommand{\RelAttributeSet}{m}{ \clist_clear:N \l_tmpa_clist \clist_map_inline:nn{#1}{ \clist_put_right:Nn \l_tmpa_clist {\RelAttribute{##1}} } \ensuremath{\{\clist_use:Nn \l_tmpa_clist {,}\}} } \let\RelAttrSet\RelAttributeSet \ExplSyntaxOff %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % BASIC OPERATORS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Restrict (select) operator. \NewDocumentCommand{\RelRestrict}{}{\ensuremath{\sigma}} \let\RelSelect\RelRestrict % Project operator. \NewDocumentCommand{\RelProject}{}{\ensuremath{\pi}} % Set union operator. \NewDocumentCommand{\RelUnion}{}{\ensuremath{\cup}} % Set difference operator. \NewDocumentCommand{\RelDifference}{}{\ensuremath{-}} \let\RelMinus\RelDifference % Cartesian product operator. \NewDocumentCommand{\RelCartesianProduct}{}{\ensuremath{\times}} \let\RelProduct\RelCartesianProduct \let\RelTimes\RelCartesianProduct % Rename operator. \NewDocumentCommand{\RelRename}{}{\ensuremath{\rho}} % Extend operator. \NewDocumentCommand{\RelExtend}{}{\ensuremath{\epsilon}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % ADDITIONAL OPERATORS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Set intersection operator. \NewDocumentCommand{\RelIntersection}{}{\ensuremath{\cap}} \let\RelIntersect\RelIntersection % Join operator (including natural join). % For some reason XeTeX puts less space in front of the operator than LuaTeX. % Adding +2.5mu for XeTeX looks close enough to LuaTeX's output. This also % applies to the outer join operators below. \NewDocumentCommand{\RelJoin}{}{\ensuremath{\ifXeTeX\mkern2.5mu\fi\mathbin{\Join}}} \let\RelNaturalJoin\RelJoin \let\RelNatJoin\RelJoin \let\RelNJoin\RelJoin % Division operator (two alternatives). \NewDocumentCommand{\RelDivide}{}{\ensuremath{/}} \NewDocumentCommand{\RelAltDivide}{}{\ensuremath{\div}} % Assignment operator. \NewDocumentCommand{\RelAssign}{}{\ensuremath{\leftarrow}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % EXTENDED OPERATORS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Aggregate functions. \DeclareMathOperator{\AggAvg}{avg} \DeclareMathOperator{\AggCount}{count} \DeclareMathOperator{\AggMin}{min} \DeclareMathOperator{\AggMax}{max} \DeclareMathOperator{\AggSum}{sum} \NewDocumentCommand{\RelAggregrate}{m m}{\ensuremath{\mathcal{G}_{#1}(#2)}} \NewDocumentCommand{\RelAverage}{m}{\RelAggregrate{\AggAverage}{#1}} \let\RelAvg\RelAverage \NewDocumentCommand{\RelCount}{m}{\RelAggregrate{\AggCount}{#1}} \NewDocumentCommand{\RelMaximum}{m}{\RelAggregrate{\AggMax}{#1}} \let\RelMax\RelMaximum \NewDocumentCommand{\RelMinimum}{m}{\RelAggregrate{\AggMin}{#1}} \let\RelMin\RelMinimum \NewDocumentCommand{\RelSum}{m}{\RelAggregrate{\AggSum}{#1}} % Outer join operators. \ExplSyntaxOn \bool_if:NTF \__unicode_engine { \NewDocumentCommand{\RelLeftOuterJoin}{}{\ensuremath{\ifXeTeX\mkern2.5mu\fi\mathbin{\leftouterjoin}}} \NewDocumentCommand{\RelRightOuterJoin}{}{\ensuremath{\ifXeTeX\mkern2.5mu\fi\mathbin{\rightouterjoin}}} \NewDocumentCommand{\RelFullOuterJoin}{}{\ensuremath{\ifXeTeX\mkern2.5mu\fi\mathbin{\fullouterjoin}}} }{ % Hand-tweaked for non-Unicode engines based on answers at % <https://tex.stackexchange.com/questions/20740/symbols-for-outer-joins> % Weirdly the height of \Join is fractionally shorter than \bowtie, so % we can't use the more sensible solution of measuring off the line % height. Use only font-relative units to ensure proper scaling. \def\__ojoin{\rule[0.11ex]{0.25em}{0.1ex}\llap{\rule[1.41ex]{0.25em}{0.1ex}}} \NewDocumentCommand{\RelLeftOuterJoin}{}{\ensuremath{\mathbin{\__ojoin\mkern-6.4mu\Join}}} \NewDocumentCommand{\RelRightOuterJoin}{}{\ensuremath{\mathbin{\Join\mkern-6.4mu\__ojoin}}} \NewDocumentCommand{\RelFullOuterJoin}{}{\ensuremath{\mathbin{\__ojoin\mkern-6.4mu\Join\mkern-6.4mu\__ojoin}}} } \ExplSyntaxOff \let\RelLOuterJoin\RelLeftOuterJoin \let\RelLeftOuter\RelLeftOuterJoin \let\RelLOJ\RelLeftOuterJoin \let\RelROuterJoin\RelRightOuterJoin \let\RelRightOuter\RelRightOuterJoin \let\RelROJ\RelRightOuterJoin \let\RelFOuterJoin\RelFullOuterJoin \let\RelFullOuter\RelFullOuterJoin \let\RelFOJ\RelFullOuterJoin % Semijoin operator. \NewDocumentCommand{\RelLeftSemiJoin}{}{\ensuremath{\ltimes}} \let\RelSemiJoin\RelLeftSemiJoin \NewDocumentCommand{\RelRightSemiJoin}{}{\ensuremath{\rtimes}} \let\RelReverseSemiJoin\RelRightSemiJoin % Antijoin operator. \NewDocumentCommand{\RelLeftAntiJoin}{}{\ensuremath{\triangleright}} \let\RelAntiJoin\RelLeftAntiJoin \NewDocumentCommand{\RelRightAntiJoin}{}{\ensuremath{\triangleleft}} \let\RelReverseAntiJoin\RelRightAntiJoin %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % MISCELLANEOUS % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % Logical operators. \NewDocumentCommand{\RelLogicalAnd}{}{\ensuremath{\wedge}} \let\RelLogAnd\RelLogicalAnd \let\RelAnd\RelLogicalAnd \NewDocumentCommand{\RelLogicalOr}{}{\ensuremath{\vee}} \let\RelLogOr\RelLogicalOr \let\RelOr\RelLogicalOr \NewDocumentCommand{\RelLogicalNot}{}{\ensuremath{\neg}} \let\RelLogNot\RelLogicalNot \let\RelNot\RelLogicalNot \endinput