Relational/equality operator swaps:
:> → :>=, :< :== → :!=
:>= → :>, :<= :!= → :==
:< → :<=, :> :=== → :!==
:<= → :<, :>= :!== → :===Ordering operators mutate to both their boundary neighbour and their direction flip (the classic boundary + reversal pair); equality operators flip polarity, and membership (in) flips to not in (the polarity flip for membership, mirroring == → !=). Legal in bodies and when guards.
Not mutated:
not in→inis not produced —x not in yparses asnot(x in y), whichMutare.Mutators.Logicalalready strips. For the same reason, aninnode that is the direct operand ofnot/!is left to Logical.- An equality operator (
==/!=/===/!==) directly undernot/!is left to Logical — each is its own exact polarity complement, so!(a != b)≡a == b(Logical's strip). The ordering operators are not suppressed there: their boundary/reversal swaps are not the negation complement, so they survive a surrounding negation as genuinely new mutants.
Filterable variants — qualify a # mutare:ignore filter with :label to suppress just one kind (Mutare.Mutator.variants/0): >, >=, <, <=, ==, !=, ===, !==.