-
-
Notifications
You must be signed in to change notification settings - Fork 0
rules bits
Bitwise rule library.
import {rules as bitsRules} from 'yopl/rules/bits.js';
Forward-only: requires X and Y to be bound; computes Z. With all three bound, behaves as a check. Cannot be solved backwards because bitwise AND is not invertible (many (X, Y) pairs produce the same Z).
const Z = variable('Z'); solve(bitsRules, 'bitAnd', [0b1100, 0b1010, Z], env => { console.log(assemble(Z, env).toString(2)); // 1000 });
Forward-only, same constraints as bitAnd. OR is also non-invertible.
Reversible. XOR is its own inverse (X ^ Y ^ Y = X), so any one missing operand can be solved for. Includes shortcut clauses 0 ^ Y = Y, X ^ 0 = X, X ^ X = 0.
// Solve for Y: 0b1100 ^ Y = 0b0110 const Y = variable('Y'); solve(bitsRules, 'bitXor', [0b1100, Y, 0b0110], env => { console.log(assemble(Y, env).toString(2)); // 1010 });
Reversible bitwise NOT. Shortcut clause for bitNot(0, 0)... wait, that's actually ~0 = -1, so the shortcut is ~~X = X family — see source for the exact clauses.
Bitwise predicates are most useful when integrating with code that already speaks bit flags — masking, packing, or parsing fixed-width records:
const rules = { ...systemRules, ...bitsRules, // hasFlag(Flags, Mask) — true if all bits in Mask are set in Flags hasFlag: (Flags, Mask) => [head(Flags, Mask), term('bitAnd', Flags, Mask, Mask)] };
For pure-arithmetic work, prefer the rules-math library — bitwise tricks are clever but harder to read.
- Operands must be plain JavaScript numbers. The native
&,|,^,~operators coerce to 32-bit signed integers, so values outside that range are truncated. -
bitAndandbitOrare not reversible.