rules comp - uhop/yopl GitHub Wiki
Comparison rule library. All comparisons require both operands to be bound and of the same comparable type (number or string).
import {rules as compRules} from 'yopl/rules/comp.js';Succeeds when X < Y. Both operands must be bound, same type (number or string).
solve(compRules, 'lt', [1, 2], () => console.log('1 < 2')); // fires
solve(compRules, 'lt', ['a', 'b'], () => console.log('a < b')); // fires
solve(compRules, 'lt', [2, 1], () => console.log('never')); // does not fire
solve(compRules, 'lt', [1, 'a'], () => console.log('never')); // mixed types failUse it inside a rule body to constrain a result:
const rules = {
...systemRules,
...mathRules,
...compRules,
// smallSum(X, Y, Z) — Z = X + Y, and Z < 100
smallSum: (X, Y, Z) => [head(X, Y, Z), term('add', X, Y, Z), term('lt', Z, 100)]
};Succeeds when X ≤ Y. Same constraints as lt. Use when an inclusive bound is needed.
Succeeds when X > Y. Same constraints as lt. Equivalent to lt(Y, X) but reads more naturally in some contexts.
Succeeds when X ≥ Y. Same constraints as lt.
Succeeds when X is anything other than the literal number 0. Useful as a guard before division or to discard the trivial case in a recursion.
const rules = {
...systemRules,
...compRules,
...mathRules,
// safeDiv(X, Y, Z) — Z = X / Y, only when Y ≠ 0
safeDiv: (X, Y, Z) => [head(X, Y, Z), term('nz', Y), term('div', X, Y, Z)]
};The library deliberately stays small. JavaScript's own <, >, === operators do most of the work; what these predicates add is integration with the solver — they participate in backtracking and can be composed with other rules. For one-off comparisons inside an inline goal function, just use the JavaScript operators directly.