-
-
Notifications
You must be signed in to change notification settings - Fork 0
Release notes
Long-form per-release changelog for yopl.
The repo's README.md carries cliff-notes for users skimming GitHub; this
page is the canonical history with internal-change context, motivation, and
credits.
Rule compiler and JS-native bridge library. The largest feature release
since the 1.2.0 ESM repackage. Rules can now be written declaratively via a
tagged-template DSL; the IR is reusable across front-ends; a new predicate
library bridges yopl unification to plain JS objects, arrays, Map, Set,
and Date.
-
Rule compiler (
src/compile/). Pure-data IR with 5 Term kinds (var,wildcard,literal,cons,compound) and 4 Goal kinds (call,cut,fail,js), plusClauseandRule. Lowering is the only place that knows the runtime rule shape; front-ends emit IR.-
Per-clause front-end (
compile/clause/). Tagged-template DSL:Uppercase identifiers are logic Variables;rule('member', 2)(clause`(X, [X | _])`, clause`(X, [_ | T]) :- member(X, T)`);
_is the wildcard;[X | T]is cons-list sugar;${...}interpolates IR or auto-wraps primitives / functions. -
Validator (
compile/validate.js) catchesarity-mismatch,call-arity-mismatch,undeclared-var,duplicate-rule, and (opt-in)unresolved-rule. -
All five existing rule modules (
system,comp,math,bits,logic) are dogfooded through the compiler.
-
Per-clause front-end (
-
Lit-walker.Lit(value)lowers per activation, descending into plain objects and arrays and substituting nested IR nodes (Var,Wild,Cons,Compound,Lit) with the activation's fresh logic Variables. SoLit({age: Var('A')})doubles as a pattern matcher and a constructor.Maps,Sets,Dates, andWrap-wrapped values pass through verbatim. IR detection is gated on the closedIR_KINDSset so user objects with a domainkindfield aren't misread. -
unifyOpts/3(insystem.js).unifyOpts(X, Y, Opts)runs deep6's unification with a per-call options bag ({openObjects, openArrays, openMaps, openSets, circular, loose, ignoreFunctions, signedZero, symbols}). The env's baselineoptionsis restored before the goal returns. From clause source, pass options as${Lit({openArrays: true})}. -
yopl/rules/native.js— JS-native bridge predicates split out fromsystem.jsso the latter stays focused on generic logic-programming.-
Type tests —
isArray,isMap,isSet,isDate. (isArraymoved out ofsystem.jsto live with its siblings.) -
Array —
arrayList(A, L)(bidir array ↔ cons list),arrayGet(A, I, X)(forward indexed lookup),arraySet(A, I, X, A2)(immutable single-index override; in-bounds replace or append-at-end),arrayLength(A, N). -
Map —
mapEntries(M, Es)(bidir; both-bound case is order-independent),mapGet(M, K, V),mapHas(M, K). -
Set —
setItems(S, Items)(bidir),setHas(S, X). -
Date —
dateTimestamp(D, Ms)(bidir; TZ-agnostic),dateComponents(D, C)anddateComponentsUTC(D, C)(bidir; component bag{year, month, day, hour, minute, second, ms}, month 0-based; pairs cleanly with theLit-walker for partial-bag pattern matching).
-
Type tests —
-
bitOrreverse-mode identities.bitOr(0, Y, Z)andbitOr(X, 0, Z)now answerZ = Y/Z = Xrespectively via(0, Y, Y)and(X, 0, X)fact clauses, mirroring the existingbitXoridentity-fact pattern.forwardTernarycuts only on the modes it actually resolves (verify-all-3 + forward) so identity facts can fire on under-specified reverse queries without duplicating forward solutions. -
IR re-exports.
yopl/compile/ir.jsre-exportsopen,soft, and_(also asany) fromdeep6for fine-grained per-value match control:Lit(open({tag: 'a'}))locks subset matching regardless of env options;Lit(soft({...}))extends both sides. -
Var()mints anonymous Variables.Var()(no name argument) returns{kind: 'var', name: Symbol()}— useful for IR fragments built in JS code that need a guaranteed-unique identity. Mirrors deep6'svariable()idiom. -
Bench scaffold (
bench/). Top-levelbench-{proof-loop,drivers, inline-goals}.jsscripts usingnano-benchmarkas a dev dep. Run vianpm run bench(one-shot) ornpm run bench:watch. -
Regex-based clause tokenizer modelled on
stream-json's sticky- regex lexing — the V8 RegExp engine eats whole lexemes in native code rather than the JS interpreter walking char-by-char. Functionally equivalent to the previous lexer; faster on the multi-KB inputs the upcoming Prolog front-end will need. -
Design docs. New
dev-docs/compiler-ir.md(IR design, decisions,Lit-walker,unifyOpts/3, practical patterns) anddev-docs/native-objects.md(Array / Map / Set / Date roadmap, what's shipped vs postponed). -
Junk audit. Removed
AUTHORS(single-line duplicate ofpackage.json#author) andCODEBASE.md(redundant withARCHITECTURE.md).
Test count grew from 152 → 258 across the IR / lower / validate / clause
front-end / native bridges / Lit-walker. npm test is green; npm run ts-check clean; npm run lint clean; bench/bench-proof-loop.js runs
in the same ballpark as the pre-compiler hand-written rules.
ESM-only repackage and test/docs overhaul, the largest release since the extraction of deep6 at 1.1.0.
-
CommonJS build removed. yopl ships as pure ESM. CJS consumers can use
Node's built-in dynamic
import(); a smoke-test demonstrating the interop pattern lives attests/test-cjs.cjsand runs vianode tests/test-cjs.cjs. -
TypeScript typings added. Hand-written
.d.tssidecars for every source module.npm run ts-checkrunstsc --noEmitagainst the typings plus a dedicated TypeScript surface test (tests/test-types.ts). -
Tests restructured. Per-driver test files
(
test-{solve,gen,async,asyncGen}.js) split out of a monolithic suite, plus dedicatedtest-system.jsandtest-rules.jsfor the predicate libraries. Run withnpm test. -
Simplified list creation. Helper exports —
head,term,list,listHead,rest— replace the inlined object-literal patterns common in older yopl rule definitions. The wiki's Writing rules page documents the new shapes. - Bug fixes and perf improvements in the proof loop and the rule libraries.
-
Expanded docs.
ARCHITECTURE.md,llms.txt,llms-full.txt,AGENTS.md, plus per-module wiki pages (solve, solvers-gen, solvers-async, solvers-asyncGen, rules-system, rules-comp, rules-math, rules-bits, rules-logic).
Cliff-notes preserved verbatim from README.md for releases that predate
this long-form page:
- 1.1.4 — updated dependencies.
- 1.1.3 — updated dependencies.
- 1.1.2 — updated dependencies.
- 1.1.1 — updated dependencies.
- 1.1.0 — deep6 was extracted from this package and is now a dependency.
-
1.0.1 — added the
exportsstatement. - 1.0.0 — first 1.0 release.