### ----------------------------------------------------
### -- Red
### -- Licenses: Artistic-2.0
### -- Authors: Fernando Correa de Oliveira
### -- File: lib/Red/Operators.rakumod
### ----------------------------------------------------
### -- Chunk 2 of 2
 $b is rw) is export {
    Red::AST::Ge.new: $a, ast-value($b), :cast<date>, :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<date>
}

#| 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<date>, :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<date>
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

#| 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::Divisible.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::Divisible.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::Divisible.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::Divisible.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::Divisible.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.map(-> $v { $v ~~ Enumeration ?? $v.value !! $v }).List);
}

#| 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;
}



