-
-
Notifications
You must be signed in to change notification settings - Fork 0
rules comp
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 fail
Use 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.