Liking cljdoc? Tell your friends :D

vaelii.impl.budget

Resource-bounded / anytime realization of an answer stream.

The engine's query paths are lazyask, query, and the level stack all yield one solution at a time, paying per result consumed. Resource-bounding is therefore the consumer-side discipline of realizing that stream under a bound and reporting whether it ran dry or was cut short — and resumption falls out of laziness for free, because the unrealized tail is the continuation.

A budget is a map of optional bounds (any subset; nil / {} means unbounded):

:max-ms wall-clock milliseconds — a soft deadline, checked between yielded results (a single blocking pull is not interrupted, so the granularity is one solution — the honest limit, matching a closure that has no partial answer) :max-results stop after this many solutions :max-cost a qualitative prover-cost ceiling — a tier keyword (see vaelii.impl.provers/cost-tiers). Honored by ask-within, which drops provers above the tier before the stream is built; ignored here, since it selects which work runs, not how much of a stream to realize. :max-depth transformation (rule-expansion) depth — honored by prove-within

A partial result — the anytime contract returned by collect / from-batch / resume:

:results the solutions realized in this step (a vector) :status :complete the source ran dry — the answer is exhaustive :timeout :max-ms elapsed with work remaining :capped :max-results reached with work remaining :count (count :results) :elapsed-ms wall-clock spent in this step :resume nil when :complete; otherwise a 1-arg fn (budget -> partial result) that continues exactly where this step stopped

:results are per-step, not cumulative: concatenate across steps for the whole answer. The resume continuation captures an in-memory lazy tail (or, for prove-within, the DFS goal stack), so resumption is in-process only — it does not survive a restart, and holding one pins its captured state in the heap (see the single-writer contract in docs/storage.md).

Resource-bounded / anytime realization of an answer stream.

The engine's query paths are **lazy** — `ask`, `query`, and the level stack
all yield one solution at a time, paying per result consumed.  Resource-bounding
is therefore the *consumer-side* discipline of realizing that stream under a
bound and reporting whether it ran dry or was cut short — and resumption falls
out of laziness for free, because the unrealized tail **is** the continuation.

A **budget** is a map of optional bounds (any subset; nil / {} means unbounded):

  :max-ms       wall-clock milliseconds — a soft deadline, checked *between*
                yielded results (a single blocking pull is not interrupted, so
                the granularity is one solution — the honest limit, matching a
                closure that has no partial answer)
  :max-results  stop after this many solutions
  :max-cost     a qualitative prover-cost ceiling — a tier keyword (see
                `vaelii.impl.provers/cost-tiers`).  Honored by `ask-within`,
                which drops provers above the tier before the stream is built;
                ignored *here*, since it selects *which* work runs, not how much
                of a stream to realize.
  :max-depth    transformation (rule-expansion) depth — honored by `prove-within`

A **partial result** — the anytime contract returned by `collect` / `from-batch`
/ `resume`:

  :results      the solutions realized in *this* step (a vector)
  :status       :complete  the source ran dry — the answer is exhaustive
                :timeout   :max-ms elapsed with work remaining
                :capped    :max-results reached with work remaining
  :count        (count :results)
  :elapsed-ms   wall-clock spent in this step
  :resume       nil when :complete; otherwise a 1-arg fn (budget -> partial
                result) that continues exactly where this step stopped

`:results` are per-step, **not cumulative**: concatenate across steps for the
whole answer.  The resume continuation captures an in-memory lazy tail (or, for
`prove-within`, the DFS goal stack), so resumption is **in-process only** — it
does not survive a restart, and holding one pins its captured state in the heap
(see the single-writer contract in docs/storage.md).
raw docstring

collectclj

(collect xs budget)

Realize the lazy seq xs under budget, returning the partial-result contract.

Both bounds are checked before pulling the next element, so :max-results n realizes exactly n and a passed deadline stops without over-reading; the element under the cursor is never lost — it stays the head of the captured tail, so resume re-pulls it. A nil / {} budget realizes the whole seq (:complete).

rest, not next: next realizes one element ahead to decide whether a tail exists, so a cap of n would pull n+1 from the source. rest defers that, and the cap check sits above the empty? that would force it — so exactly n elements are realized (an unbounded source is bounded without reading past the cap).

Realize the lazy seq `xs` under `budget`, returning the partial-result contract.

Both bounds are checked *before* pulling the next element, so `:max-results` n
realizes exactly n and a passed deadline stops without over-reading; the element
under the cursor is never lost — it stays the head of the captured tail, so
`resume` re-pulls it.  A `nil` / `{}` budget realizes the whole seq (`:complete`).

`rest`, not `next`: `next` realizes one element *ahead* to decide whether a tail
exists, so a cap of n would pull n+1 from the source.  `rest` defers that, and the
cap check sits above the `empty?` that would force it — so exactly n elements are
realized (an unbounded source is bounded without reading past the cap).
raw docstring

deadlineclj

(deadline budget)

Absolute System/nanoTime instant :max-ms from now, or nil when unbounded.

Absolute `System/nanoTime` instant `:max-ms` from now, or nil when unbounded.
raw docstring

from-batchclj

(from-batch results status start-nanos resume-fn)

Assemble the partial-result contract from a completed step. resume-fn is a 1-arg (budget -> partial result) continuation; it is dropped when status is :complete (nothing remains to continue). Both engines — the lazy collect and the eager prove-within — build their answer through here, so the two return the identical shape.

Assemble the partial-result contract from a completed step.  `resume-fn` is a
1-arg (budget -> partial result) continuation; it is dropped when `status` is
`:complete` (nothing remains to continue).  Both engines — the lazy `collect`
and the eager `prove-within` — build their answer through here, so the two
return the identical shape.
raw docstring

ms-sinceclj

(ms-since start-nanos)

Milliseconds elapsed since a System/nanoTime instant, as a double.

Milliseconds elapsed since a `System/nanoTime` instant, as a double.
raw docstring

resumeclj

(resume partial budget)

Continue a :timeout / :capped partial result under a fresh budget. A :complete result has no continuation, so resume returns it unchanged — making a while (:resume …) (recur (resume …)) loop terminate cleanly.

Continue a `:timeout` / `:capped` partial result under a fresh `budget`.  A
`:complete` result has no continuation, so `resume` returns it unchanged —
making a `while (:resume …) (recur (resume …))` loop terminate cleanly.
raw 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