rules logic - uhop/yopl GitHub Wiki
rules-logic
Boolean logic rule library. Operands are coerced to JavaScript booleans with !!.
Import
import {rules as logicRules} from 'yopl/rules/logic.js';
Predicates
logicalAnd(X, Y, Z) — Z = X ∧ Y
Computes Z from X and Y (forward direction only). With all three bound, behaves as a check. Not reversible: knowing Z = false doesn't pin down whether X or Y is the false one.
const Z = variable('Z');
solve(logicRules, 'logicalAnd', [true, false, Z], env => {
console.log(assemble(Z, env)); // false
});
logicalOr(X, Y, Z) — Z = X ∨ Y
Computes Z from X and Y. Same constraints as logicalAnd.
logicalXor(X, Y, Z) — Z = X ⊕ Y
Reversible. Any one missing operand can be solved for. The same property that makes bitXor reversible applies here.
// What value of Y makes (true XOR Y) = false?
const Y = variable('Y');
solve(logicRules, 'logicalXor', [true, Y, false], env => {
console.log(assemble(Y, env)); // true
});
logicalNot(X, Y) — Y = ¬X
Reversible negation. Both (X bound, Y unknown) and (Y bound, X unknown) work.
Use cases
Boolean predicates are useful when boolean state is part of the problem you're solving — not for general short-circuit JavaScript logic, where the native && / || / ! operators are clearer. They become valuable inside reversible rule chains:
const rules = {
...systemRules,
...logicRules,
// implication(P, Q, R) — R = (P → Q), i.e. (¬P ∨ Q)
implication: (P, Q, R, NotP) => [head(P, Q, R), term('logicalNot', P, NotP), term('logicalOr', NotP, Q, R)]
};
Limitations
logicalAndandlogicalOrare forward-only.- All operands are coerced with
!!, so any truthy JavaScript value works as input — but the output is always a stricttrue/false. - The wildcard symbol
_fromdeep6is treated as "any boolean" and propagates accordingly.