RaCoCo result: Red::Operators

# Red::Operators 34.8%

    use Red::AST;
    use Red::AST::Infixes;
    use Red::AST::Divisable;
    use Red::AST::Value;
    use Red::ResultSeq;

    =head2 Red::Operators

    unit module Red::Operators;

    # TODO: Diferenciate prefix and postfix
    #| --X
    multi prefix:<-->(Red::Column $a) is export {
        @*UPDATE.push: $a => Red::AST::Sub.new: $a, ast-value 1;
        $a
    }

    #| ++X
    multi prefix:<++>(Red::Column $a) is export {
        @*UPDATE.push: $a => Red::AST::Sum.new: $a, ast-value 1;
        $a
    }

    #| X--
    multi postfix:<-->(Red::Column $a) is export {
        @*UPDATE.push: $a => Red::AST::Sub.new: $a, ast-value 1;
        $a
    }

    #| X++
    multi postfix:<++>(Red::AST $a) is export {
        @*UPDATE.push: $a => Red::AST::Sum.new: $a, ast-value 1;
        $a
    }

    #| -X
    multi prefix:<->(Red::AST $a) is export {
        Red::AST::Mul.new: ast-value(-1), $a
    }

    #| +X
    multi prefix:<+>(Red::AST $a) is export {
        Red::AST::Mul.new: ast-value(1), $a
    }

    #| X + Y
    multi infix:<+>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Sum.new: $a, $b
    }

    #| X + Y # Where Y is castable to Numeric
    multi infix:<+>(Red::AST $a, Numeric() $b) is export {
        Red::AST::Sum.new: $a, ast-value $b
    }

    #| X + Y # Where X is castable to Numeric
    multi infix:<+>(Numeric() $a, Red::AST $b) is export {
        Red::AST::Sum.new: ast-value($a), $b
    }

    #| X - Y
    multi infix:<->(Red::AST $a, Red::AST $b) is export {
        Red::AST::Sub.new: $a, $b
    }

    #| X - Y # Where Y is castable to Numeric
    multi infix:<->(Red::AST $a, Numeric() $b) is export {
        Red::AST::Sub.new: $a, ast-value $b
    }

    #| X - Y # Where X is castable to Numeric
    multi infix:<->(Numeric() $a, Red::AST $b) is export {
        Red::AST::Sub.new: ast-value($a), $b
    }

    #| X * Y
    multi infix:<*>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Mul.new: $a, $b
    }

    #| X * Y # Where Y is castable to Numeric
    multi infix:<*>(Red::AST $a, Numeric() $b) is export {
        Red::AST::Mul.new: $a, ast-value $b
    }

    #| X * Y
    multi infix:<*>(Numeric() $a, Red::AST $b) is export {
        Red::AST::Mul.new: ast-value($a), $b
    }

    #| X / Y
    multi infix:</>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Div.new: $a, $b
    }

    #| X / Y # Where Y is castable to Numeric and read only
    multi infix:</>(Red::AST $a, Numeric() $b is readonly) is export {
        Red::AST::Div.new: $a, ast-value $b
    }

    #| X / Y # Where X is castable to Numeric and read only
    multi infix:</>(Numeric() $a is readonly, Red::AST $b) is export {
        Red::AST::Div.new: ast-value($a), $b
    }

    #| X / Y # Where Y is castable to Numeric and writable
    multi infix:</>(Red::AST $a, Numeric() $b is rw) is export {
        Red::AST::Div.new: $a, ast-value($b), :bind-right
    }

    #| X / Y # Where X is castable to Numeric and writable
    multi infix:</>(Numeric() $a is rw, Red::AST $b) is export {
        Red::AST::Div.new: ast-value($a), $b, :bind-left
    }

    #| X div Y
    multi infix:<div>(Red::AST $a, Red::AST $b) is export {
        Red::AST::IDiv.new: $a, $b
    }

    #| X div Y # Where Y is castable to Numeric and read only
    multi infix:<div>(Red::AST $a, Numeric() $b is readonly) is export {
        Red::AST::IDiv.new: $a, ast-value $b
    }

    #| X div Y # Where X is castable to Numeric and read only
    multi infix:<div>(Numeric() $a is readonly, Red::AST $b) is export {
        Red::AST::IDiv.new: ast-value($a), $b
    }

    #| X div Y # Where Y is castable to Numeric and writable
    multi infix:<div>(Red::AST $a, Numeric() $b is rw) is export {
        Red::AST::IDiv.new: $a, ast-value($b), :bind-right
    }

    #| X div Y # Where X is castable to Numeric and writable
    multi infix:<div>(Numeric() $a is rw, Red::AST $b) is export {
        Red::AST::IDiv.new: ast-value($a), $b, :bind-left
    }

    #| X == Y
    multi infix:<==>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Eq.new: $a, $b, :cast<num>
    }

    #| X == Y # Where Y is castable to Numeric and writable
    multi infix:<==>(Red::AST $a, Numeric() $b is rw) is export {
        Red::AST::Eq.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X == Y # Where Y is castable to Numeric and read only
    multi infix:<==>(Red::AST $a, Numeric() $b is readonly) is export {
        Red::AST::Eq.new: $a, ast-value($b), :cast<num>
    }

    #| X == Y # Where X is castable to Numeric and writable
    multi infix:<==>(Numeric() $a is rw, Red::AST $b) is export {
        Red::AST::Eq.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X == Y # Where X is castable to Numeric and read only
    multi infix:<==>(Numeric() $a is readonly, Red::AST $b) is export {
        Red::AST::Eq.new: ast-value($a), $b, :cast<num>
    }

    #| X == Y # Where X is castable to Numeric and read only
    multi infix:<==>(Red::AST $a where .returns ~~ DateTime, Date $b) is export {
        Red::AST::Eq.new: $a.yyyy-mm-dd, ast-value($b), :cast<num>;
    }

    #| X != Y # Where Y is castable to Numeric and writable
    multi infix:<!=>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Ne.new: $a, $b, :cast<num>
    }

    #| X != Y # Where Y is castable to Numeric and read only
    multi infix:<!=>(Red::AST $a, Numeric() $b is rw) is export {
        Red::AST::Ne.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X != Y # Where Y is castable to Numeric and read only
    multi infix:<!=>(Red::AST $a, Numeric() $b is readonly) is export {
        Red::AST::Ne.new: $a, ast-value($b), :cast<num>
    }

    #| X != Y # Where X is castable to Numeric and writable
    multi infix:<!=>(Numeric() $a is rw, Red::AST $b) is export {
        Red::AST::Ne.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X != Y # Where X is castable to Numeric and read only
    multi infix:<!=>(Numeric() $a is readonly, Red::AST $b) is export {
        Red::AST::Ne.new: ast-value($a), $b, :cast<num>
    }

    #| X == Y
    #multi infix:<==>(Red::AST $a, Red::AST $b) is export {
    #    Red::AST::Eq.new: $a, $b, :cast<num>
    #}

    #| X == Y # Where Y is Date and writable
    multi infix:<==>(Red::AST $a, Date $b is rw) is export {
        Red::AST::Eq.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X == Y # Where Y is Date and read only
    multi infix:<==>(Red::AST $a, Date $b is readonly) is export {
        Red::AST::Eq.new: $a, ast-value($b), :cast<num>
    }

    #| X == Y # Where X is Date and writable
    multi infix:<==>(Date $a is rw, Red::AST $b) is export {
        Red::AST::Eq.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X == Y # Where X is Date and read only
    multi infix:<==>(Date $a is readonly, Red::AST $b) is export {
        Red::AST::Eq.new: ast-value($a), $b, :cast<num>
    }

    #| X != Y
    multi infix:<!=>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Ne.new: $a, $b, :cast<num>
    }

    #| X != Y # Where Y is Date and writable
    multi infix:<!=>(Red::AST $a, Date $b is rw) is export {
        Red::AST::Ne.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X != Y # Where Y is Date and read only
    multi infix:<!=>(Red::AST $a, Date $b is readonly) is export {
        Red::AST::Ne.new: $a, ast-value($b), :cast<num>
    }

    #| X != Y # Where X is Date and writable
    multi infix:<!=>(Date $a is rw, Red::AST $b) is export {
        Red::AST::Ne.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X != Y # Where X is Date and read only
    multi infix:<!=>(Date $a is readonly, Red::AST $b) is export {
        Red::AST::Ne.new: ast-value($a), $b, :cast<num>
    }

    #| X eq Y # Where Y is castable to Str and writable
    multi infix:<eq>(Red::AST $a, Str() $b is rw) is export {
        Red::AST::Eq.new: $a, ast-value($b), :cast<str>, :bind-right
    }

    #| X eq Y # Where Y is castable to Str and read only
    multi infix:<eq>(Red::AST $a, Str() $b is readonly) is export {
        Red::AST::Eq.new: $a, ast-value($b), :cast<str>
    }

    #| X eq Y # Where X is castable to Str and writable
    multi infix:<eq>(Str() $a is rw, Red::AST $b) is export {
        Red::AST::Eq.new: ast-value($a), $b, :cast<str>, :bind-left
    }

    #| X eq Y # Where X is castable to Str and read only
    multi infix:<eq>(Str() $a is readonly, Red::AST $b) is export {
        Red::AST::Eq.new: ast-value($a), $b, :cast<str>
    }

    #| X eq Y # Where Y is any Red::AST that returns a DateTime
    multi infix:<eq>(Red::AST $a where .returns ~~ DateTime, Date $b) is export {
        Red::AST::Eq.new: $a.yyyy-mm-dd, ast-value($b), :cast<str>;
    }

    #| X eq Y # Where both are AST that returns Str
    multi infix:<eq>(Red::AST $a where .returns ~~ Str, Red::AST $b where .returns ~~ Str) is export {
        Red::AST::Eq.new: $a, $b, :cast<str>;
    }

    #| X ne Y # Where Y is castable to Str and writable
    multi infix:<ne>(Red::AST $a, Str() $b is rw) is export {
        Red::AST::Ne.new: $a, ast-value($b), :cast<str>, :bind-right
    }

    #| X ne Y # Where Y is castable to Str and read only
    multi infix:<ne>(Red::AST $a, Str() $b is readonly) is export {
        Red::AST::Ne.new: $a, ast-value($b), :cast<str>
    }

    #| X ne Y # Where X is castable to Str and writable
    multi infix:<ne>(Str() $a is rw, Red::AST $b) is export {
        Red::AST::Ne.new: ast-value($a), $b, :cast<str>, :bind-left
    }

    #| X ne Y # Where X is castable to Str and read only
    multi infix:<ne>(Str() $a is readonly, Red::AST $b) is export {
        Red::AST::Ne.new: ast-value($a), $b, :cast<str>
    }

    #| X < Y # Where Y is any Red::AST that returns a DateTime
    multi infix:<< < >>(Red::AST $a where .returns ~~ Numeric, Red::AST $b) is export {
        Red::AST::Lt.new: $a, $b, :cast<num>
    }

    #| X < Y # Where Y is castable to Numeric and writable
    multi infix:<< < >>(Red::AST $a, Numeric() $b is rw) is export {
        Red::AST::Lt.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X < Y # Where Y is castable to Numeric and read only
    multi infix:<< < >>(Red::AST $a, Numeric() $b is readonly) is export {
        Red::AST::Lt.new: $a, ast-value($b), :cast<num>
    }

    #| X < Y # Where X is castable to Numeric and writable
    multi infix:<< < >>(Numeric() $a is rw, Red::AST $b) is export {
        Red::AST::Lt.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X < Y # Where X is castable to Numeric and read only
    multi infix:<< < >>(Numeric() $a is readonly, Red::AST $b) is export {
        Red::AST::Lt.new: ast-value($a), $b, :cast<num>
    }

    #| X > Y # Where Y is any Red::AST that returns a Numeric
    multi infix:<< > >>(Red::AST $a where .returns ~~ Numeric, Red::AST $b) is export {
        Red::AST::Gt.new: $a, $b, :cast<num>
    }

    #| X > Y # Where Y is castable to Numeric and writable
    multi infix:<< > >>(Red::AST $a, Numeric() $b is rw) is export {
        Red::AST::Gt.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X > Y # Where Y is castable to Numeric and read only
    multi infix:<< > >>(Red::AST $a, Numeric() $b is readonly) is export {
        Red::AST::Gt.new: $a, ast-value($b), :cast<num>
    }

    #| X > Y # Where X is castable to Numeric and writable
    multi infix:<< > >>(Numeric() $a is rw, Red::AST $b) is export {
        Red::AST::Gt.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X > Y # Where X is castable to Numeric and read only
    multi infix:<< > >>(Numeric() $a is readonly, Red::AST $b) is export {
        Red::AST::Gt.new: ast-value($a), $b, :cast<num>
    }

    #| X <= Y # Where Y is any Red::AST that returns a Numeric
    multi infix:<< <= >>(Red::AST $a where .returns ~~ Numeric, Red::AST $b) is export {
        Red::AST::Le.new: $a, $b, :cast<num>
    }

    #| X <= Y # Where Y is castable to Numeric and read only
    multi infix:<< <= >>(Red::AST $a, Numeric() $b is rw) is export {
        Red::AST::Le.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X <= Y # Where Y is castable to Numeric and read only
    multi infix:<< <= >>(Red::AST $a, Numeric() $b is readonly) is export {
        Red::AST::Le.new: $a, ast-value($b), :cast<num>
    }

    #| X <= Y # Where X is castable to Numeric and writable
    multi infix:<< <= >>(Numeric() $a is rw, Red::AST $b) is export {
        Red::AST::Le.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X <= Y # Where X is castable to Numeric and read only
    multi infix:<< <= >>(Numeric() $a is readonly, Red::AST $b) is export {
        Red::AST::Le.new: ast-value($a), $b, :cast<num>
    }

    #| X >= Y # Where Y is any Red::AST that returns a DateTime
    multi infix:<< >= >>(Red::AST $a where .returns ~~ Numeric, Red::AST $b) is export {
        Red::AST::Ge.new: $a, $b, :cast<num>
    }

    #| X >= Y # Where Y is castable to Numeric and writable
    multi infix:<< >= >>(Red::AST $a, Numeric() $b is rw) is export {
        Red::AST::Ge.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X >= Y # Where Y is castable to Numeric and read only
    multi infix:<< >= >>(Red::AST $a, Numeric() $b is readonly) is export {
        Red::AST::Ge.new: $a, ast-value($b), :cast<num>
    }

    #| X >= Y # Where X is castable to Numeric and writable
    multi infix:<< >= >>(Numeric() $a is rw, Red::AST $b) is export {
        Red::AST::Ge.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X >= Y # Where X is castable to Numeric and read only
    multi infix:<< >= >>(Numeric() $a is readonly, Red::AST $b) is export {
        Red::AST::Ge.new: ast-value($a), $b, :cast<num>
    }

    ############################
    #| X < Y # Where Y is any Red::AST that returns a DateTime
    multi infix:<< < >>(Red::AST $a where .returns ~~ DateTime, Red::AST $b) is export {
        Red::AST::Lt.new: $a, $b, :cast<num>
    }

    #| X < Y # Where Y is DateTime and writable
    multi infix:<< < >>(Red::AST $a, DateTime $b is rw) is export {
        Red::AST::Lt.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X < Y # Where Y is DateTime and read only
    multi infix:<< < >>(Red::AST $a, DateTime $b is readonly) is export {
        Red::AST::Lt.new: $a, ast-value($b), :cast<num>
    }

    #| X < Y # Where X is DateTime and writable
    multi infix:<< < >>(DateTime $a is rw, Red::AST $b) is export {
        Red::AST::Lt.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X < Y # Where X is DateTime and read only
    multi infix:<< < >>(DateTime $a is readonly, Red::AST $b) is export {
        Red::AST::Lt.new: ast-value($a), $b, :cast<num>
    }

    #| X > Y # Where Y is any Red::AST that returns a DateTime
    multi infix:<< > >>(Red::AST $a where .returns ~~ DateTime, Red::AST $b) is export {
        Red::AST::Gt.new: $a, $b, :cast<num>
    }

    #| X > Y # Where Y is DateTime and writable
    multi infix:<< > >>(Red::AST $a, DateTime $b is rw) is export {
        Red::AST::Gt.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X > Y # Where Y is DateTime and read only
    multi infix:<< > >>(Red::AST $a, DateTime $b is readonly) is export {
        Red::AST::Gt.new: $a, ast-value($b), :cast<num>
    }

    #| X > Y # Where X is DateTime and writable
    multi infix:<< > >>(DateTime $a is rw, Red::AST $b) is export {
        Red::AST::Gt.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X > Y # Where X is DateTime and read only
    multi infix:<< > >>(DateTime $a is readonly, Red::AST $b) is export {
        Red::AST::Gt.new: ast-value($a), $b, :cast<num>
    }

    #| X <= Y # Where Y is any Red::AST that returns a DateTime
    multi infix:<< <= >>(Red::AST $a where .returns ~~ DateTime, Red::AST $b) is export {
        Red::AST::Le.new: $a, $b, :cast<num>
    }

    #| X <= Y # Where Y is DateTime and writable
    multi infix:<< <= >>(Red::AST $a, DateTime $b is rw) is export {
        Red::AST::Le.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X <= Y # Where Y is DateTime and read only
    multi infix:<< <= >>(Red::AST $a, DateTime $b is readonly) is export {
        Red::AST::Le.new: $a, ast-value($b), :cast<num>
    }

    #| X <= Y # Where X is DateTime and writable
    multi infix:<< <= >>(DateTime $a is rw, Red::AST $b) is export {
        Red::AST::Le.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X <= Y # Where X is DateTime and read only
    multi infix:<< <= >>(DateTime $a is readonly, Red::AST $b) is export {
        Red::AST::Le.new: ast-value($a), $b, :cast<num>
    }

    #| X >= Y # Where Y is any Red::AST that returns a DateTime
    multi infix:<< >= >>(Red::AST $a where .returns ~~ DateTime, Red::AST $b) is export {
        Red::AST::Ge.new: $a, $b, :cast<num>
    }

    #| X >= Y # Where Y is DateTime and writable
    multi infix:<< >= >>(Red::AST $a, DateTime $b is rw) is export {
        Red::AST::Ge.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X >= Y # Where Y is DateTime and read only
    multi infix:<< >= >>(Red::AST $a, DateTime $b is readonly) is export {
        Red::AST::Ge.new: $a, ast-value($b), :cast<num>
    }

    #| X >= Y # Where X is DateTime and writable
    multi infix:<< >= >>(DateTime $a is rw, Red::AST $b) is export {
        Red::AST::Ge.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X >= Y # Where X is DateTime and read only
    multi infix:<< >= >>(DateTime $a is readonly, Red::AST $b) is export {
        Red::AST::Ge.new: ast-value($a), $b, :cast<num>
    }

    ############################

    #| X < Y # Where Y is any Red::AST that returns a Date
    multi infix:<< < >>(Red::AST $a where .returns ~~ Date, Red::AST $b) is export {
        Red::AST::Lt.new: $a, $b, :cast<num>
    }

    #| X < Y # Where Y is Date and writable
    multi infix:<< < >>(Red::AST $a, Date $b is rw) is export {
        Red::AST::Lt.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X < Y # Where Y is Date and read only
    multi infix:<< < >>(Red::AST $a, Date $b is readonly) is export {
        Red::AST::Lt.new: $a, ast-value($b), :cast<num>
    }

    #| X < Y # Where X is Date and writable
    multi infix:<< < >>(Date $a is rw, Red::AST $b) is export {
        Red::AST::Lt.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X < Y # Where X is Date and read only
    multi infix:<< < >>(Date $a is readonly, Red::AST $b) is export {
        Red::AST::Lt.new: ast-value($a), $b, :cast<num>
    }

    #| X > Y # Where Y is any Red::AST that returns a Date
    multi infix:<< > >>(Red::AST $a where .returns ~~ Date, Red::AST $b) is export {
        Red::AST::Gt.new: $a, $b, :cast<num>
    }

    #| X > Y # Where Y is Date and writable
    multi infix:<< > >>(Red::AST $a, Date $b is rw) is export {
        Red::AST::Gt.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X > Y # Where Y is Date and read only
    multi infix:<< > >>(Red::AST $a, Date $b is readonly) is export {
        Red::AST::Gt.new: $a, ast-value($b), :cast<num>
    }

    #| X > Y # Where X is Date and writable
    multi infix:<< > >>(Date $a is rw, Red::AST $b) is export {
        Red::AST::Gt.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X > Y # Where X is Date and read only
    multi infix:<< > >>(Date $a is readonly, Red::AST $b) is export {
        Red::AST::Gt.new: ast-value($a), $b, :cast<num>
    }

    #| X <= Y # Where Y is any Red::AST that returns a Date
    multi infix:<< <= >>(Red::AST $a where .returns ~~ Date, Red::AST $b) is export {
        Red::AST::Le.new: $a, $b, :cast<num>
    }

    #| X <= Y # Where Y is Date and writable
    multi infix:<< <= >>(Red::AST $a, Date $b is rw) is export {
        Red::AST::Le.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X <= Y # Where Y is Date and read only
    multi infix:<< <= >>(Red::AST $a, Date $b is readonly) is export {
        Red::AST::Le.new: $a, ast-value($b), :cast<num>
    }

    #| X <= Y # Where X is Date and read only
    multi infix:<< <= >>(Date $a is rw, Red::AST $b) is export {
        Red::AST::Le.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X <= Y # Where X is Date and read only
    multi infix:<< <= >>(Date $a is readonly, Red::AST $b) is export {
        Red::AST::Le.new: ast-value($a), $b, :cast<num>
    }

    #| X >= Y # Where Y is any Red::AST that returns a Date
    multi infix:<< >= >>(Red::AST $a where .returns ~~ Date, Red::AST $b) is export {
        Red::AST::Ge.new: $a, $b, :cast<num>
    }

    #| X >= Y # Where Y is Date and writable
    multi infix:<< >= >>(Red::AST $a, Date $b is rw) is export {
        Red::AST::Ge.new: $a, ast-value($b), :cast<num>, :bind-right
    }

    #| X >= Y # Where Y is Date and read only
    multi infix:<< >= >>(Red::AST $a, Date $b is readonly) is export {
        Red::AST::Ge.new: $a, ast-value($b), :cast<num>
    }

    #| X >= Y # Where X is Date and writable
    multi infix:<< >= >>(Date $a is rw, Red::AST $b) is export {
        Red::AST::Ge.new: ast-value($a), $b, :cast<num>, :bind-left
    }

    #| X >= Y # Where X is Date and read only
    multi infix:<< >= >>(Date $a is readonly, Red::AST $b) is export {
        Red::AST::Ge.new: ast-value($a), $b, :cast<num>
    }

    #| X lt Y
    multi infix:<lt>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Lt.new: $a, $b, :cast<str>
    }

    #| X lt Y # Where Y is castable to Str and writable
    multi infix:<lt>(Red::AST $a, Str() $b is rw) is export {
        Red::AST::Lt.new: $a, ast-value($b), :cast<str>, :bind-right
    }

    #| X lt Y # Where Y is castable to Str and read only
    multi infix:<lt>(Red::AST $a, Str() $b is readonly) is export {
        Red::AST::Lt.new: $a, ast-value($b), :cast<str>
    }

    #| X lt Y # Where X is castable to Str and writable
    multi infix:<lt>(Str() $a is rw, Red::AST $b) is export {
        Red::AST::Lt.new: ast-value($a), $b, :cast<str>, :bind-left
    }

    #| X lt Y # Where X is castable to Str and read only
    multi infix:<lt>(Str() $a is readonly, Red::AST $b) is export {
        Red::AST::Lt.new: ast-value($a), $b, :cast<str>
    }

    #| X gt Y
    multi infix:<gt>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Gt.new: $a, $b, :cast<str>
    }

    #| X gt Y # Where Y is castable to Str and writable
    multi infix:<gt>(Red::AST $a, Str() $b is rw) is export {
        Red::AST::Gt.new: $a, ast-value($b), :cast<str>, :bind-right
    }

    #| X gt Y # Where Y is castable to Str and read only
    multi infix:<gt>(Red::AST $a, Str() $b is readonly) is export {
        Red::AST::Gt.new: $a, ast-value($b), :cast<str>
    }

    #| X gt Y # Where X is castable to Str and writable
    multi infix:<gt>(Str() $a is rw, Red::AST $b) is export {
        Red::AST::Gt.new: ast-value($a), $b, :cast<str>, :bind-left
    }

    #| X gt Y # Where X is castable to Str and read only
    multi infix:<gt>(Str() $a is readonly, Red::AST $b) is export {
        Red::AST::Gt.new: ast-value($a), $b, :cast<str>
    }

    #| X le Y
    multi infix:<le>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Le.new: $a, $b, :cast<str>
    }

    #| X le Y # Where Y is castable to Str and writable
    multi infix:<le>(Red::AST $a, Str() $b is rw) is export {
        Red::AST::Le.new: $a, ast-value($b), :cast<str>, :bind-right
    }

    #| X le Y # Where Y is castable to Str and read only
    multi infix:<le>(Red::AST $a, Str() $b is readonly) is export {
        Red::AST::Le.new: $a, ast-value($b), :cast<str>
    }

    #| X le Y # Where X is castable to Str and writable
    multi infix:<le>(Str() $a is rw, Red::AST $b) is export {
        Red::AST::Le.new: ast-value($a), $b, :cast<str>, :bind-left
    }

    #| X le Y # Where X is castable to Str and read only
    multi infix:<le>(Str() $a is readonly, Red::AST $b) is export {
        Red::AST::Le.new: ast-value($a), $b, :cast<str>
    }

    #| X ge Y
    multi infix:<ge>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Ge.new: $a, $b, :cast<str>
    }

    #| X ge Y # Where Y is castable to Str and writable
    multi infix:<ge>(Red::AST $a, Str() $b is rw) is export {
        Red::AST::Ge.new: $a, ast-value($b), :cast<str>, :bind-right
    }

    #| X ge Y # Where Y is castable to Str and read only
    multi infix:<ge>(Red::AST $a, Str() $b is readonly) is export {
        Red::AST::Ge.new: $a, ast-value($b), :cast<str>
    }

    #| X ge Y # Where X is castable to Str and writable
    multi infix:<ge>(Str() $a is rw, Red::AST $b) is export {
        Red::AST::Ge.new: ast-value($a), $b, :cast<str>, :bind-left
    }

    #| X ge Y # Where X is castable to Str and read only
    multi infix:<ge>(Str() $a is readonly, Red::AST $b) is export {
        Red::AST::Ge.new: ast-value($a), $b, :cast<str>
    }

    #| X % Y
    multi infix:<%>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Mod.new: $a, $b, :cast<int>
    }

    #| X % Y # Where X is castable to Int and writable
    multi infix:<%>(Red::AST $a, Int() $b is rw) is export {
        Red::AST::Mod.new: $a, ast-value($b), :cast<int>, :bind-right
    }

    #| X % Y # Where Y is castable to Int and read only
    multi infix:<%>(Red::AST $a, Int() $b is readonly) is export {
        Red::AST::Mod.new: $a, ast-value($b), :cast<int>
    }

    #| X % Y # Where X is castable to Int and writable
    multi infix:<%>(Int() $a is rw, Red::AST $b) is export {
        Red::AST::Mod.new: ast-value($a), $b, :cast<int>, :bind-left
    }

    #| X % Y # Where X is castable to Int and read only
    multi infix:<%>(Int() $a is readonly, Red::AST $b) is export {
        Red::AST::Mod.new: ast-value($a), $b, :cast<int>
    }

    #| X %% Y
    multi infix:<%%>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Divisable.new: $a, $b, :cast<int>
    }

    #| X %% Y # Where Y is castable to Int and writable
    multi infix:<%%>(Red::AST $a, Int() $b is rw) is export {
        Red::AST::Divisable.new: $a, ast-value($b), :cast<int>, :bind-right
    }

    #| X %% Y # Where Y is castable to Int and read only
    multi infix:<%%>(Red::AST $a, Int() $b is readonly) is export {
        Red::AST::Divisable.new: $a, ast-value($b), :cast<int>
    }

    #| X %% Y # Where X is castable to Int
    multi infix:<%%>(Int() $a is rw, Red::AST $b) is export {
        Red::AST::Divisable.new: ast-value($a), $b, :cast<int>, :bind-left
    }

    #| X %% Y # Where X is read only
    multi infix:<%%>(Int() $a is readonly, Red::AST $b) is export {
        Red::AST::Divisable.new: ast-value($a), $b, :cast<int>
    }

    #| X ~ Y
    multi infix:<~>(Red::AST $a, Red::AST $b) is export {
        Red::AST::Concat.new: $a, $b, :cast<str>
    }

    #| X ~ Y Where Y is castable to Str and writable
    multi infix:<~>(Red::AST $a, Str() $b is rw) is export {
        Red::AST::Concat.new: $a, ast-value($b), :cast<str>, :bind-right
    }

    #| X ~ Y Where Y is castable to Str and read only
    multi infix:<~>(Red::AST $a, Str() $b is readonly) is export {
        Red::AST::Concat.new: $a, ast-value($b), :cast<str>
    }

    #| X ~ Y # Where X is castable to Str and writable
    multi infix:<~>(Str() $a is rw, Red::AST $b) is export {
        Red::AST::Concat.new: ast-value($a), $b, :cast<str>, :bind-left
    }

    #| X ~ Y # Where X is castable to Str and read only
    multi infix:<~>(Str() $a is readonly, Red::AST $b) is export {
        Red::AST::Concat.new: ast-value($a), $b, :cast<str>
    }

    #| not X # Where X is read only
    multi prefix:<not>(Red::AST $a is readonly) is export {
        Red::AST::Not.new: $a
    }

    #| not X
    multi prefix:<not>(Red::AST $a is rw) is export {
        Red::AST::Not.new: $a, :bind
    }

    #| !X
    multi prefix:<!>(Red::AST $a) is export {
        Red::AST::Not.new: $a
    }

    #| not X # Where X is a in
    multi prefix:<not>(Red::AST::In $a) is export {
        $a.not;
    }

    #| !X # Where X is a in
    multi prefix:<!>(Red::AST::In $a) is export {
        $a.not;
    }

    #| so X
    multi prefix:<so>(Red::AST $a) is export {
        Red::AST::So.new: $a
    }

    #| ?X
    multi prefix:<?>(Red::AST $a) is export {
        Red::AST::So.new: $a
    }

    #| X AND Y
    multi infix:<AND>(Red::AST $a, Red::AST $b) is export is tighter(&infix:<==>) {
        Red::AST::AND.new: $a, $b
    }

    #| X OR Y
    multi infix:<OR>(Red::AST $a, Red::AST $b) is export {
        Red::AST::OR.new: $a, $b
    }

    #| X ∪ Y # Where X and Y are ResultSeqs
    multi infix:<∪>(Red::ResultSeq $a, Red::ResultSeq $b) is export {
        $a (|) $b
    }
    #| X (|) Y # Where X and Y are ResultSeqs
    multi infix:<(|)>(Red::ResultSeq $a, Red::ResultSeq $b) is export {
        $a.union: $b
    }
    #| X ∩ Y # Where X and Y are ResultSeqs
    multi infix:<∩>(Red::ResultSeq $a, Red::ResultSeq $b) is export {
        $a (&) $b
    }
    #| X (&) Y # Where X and Y are ResultSeqs
    multi infix:<(&)>(Red::ResultSeq $a, Red::ResultSeq $b) is export {
        $a.intersect: $b
    }
    #| X ⊖ Y # Where X and Y are ResultSeqs
    multi infix:<⊖>(Red::ResultSeq $a, Red::ResultSeq $b) is export {
        $a (-) $b
    }
    #| X (-) Y # Where X and Y are ResultSeqs
    multi infix:<(-)>(Red::ResultSeq $a, Red::ResultSeq $b) is export {
        $a.minus: $b
    }

    #| X in Y # Where Y is a ResultSeq
    multi infix:<in>(Red::AST $a, Red::ResultSeq:D $b ) is export is default {
        Red::AST::In.new: $a, $b.ast(:sub-select);
    }
    #| X ⊂ Y # Where Y is a ResultSeq
    multi infix:<⊂>(Red::AST $a, Red::ResultSeq $b ) is export is default {
        Red::AST::In.new: $a, $b.ast(:sub-select);
    }
    #| X (<) Y # Where Y is a ResultSeq
    multi infix:«(<)»(Red::AST $a, Red::ResultSeq $b ) is export is default {
        Red::AST::In.new: $a, $b.ast(:sub-select);
    }
    #| X ⊃ Y # Where Y is a ResultSeq
    multi infix:<⊃>(Red::AST $a, Red::ResultSeq $b ) is export is default {
        Red::AST::NotIn.new: $a, $b.ast(:sub-select);
    }
    #| X (>) Y # Where Y is a ResultSeq
    multi infix:«(>)»(Red::AST $a, Red::ResultSeq $b ) is export is default {
        Red::AST::NotIn.new: $a, $b.ast(:sub-select);
    }

    subset PositionalNotResultSeq of Any  where { $_ ~~ Positional && $_ !~~ Red::ResultSeq };

    #| X in Y # Where Y is a positional but not a ResultSeq
    multi infix:<in>(Red::AST $a, PositionalNotResultSeq $b ) is export {
        Red::AST::In.new: $a, ast-value($b);
    }

    #| X ⊂ Y # Where Y is a positional but not a ResultSeq
    multi infix:<⊂>(Red::AST $a, PositionalNotResultSeq $b ) is export {
        Red::AST::In.new: $a, ast-value($b);
    }

    #| X (<) Y # Where Y is a positional but not a ResultSeq
    multi infix:«(<)»(Red::AST $a, PositionalNotResultSeq $b ) is export {
        Red::AST::In.new: $a, ast-value($b);
    }

    #| X ⊃ Y # Where Y is a positional but not a ResultSeq
    multi infix:<⊃>(Red::AST $a, PositionalNotResultSeq $b ) is export {
        Red::AST::NotIn.new: $a, ast-value($b);
    }

    #| X (>) Y # Where Y is a positional but not a ResultSeq
    multi infix:«(>)»(Red::AST $a, PositionalNotResultSeq $b ) is export {
        Red::AST::NotIn.new: $a, ast-value($b);
    }

    #| X in Y # where Y is a select
    multi infix:<in>(Red::AST $a, Red::AST::Select $b ) is export {
        Red::AST::In.new: $a, $b.as-sub-select;
    }

    #| X ⊂ Y # where Y is a select
    multi infix:<⊂>(Red::AST $a, Red::AST::Select $b ) is export {
        Red::AST::In.new: $a, $b.as-sub-select;
    }

    #| X (<) Y # where Y is a select
    multi infix:«(<)»(Red::AST $a, Red::AST::Select $b ) is export {
        Red::AST::In.new: $a, $b.as-sub-select;
    }

    #| X ⊃ Y # where Y is a select
    multi infix:<⊃>(Red::AST $a, Red::AST::Select $b ) is export {
        Red::AST::NotIn.new: $a, $b.as-sub-select;
    }

    #| X (>) Y # Where Y is a select
    multi infix:«(>)»(Red::AST $a, Red::AST::Select $b ) is export {
        Red::AST::NotIn.new: $a, $b.as-sub-select;
    }