Read CFASL — Cyc's binary serialization format — as Clojure data.
A CFASL stream is a sequence of self-describing objects: one opcode byte, then
whatever that opcode's payload is, recursively. Nothing frames an object but its own
opcode, so a reader that mis-sizes one payload desynchronizes the whole rest of the
file rather than failing where the mistake is — which is why vaelii.foreign.units
checks its record count against the dump's own and treats a short read as an error.
Where this comes from. Cycorp published CFASL's reference implementation under
the Apache License 2.0, so none of this was reverse-engineered:
com.cyc.cycjava.cycl.cfasl supplies the opcode table and every encoding below, and
org.opencyc.api.CfaslInputStream (the same license, per OpenCyc's LEGAL.txt)
supplies the four the SubL sources declare and leave undefined — float, bignum,
character and byte-vector. licenses/THIRD-PARTY.md records the attribution and
which upstreams are not admissible here.
The opcode table is the server's, not the API client's, and they disagree in
exactly the range a dump uses: the client reads 36/37/38 as source / source-def /
axiom, while a KB dump writes deduction / kb-hl-support / clause-struc, and 50 is the
client's special-object against the server's common-symbol. Reading unit files with
the client's table decodes the first few thousand objects and then quietly produces
nonsense. The table below is cfasl.lisp's and cfasl-kb-methods.lisp's.
Handles are not resolved here. A constant, NART, assertion or clause-struc is
written as its opcode plus an integer dump-id, and what that id means lives in another
file of the same dump. So a caller passes resolvers — {:constant f :nart f …} —
and anything it does not name reads back as its own marker list, (:nart 23227), the
same shape vaelii.foreign.cycl yields for a reference its own dump could not
resolve. That indirection is upstream's too (*cfasl-nart-handle-lookup-func*).
Read CFASL — Cyc's binary serialization format — as Clojure data.
A CFASL stream is a sequence of self-describing objects: one **opcode** byte, then
whatever that opcode's payload is, recursively. Nothing frames an object but its own
opcode, so a reader that mis-sizes one payload desynchronizes the whole rest of the
file rather than failing where the mistake is — which is why `vaelii.foreign.units`
checks its record count against the dump's own and treats a short read as an error.
**Where this comes from.** Cycorp published CFASL's reference implementation under
the Apache License 2.0, so none of this was reverse-engineered:
`com.cyc.cycjava.cycl.cfasl` supplies the opcode table and every encoding below, and
`org.opencyc.api.CfaslInputStream` (the same license, per OpenCyc's `LEGAL.txt`)
supplies the four the SubL sources declare and leave undefined — float, bignum,
character and byte-vector. `licenses/THIRD-PARTY.md` records the attribution and
which upstreams are *not* admissible here.
**The opcode table is the server's, not the API client's**, and they disagree in
exactly the range a dump uses: the client reads 36/37/38 as source / source-def /
axiom, while a KB dump writes deduction / kb-hl-support / clause-struc, and 50 is the
client's special-object against the server's common-symbol. Reading unit files with
the client's table decodes the first few thousand objects and then quietly produces
nonsense. The table below is `cfasl.lisp`'s and `cfasl-kb-methods.lisp`'s.
**Handles are not resolved here.** A constant, NART, assertion or clause-struc is
written as its opcode plus an integer dump-id, and what that id means lives in another
file of the same dump. So a caller passes `resolvers` — `{:constant f :nart f …}` —
and anything it does not name reads back as its own marker list, `(:nart 23227)`, the
same shape `vaelii.foreign.cycl` yields for a reference its own dump could not
resolve. That indirection is upstream's too (`*cfasl-nart-handle-lookup-func*`).(objects in resolvers)A lazy seq of every object in in, to end of stream.
Holds no more than the object being read, so a 780 MB dump streams.
A lazy seq of every object in `in`, to end of stream. Holds no more than the object being read, so a 780 MB dump streams.
opcode -> what it names, the whole table this reader dispatches on.
Two families, both from Cycorp's own sources: the general ones (cfasl.lisp) and the
KB-object ones (cfasl-kb-methods.lisp), which are the ones carrying a dump-id.
:cfasl/… in a comment below marks an opcode this reader refuses rather than guesses
at — see unsupported.
opcode -> what it names, the whole table this reader dispatches on. Two families, both from Cycorp's own sources: the general ones (`cfasl.lisp`) and the KB-object ones (`cfasl-kb-methods.lisp`), which are the ones carrying a dump-id. `:cfasl/…` in a comment below marks an opcode this reader refuses rather than guesses at — see `unsupported`.
(read-object in resolvers)Read one CFASL object from in, resolving handles through resolvers.
Returns ::eof when the stream is exhausted between objects — the only place an
ending is legal. A dump file is read by calling this until it says so, and everything
inside an object goes through read-element, for which an ending is truncation.
Read one CFASL object from `in`, resolving handles through `resolvers`. Returns `::eof` when the stream is exhausted **between** objects — the only place an ending is legal. A dump file is read by calling this until it says so, and everything inside an object goes through `read-element`, for which an ending is truncation.
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |