Synthesize a knowledge base of a chosen shape.
The two other kinds of KB are given: a shipped ontology (vaelii.impl.starter) is
fixed content, and an imported corpus (vaelii.impl.io.import, or a translated one)
is whatever the source says. Neither lets you ask what happens at ten times the
rules, and that is the question a scale or behaviour measurement is made of. So this
namespace generates a KB from a handful of numbers — how many types, individuals,
predicates, facts and rules, how the rules split forward/backward, how many of them are
defeasible — and each number is a knob the browser renders as a slider (knobs).
Two properties make a generated KB usable as a measurement rather than as noise:
java.util.Random in a fixed
order, so the same parameters give the same KB — a shape can be reproduced from the
numbers alone, and a run compared against a rerun.plan is pure — the whole KB as data, nothing asserted. load-into asserts it,
reporting progress through an optional :on-progress callback (which may throw to
cancel the load, the seam vaelii.impl.catalog cancels on).
Synthesize a knowledge base of a chosen **shape**. The two other kinds of KB are given: a shipped ontology (`vaelii.impl.starter`) is fixed content, and an imported corpus (`vaelii.impl.io.import`, or a translated one) is whatever the source says. Neither lets you ask *what happens at ten times the rules*, and that is the question a scale or behaviour measurement is made of. So this namespace generates a KB from a handful of numbers — how many types, individuals, predicates, facts and rules, how the rules split forward/backward, how many of them are defeasible — and each number is a knob the browser renders as a slider (`knobs`). Two properties make a generated KB usable as a measurement rather than as noise: * **Deterministic.** Everything is drawn from one seeded `java.util.Random` in a fixed order, so the same parameters give the same KB — a shape can be reproduced from the numbers alone, and a run compared against a rerun. * **Stratified.** Predicates are split into layers: facts populate layer 0, and a rule concluding a layer-k predicate draws its antecedents only from layers below k. The rule set is therefore acyclic, so forward chaining cascades base → derived → further-derived and terminates, instead of the runaway recursion a rule set wired at random produces. Individuals and predicates are Zipf-sampled, so the corpus has hot terms and a long tail like a real one rather than a uniform smear. `plan` is pure — the whole KB as data, nothing asserted. `load-into` asserts it, reporting progress through an optional `:on-progress` callback (which may throw to cancel the load, the seam `vaelii.impl.catalog` cancels on).
Every parameter with its default: the numeric knobs plus the four that are not sliders — the seed, whether to forward-chain at the end and what bounds that run, and which shipped vocabulary the generated content sits on top of.
Every parameter with its default: the numeric knobs plus the four that are not sliders — the seed, whether to forward-chain at the end and what bounds that run, and which shipped vocabulary the generated content sits on top of.
The generator's numeric parameters as data — one entry per slider the browser draws.
:scale :log marks a knob whose slider moves over orders of magnitude (the counts
that reach into the millions); the rest are linear. Keeping this a value rather than
a form in the page means the UI and the generator cannot disagree about the range of
a parameter or its default.
The generator's numeric parameters as data — one entry per slider the browser draws. `:scale :log` marks a knob whose slider moves over orders of magnitude (the counts that reach into the millions); the rest are linear. Keeping this a value rather than a form in the page means the UI and the generator cannot disagree about the range of a parameter or its default.
(load-into kb params)(load-into kb params {:keys [on-progress] :or {on-progress (fn [_])}})Generate a KB from params and assert it into kb. Returns a summary map.
:on-progress is called with {:phase :done :total :note} at every phase boundary and
every chunk-size assertions; it may throw to abort the load, which is how a
caller cancels one (nothing is undone — the KB simply holds what had landed). The
chaining phase reports through the same callback (chain's own :on-progress), so it
moves and cancels like the assert phases; what it counts is conclusions rather than
planned units, so it carries no total.
The load is one with-deferred-settle per phase (belief reconciled once, not per
fact), facts go through the bulk path (v/bulk-assert-facts! — they are well-formed by
construction and deduped here, which are exactly that path's two preconditions), and
forward chaining is left until the end: a rule that fires per arriving fact would do
the same work N times over a growing KB and reach the same fixpoint.
Generate a KB from `params` and assert it into `kb`. Returns a summary map.
`:on-progress` is called with `{:phase :done :total :note}` at every phase boundary and
every `chunk-size` assertions; it may **throw** to abort the load, which is how a
caller cancels one (nothing is undone — the KB simply holds what had landed). The
chaining phase reports through the same callback (`chain`'s own `:on-progress`), so it
moves and cancels like the assert phases; what it counts is conclusions rather than
planned units, so it carries no total.
The load is one `with-deferred-settle` per phase (belief reconciled once, not per
fact), facts go through the bulk path (`v/bulk-assert-facts!` — they are well-formed by
construction and deduped here, which are exactly that path's two preconditions), and
forward chaining is left until the end: a rule that fires per arriving fact would do
the same work N times over a growing KB and reach the same fixpoint.(plan params)The whole synthetic KB as data — pure, and a function of params alone (the seed
included), so the same numbers describe the same KB every time.
Returns {:params :context-edges :genls :memberships :facts :rules :units}, where
:units is the total number of assertions load-into will make (what a progress bar
divides by). The fact and membership seqs are lazy and generated in chunks, so a
ten-million-fact plan is a description rather than a heap full of lists.
The whole synthetic KB as data — pure, and a function of `params` alone (the seed
included), so the same numbers describe the same KB every time.
Returns `{:params :context-edges :genls :memberships :facts :rules :units}`, where
`:units` is the total number of assertions `load-into` will make (what a progress bar
divides by). The fact and membership seqs are lazy and generated in chunks, so a
ten-million-fact plan is a description rather than a heap full of lists.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 |