Liking cljdoc? Tell your friends :D

vaelii.impl.observe

The leaf extension point the engine's mutation choke points notify without a require cycle. Two independent things ride on it: named observers of the stored fact set, and one counter saying that something changed.

Observers: the incremental rule-matcher (vaelii.impl.rete) keeps RAM alpha memories that mirror the stored fact set. kb/create-sentex (add) and integrate/sentex-removed! (remove) sit below rete, so they call the atoms here and rete installs itself into them when engaged. When nothing is engaged the atoms hold nil and notify-* is a deref and a nil? check. The observer is global, not per-KB; the installed functions dispatch on kb.

The change clock (note-change) is the coarse counter a cache keys on, and the resident caches it serves (cached) declare themselves to vaelii.impl.caches at the bottom of this file. See docs/inference.md.

The leaf extension point the engine's mutation choke points notify without a require
cycle. Two independent things ride on it: named observers of the stored fact set, and one
counter saying that something changed.

Observers: the incremental rule-matcher (`vaelii.impl.rete`) keeps RAM alpha memories that
mirror the stored fact set. `kb/create-sentex` (add) and `integrate/sentex-removed!` (remove)
sit below `rete`, so they call the atoms here and `rete` installs itself into them when
engaged. When nothing is engaged the atoms hold nil and `notify-*` is a deref and a `nil?`
check. The observer is global, not per-KB; the installed functions dispatch on `kb`.

The change clock (`note-change`) is the coarse counter a cache keys on, and the resident
caches it serves (`cached`) declare themselves to `vaelii.impl.caches` at the bottom of
this file. See docs/inference.md.
raw docstring

*chain-fast-paths*clj

One switch over the placement-path fast paths forward chaining leans on — the justification dedup index (jtms/*dedup-cache*), the ensure-node no-op skip, and the single-context placement answer (taxonomy/maximal-common-descendant-contexts). Each computes exactly what its reference path computes, so — like res/*arg-root-retrieval* — this is a pure cost decision that must never change the answer set. Bind it false to run the reference paths, which is what chain_fast_paths_test compares against, and what vaelii.bench.pyramid's -ref modes measure. On by default.

One switch over the placement-path fast paths forward chaining leans on — the
justification dedup index (`jtms/*dedup-cache*`), the `ensure-node` no-op skip, and
the single-context placement answer (`taxonomy/maximal-common-descendant-contexts`).
Each computes exactly what its reference path computes, so — like
`res/*arg-root-retrieval*` — this is a pure cost decision that must never change
the answer set.  Bind it **false** to run the reference paths, which is what
`chain_fast_paths_test` compares against, and what `vaelii.bench.pyramid`'s `-ref`
modes measure.  On by default.
sourceraw docstring

*fired-sink*clj

Nil, or a java.util.Set that jtms/add-justification adds the consequence of each rule firing's justification to (an integer informant, the rule's handle). core/undoing-refusal binds it while assert-entry/*write-check* is bound.

Nil, or a `java.util.Set` that `jtms/add-justification` adds the consequence of each
rule firing's justification to (an integer informant, the rule's handle).
`core/undoing-refusal` binds it while `assert-entry/*write-check*` is bound.
sourceraw docstring

*handle-cache*clj

A mutable {[sentence context] handle} map, or nil (the default: off). A positive lookup cache over kb/find-sentex-handle for forward chaining, where a conclusion reached by k witnesses is looked up once per witness. Only hits are cached: a cached absence would be wrong once a firing stores the sentence, and integrate/sentex-removed! clears an entry. The key is the sentence as the caller spelled it, and canonicalization reads only the symmetric predicate set (resolution/kb-sentex), so every entry carries that set as its cache key and the map drops when the set is replaced. Bound per run (chain/chain). A java.util.HashMap, because the engine is single-writer. See docs/inference.md.

A mutable `{[sentence context] handle}` map, or nil (the default: off). A positive
lookup cache over `kb/find-sentex-handle` for forward chaining, where a conclusion reached
by k witnesses is looked up once per witness. Only hits are cached: a cached absence would
be wrong once a firing stores the sentence, and `integrate/sentex-removed!` clears an entry.
The key is the sentence as the caller spelled it, and canonicalization reads only the
`symmetric` predicate set (`resolution/kb-sentex`), so every entry carries that set as its
cache key and the map drops when the set is replaced. Bound per run (`chain/chain`). A
`java.util.HashMap`, because the engine is single-writer. See docs/inference.md.
sourceraw docstring

*held-values*clj

An atom, or nil. While one is bound, whatever cached derives inside that scope is held fixed for the rest of it and the clock is not consulted again. A caller that writes while it reads (forward chaining places each solution of a lazy join before the next is realized) would otherwise re-derive per solution and join against states the other half never saw. Bound where a step runs (chain/process-datum, inference/step!) and never wider; a backward search binds it too (with-search-scope, res/prove-seq). See docs/inference.md.

An atom, or nil. While one is bound, whatever `cached` derives inside that scope is held
fixed for the rest of it and the clock is not consulted again. A caller that writes while
it reads (forward chaining places each solution of a lazy join before the next is realized)
would otherwise re-derive per solution and join against states the other half never saw.
Bound where a step runs (`chain/process-datum`, `inference/step!`) and never wider; a
backward search binds it too (`with-search-scope`, `res/prove-seq`). See
docs/inference.md.
sourceraw docstring

*live*clj

True where a thread reads what the writer holds now even while a hold is open. The taxonomy's visibility callbacks bind it (live): the closures they decide are memoized where the writer reads them, so they must describe the network the writer is deciding.

True where a thread reads what the writer holds now even while a hold is open.  The
taxonomy's visibility callbacks bind it (`live`): the closures they decide are memoized
where the writer reads them, so they must describe the network the writer is deciding.
sourceraw docstring

*reach-memo*clj

A per-query cache for the transitive-predicate closure's per-node neighbour lookups (succs / preds-of), an atom of {[dir pred node context] -> set}, or nil for none. A rule with two transitive antecedents solves the second once per binding of the join variable over nodes the bindings share. A backward search establishes one memo per search step (res/prove-from segment, inference/step!), created fresh and never invalidated, since a query mutates no belief. See docs/inference.md.

A per-query cache for the transitive-predicate closure's per-node neighbour lookups
(`succs` / `preds-of`), an atom of `{[dir pred node context] -> set}`, or nil for none.
A rule with two transitive antecedents solves the second once per binding of the join
variable over nodes the bindings share. A backward search establishes one memo per search
step (`res/prove-from` segment, `inference/step!`), created fresh and never invalidated,
since a query mutates no belief. See docs/inference.md.
sourceraw docstring

*write-record*clj

Nil, or the open write record: an IdentityHashMap from each structure a choke point moved since the record opened (a network, a taxonomy atom, the candidate index, a record store, an index backend, a trie) to what that structure held before its first move. Bound by the write entry points while a report is wanted (vaelii.impl.settle/write-record), and emptied by settle-finish once it has reported.

Nil, or the open write record: an `IdentityHashMap` from each structure a choke point
moved since the record opened (a network, a taxonomy atom, the candidate index, a
record store, an index backend, a trie) to what that structure held before its first
move.  Bound by the write entry points while a report is wanted
(`vaelii.impl.settle/write-record`), and emptied by `settle-finish` once it has
reported.
sourceraw docstring

cache-generationclj

(cache-generation cache-key)

Which filling of the handle cache is current under cache-key, a counter that steps at every wholesale clear, or nil when no cache is bound or it was filled under another key. A cache nothing has filled yet is claimed for cache-key here at generation 1, so a reader can record the filling before the first store lands. For a reader whose claim rests on every store since some moment being in the cache (kb/find-sentex-handle's authority memo): an equal generation says no clear has happened since.

Which filling of the handle cache is current under `cache-key`, a counter that steps at
every wholesale clear, or nil when no cache is bound or it was filled under another key.
A cache nothing has filled yet is claimed for `cache-key` here at generation 1, so a reader
can record the filling before the first store lands. For a reader whose claim rests on every
store since some moment being in the cache (`kb/find-sentex-handle`'s authority memo): an
equal generation says no clear has happened since.
sourceraw docstring

cache-handle!clj

(cache-handle! cache-key sentence context handle)

Record that sentence in context is stored at handle, valid while cache-key holds; returns handle. A key the cache was not filled under empties it first — everything in it was keyed on a canonicalization that has since moved — and steps the generation (cache-generation). A no-op when no cache is bound.

Record that `sentence` in `context` is stored at `handle`, valid while `cache-key`
holds; returns `handle`.  A key the cache was not filled under empties it first —
everything in it was keyed on a canonicalization that has since moved — and steps
the generation (`cache-generation`).  A no-op when no cache is bound.
sourceraw docstring

cachedclj

(cached cache k build)

The value of k in the resident cache, an atom of {k {:value v :clock n}}, with build run whenever the change clock has moved since v was derived. A nil cache runs build every time. A bound *held-values* overrides both. build is called with the stale value it replaces, or nil, for a caller that derives the new answer from the old (qcn-kb's warm-started pass). The clock is read before build and the entry recorded under that reading. Nothing here is content-keyed: the derivations over a resident value stay keyed on that value, so two KBs reaching one network share one pass.

The value of `k` in the resident `cache`, an atom of `{k {:value v :clock n}}`, with
`build` run whenever the change clock has moved since `v` was derived. A nil `cache` runs
`build` every time. A bound `*held-values*` overrides both. `build` is called with the
stale value it replaces, or nil, for a caller that derives the new answer from the old
(`qcn-kb`'s warm-started pass). The clock is read before `build` and the entry recorded
under that reading. Nothing here is content-keyed: the derivations over a resident value
stay keyed on that value, so two KBs reaching one network share one pass.
sourceraw docstring

cached-handleclj

(cached-handle cache-key sentence context)

The cached handle for sentence in context under cache-key, or nil — including whenever the cache was filled under a different key, which is a miss and not a wrong answer.

The cached handle for `sentence` in `context` under `cache-key`, or nil — including
whenever the cache was filled under a different key, which is a miss and not a
wrong answer.
sourceraw docstring

change-clockclj

(change-clock)

The current value of the change clock. A reader records what it derived under this and re-derives when it has moved. A thread that reads held belief (held-reader?) reads -1 - clock instead, so what it derives under the hold never shares an entry with the writer's. open-hold! moves the clock, so two holds' readers do not share one either.

The current value of the change clock. A reader records what it derived under this and
re-derives when it has moved. A thread that reads held belief (`held-reader?`) reads
`-1 - clock` instead, so what it derives under the hold never shares an entry with the
writer's. `open-hold!` moves the clock, so two holds' readers do not share one either.
sourceraw docstring

close-hold!clj

(close-hold! h)

Close hold h: from this call on, every thread reads the belief its writer published.

Close hold `h`: from this call on, every thread reads the belief its writer published.
sourceraw docstring

forget-handle!clj

(forget-handle! sentence context)

Drop sentence/context from the cache — the removal choke point's half of the contract above. It reads no cache key on purpose: a removal falsifies the entry under every key, and the choke point should not have to know which one is current.

Drop `sentence`/`context` from the cache — the removal choke point's half of the
contract above.  It reads no cache key on purpose: a removal falsifies the entry under every
key, and the choke point should not have to know which one is current.
sourceraw docstring

held-atomclj

(held-atom v)

An atom holding v that keeps its value for a hold's readers (hold-atom!).

An atom holding `v` that keeps its value for a hold's readers (`hold-atom!`).
sourceraw docstring

held-reader?clj

(held-reader?)

Does the current thread read held belief: a hold is open, this thread owns none, and it is not reading live (*live*)?

Does the current thread read held belief: a hold is open, this thread owns none, and
it is not reading live (`*live*`)?
sourceraw docstring

hold-atom!clj

(hold-atom! ha h)

Keep ha's current value for the readers of hold h, until release-atom!.

Keep `ha`'s current value for the readers of hold `h`, until `release-atom!`.
sourceraw docstring

hold-owner?clj

(hold-owner?)

Does the current thread own an open hold?

Does the current thread own an open hold?
sourceraw docstring

install!clj

(install! add-fn remove-fn)

Register the add/remove observers (called by rete when it engages).

Two atoms written in two steps, which is sound because both ends of the pair belong to the writer: rete/engage! and rete/disengage! are the only callers, and the only readers are notify-add / notify-remove at the store's own choke points and the installed? check those two callers branch on — all of them on the writing thread, under the single-writer contract (docs/storage.md). Nothing beside the writer can land between the two.

Register the add/remove observers (called by `rete` when it engages).

Two atoms written in two steps, which is sound because both ends of the pair belong to
the writer: `rete/engage!` and `rete/disengage!` are the only callers, and the only
readers are `notify-add` / `notify-remove` at the store's own choke points and the
`installed?` check those two callers branch on — all of them on the writing thread, under the
single-writer contract (docs/storage.md).  Nothing beside the writer can land between
the two.
sourceraw docstring

installed?clj

(installed?)

Is any observer currently engaged?

Is any observer currently engaged?
sourceraw docstring

keep-before!clj

(keep-before! owner k read)

Record (read) under k in owner's map of the open write record, a volatile of a map keyed by =, unless an earlier move recorded k. A nil value records that k held nothing.

Record `(read)` under `k` in `owner`'s map of the open write record, a volatile of a
map keyed by `=`, unless an earlier move recorded `k`.  A nil value records that `k`
held nothing.
sourceraw docstring

keptclj

(kept owner)

The map keep-before! recorded for owner in the open write record, or nil.

The map `keep-before!` recorded for `owner` in the open write record, or nil.
sourceraw docstring

livecljmacro

(live & body)

Run body reading what the writer holds now, whatever hold is open. Binds *live* only on a thread that reads held belief (held-reader?), so the writer and every read outside a settle pay one registry read.

Run `body` reading what the writer holds now, whatever hold is open.  Binds `*live*`
only on a thread that reads held belief (`held-reader?`), so the writer and every read
outside a settle pay one registry read.
sourceraw docstring

neighbour-countsclj

(neighbour-counts)

{:hits :misses} for the neighbour memo — hits served, neighbour sets computed.

`{:hits :misses}` for the neighbour memo — hits served, neighbour sets computed.
sourceraw docstring

new-holdclj

(new-hold)

A hold owned by the current thread, not yet open: {:token :owner}.

A hold owned by the current thread, not yet open: `{:token :owner}`.
sourceraw docstring

newly-seen?clj

(newly-seen? cache k v)

Record v as the value now held under k in the resident cache, and answer whether it is new there: true the first time, false while it is still the one held. A nil cache is no memory, so everything is new. For a report that fires once per KB rather than once per computation, since the derivations over a network are shared across KBs. Errs toward reporting: a wholesale clear drops the entry, so a report can repeat and cannot go missing. The marker is held under [::seen k] (restore-seen!).

Record `v` as the value now held under `k` in the resident `cache`, and answer whether it
is new there: true the first time, false while it is still the one held. A nil cache is no
memory, so everything is new. For a report that fires once per KB rather than once per
computation, since the derivations over a network are shared across KBs. Errs toward
reporting: a wholesale clear drops the entry, so a report can repeat and cannot go
missing. The marker is held under `[::seen k]` (`restore-seen!`).
sourceraw docstring

note-changeclj

(note-change)

Something a resident derived structure is a function of has changed. Three places bump it: the two store choke points (kb/create-sentex, integrate/sentex-removed!), every mutating jtms entry point (before and after, jtms/moving), and a watch on the taxonomy's atom. core/clear! and reindex/reindex bump by hand. Global and coarse: it says only that something moved, so a reader keyed on it re-derives more often than it must and never less. Bare, not !: it destroys nothing.

Something a resident derived structure is a function of has changed. Three places bump
it: the two store choke points (`kb/create-sentex`, `integrate/sentex-removed!`), every
mutating `jtms` entry point (before and after, `jtms/moving`), and a watch on the
taxonomy's atom. `core/clear!` and `reindex/reindex` bump by hand. Global and coarse: it
says only that something moved, so a reader keyed on it re-derives more often than it must
and never less. Bare, not `!`: it destroys nothing.
sourceraw docstring

note-neighbours!clj

(note-neighbours! hit?)

Record one neighbour-set read by the closure walk: hit? true where *reach-memo* answered it, false where it was computed (every read with no memo bound included). misses is the walk's real cost, one store retrieval each, and feeds the :closure-neighbours row's :hit-rate. Process-wide AtomicLongs, as literal-cache's are, since they measure the mechanism and not a store.

Record one neighbour-set read by the closure walk: `hit?` true where `*reach-memo*`
answered it, false where it was computed (every read with no memo bound included).
`misses` is the walk's real cost, one store retrieval each, and feeds the
`:closure-neighbours` row's `:hit-rate`. Process-wide `AtomicLong`s, as `literal-cache`'s
are, since they measure the mechanism and not a store.
sourceraw docstring

notify-addclj

(notify-add kb sentex h)

A sentex sentex (handle h) just landed in kb's store. Cheap no-op when nothing is engaged.

A sentex `sentex` (handle `h`) just landed in `kb`'s store.  Cheap no-op when
nothing is engaged.
sourceraw docstring

notify-removeclj

(notify-remove kb sentex)

A sentex sentex is leaving kb's store. Cheap no-op when nothing is engaged.

A sentex `sentex` is leaving `kb`'s store.  Cheap no-op when nothing is engaged.
sourceraw docstring

open-hold!clj

(open-hold! h)

Open hold h: move the change clock, then register h, after which every thread that owns no hold reads the belief h keeps. The clock moves first so a cache entry a held reader installs under this hold carries a clock value no earlier hold's reader used (change-clock).

Open hold `h`: move the change clock, then register `h`, after which every thread that
owns no hold reads the belief `h` keeps.  The clock moves first so a cache entry a held
reader installs under this hold carries a clock value no earlier hold's reader used
(`change-clock`).
sourceraw docstring

reads-held-in?clj

(reads-held-in? m h)

Does the current thread read the belief hold h keeps, by registry value m: h is open in m, this thread owns no hold there, and it is not reading live? The network and the held atoms ask this after their own owner check, so the writer's reads never reach it.

Does the current thread read the belief hold `h` keeps, by `registry` value `m`: `h`
is open in `m`, this thread owns no hold there, and it is not reading live?  The
network and the held atoms ask this after their own owner check, so the writer's reads
never reach it.
sourceraw docstring

reads-held?clj

(reads-held? h)

reads-held-in? against the registry as it is now.

`reads-held-in?` against the registry as it is now.
sourceraw docstring

record-ofclj

(record-of owner make)

What the open write record keeps for owner, made by (make) at the first call since the record opened or was emptied, so make reads owner before its first move; nil when no record is open.

What the open write record keeps for `owner`, made by `(make)` at the first call since
the record opened or was emptied, so `make` reads `owner` before its first move; nil
when no record is open.
sourceraw docstring

recordedclj

(recorded owner)

What the open write record keeps for owner, or nil.

What the open write record keeps for `owner`, or nil.
sourceraw docstring

registryclj

(registry)

The open holds, as one value. Every open and every close replaces it, so a reader that reads it before and after a read of live state, and finds the same value both times, knows no hold opened or closed in between.

The open holds, as one value.  Every open and every close replaces it, so a reader
that reads it before and after a read of live state, and finds the same value both
times, knows no hold opened or closed in between.
sourceraw docstring

release-atom!clj

(release-atom! ha)

Stop keeping a value for a hold's readers: every deref reads ha's own value.

Stop keeping a value for a hold's readers: every deref reads `ha`'s own value.
sourceraw docstring

reset-neighbour-countersclj

(reset-neighbour-counters)

Zero the neighbour counters and answer them as they stood. Wider than one KB, like the counters themselves, which is why it is its own control and not part of a clear.

Zero the neighbour counters and answer them as they stood.  Wider than one KB, like
the counters themselves, which is why it is its own control and not part of a clear.
sourceraw docstring

restore-seen!clj

(restore-seen! cache baseline)

Put the newly-seen? markers of the resident cache back to those baseline, a value cache held earlier, holds, and keep every other entry as it stands. A rollback calls it beside the ledger's restore, so a network whose entry the rollback dropped is reported again.

Put the `newly-seen?` markers of the resident `cache` back to those `baseline`, a value
`cache` held earlier, holds, and keep every other entry as it stands. A rollback calls it
beside the ledger's restore, so a network whose entry the rollback dropped is reported
again.
sourceraw docstring

uninstall!clj

(uninstall!)

Clear the observers, so the store choke points go back to doing nothing extra. install!'s pair, written in two steps for install!'s reason.

Clear the observers, so the store choke points go back to doing nothing extra.
`install!`'s pair, written in two steps for `install!`'s reason.
sourceraw docstring

with-handle-cachecljmacro

(with-handle-cache & body)

Run body with the stored-handle cache engaged. An outer cache is reused rather than shadowed, so a nested run shares the entries its parent has already paid for — the same composition with-held-values makes.

Run `body` with the stored-handle cache engaged.  An outer cache is reused rather
than shadowed, so a nested run shares the entries its parent has already paid for —
the same composition `with-held-values` makes.
sourceraw docstring

with-held-valuescljmacro

(with-held-values & body)

Run body with the resident values it reads held fixed — see *held-values*. An outer binding is reused rather than shadowed, so a nested step joins against the state its parent is joining against, which is what makes the two binding sites compose.

Run `body` with the resident values it reads held fixed — see `*held-values*`.  An outer
binding is reused rather than shadowed, so a nested step joins against the state its
parent is joining against, which is what makes the two binding sites compose.
sourceraw docstring

with-search-scopecljmacro

(with-search-scope & body)

Run body as one step of a backward search: resident values held fixed (with-held-values) and one transitive-closure memo (*reach-memo*) open for its length. Both compose with an outer scope, so a nested expansion shares what its parent paid for. inference/step! binds it per node and res/prove-from per segment. body must be eager: a lazy seq escaping the scope realizes later with the bindings gone.

Run `body` as one step of a backward search: resident values held fixed
(`with-held-values`) and one transitive-closure memo (`*reach-memo*`) open for its length.
Both compose with an outer scope, so a nested expansion shares what its parent paid for.
`inference/step!` binds it per node and `res/prove-from` per segment. `body` must be eager:
a lazy seq escaping the scope realizes later with the bindings gone.
sourceraw docstring

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close